{$ASMMODE INTEL}
{$DEFINE FPC_SYSTEM_HAS_MUL_QWORD}
// multiplies two qwords
// the longbool for checkoverflow avoids a misaligned stack
function fpc_mul_qword(F1,F2:QWord; CheckOverflow:LongBool):QWord;[public,alias:'FPC_MUL_QWORD']; compilerproc;
assembler;asm
CMP CheckOverflow,0
JZ @@NoOvr
CMP DWORD [F1+4],0
JZ @@MulNumbers
CMP DWORD [F2+4],0
JZ @@MulNumbers
JNZ @@MulOverflow
@@MulNumbers:
MOV EAX,DWORD [F1+4]
MUL DWORD [F2+0]
OR EDX,EDX
JNZ @@MulOverflow
MOV ECX,EAX
MOV EAX,DWORD [F1+0]
MUL DWORD [F2+4]
OR EDX,EDX
JNZ @@MulOverflow
ADD ECX,EAX
JC @@MulOverflow
MOV EAX,DWORD [F1+0]
MUL DWORD [F2+0]
ADD EDX,ECX
JC @@MulOverflow
JMP @@Exit
@@MulOverflow:
MOV EDX,EBP
MOV EAX,215
CALL HandleErrorFrame
@@NoOvr://
MOV EAX,DWORD [F1+4]
MUL DWORD [F2+0]
MOV ECX,EAX
MOV EAX,DWORD [F1+0]
MUL DWORD [F2+4]
ADD ECX,EAX
MOV EAX,DWORD [F1+0]
MUL DWORD [F2+0]
ADD EDX,ECX
@@Exit:://
end;
{$DEFINE FPC_SYSTEM_HAS_MUL_INT64}
function fpc_mul_int64(F1,F2:Int64; CheckOverflow:LongBool):Int64;[public,alias:'FPC_MUL_INT64']; compilerproc;
assembler;asm
PUSH EBX
CMP CheckOverflow,0
JZ @@NoOvr
//
XOR BL,BL
BT DWORD [F1+4],31
JNC @@1
XOR BL,-1
MOV EAX,DWORD [F1+0]
MOV EDX,DWORD [F1+4]
NOT EAX
NOT EDX
ADD EAX,1
ADC EDX,0
MOV DWORD [F1+0],EAX
MOV DWORD [F1+4],EDX
@@1: //
BT DWORD [F2+4],31
JNC @@2
XOR BL,-1
MOV EAX,DWORD [F2+0]
MOV EDX,DWORD [F2+4]
NOT EAX
NOT EDX
ADD EAX,1
ADC EDX,0
MOV DWORD [F2+0],EAX
MOV DWORD [F2+4],EDX
@@2: //
CMP DWORD [F1+4],0
JZ @@MulNumbers
CMP DWORD [F2+4],0
JZ @@MulNumbers
JNZ @@MulOverflow
@@MulNumbers:
MOV EAX,DWORD [F1+4]
MUL DWORD [F2+0]
OR EDX,EDX
JNZ @@MulOverflow
MOV ECX,EAX
MOV EAX,DWORD [F1+0]
MUL DWORD [F2+4]
OR EDX,EDX
JNZ @@MulOverflow
ADD ECX,EAX
JC @@MulOverflow
MOV EAX,DWORD [F1+0]
MUL DWORD [F2+0]
ADD EDX,ECX
JC @@MulOverflow
OR BL,BL
JZ @@MulOK
NOT EAX
NOT EDX
ADD EAX,1
ADC EDX,0
@@MulOK:JMP @@Exit
@@MulOverflow:
MOV EDX,EBP
MOV EAX,215
CALL HandleErrorFrame
@@NoOvr://
MOV EAX,DWORD [F1+4]
MUL DWORD [F2+0]
MOV ECX,EAX
MOV EAX,DWORD [F1+0]
MUL DWORD [F2+4]
ADD ECX,EAX
MOV EAX,DWORD [F1+0]
MUL DWORD [F2+0]
ADD EDX,ECX
@@Exit: POP EBX
end;
{$ASMMODE ATT}