mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-22 11:49:23 +02:00
* fixed overflow checking in qword multiplication
This commit is contained in:
parent
f77e8ab5a6
commit
9205c6e800
@ -168,17 +168,19 @@
|
||||
the longbool for checkoverflow avoids a misaligned stack
|
||||
}
|
||||
function fpc_mul_qword(f1,f2 : qword;checkoverflow : longbool) : qword;[public,alias: 'FPC_MUL_QWORD']; {$ifdef hascompilerproc} compilerproc; {$endif}
|
||||
|
||||
var
|
||||
_f1 : qword;
|
||||
r : qword;
|
||||
r : qword;
|
||||
overflowed : boolean;
|
||||
begin
|
||||
_f1:=f1;
|
||||
overflowed:=false;
|
||||
{ the following piece of code is taken from the
|
||||
AMD Athlon Processor x86 Code Optimization manual }
|
||||
asm
|
||||
movl f1+4,%edx
|
||||
movl f2+4,%ecx
|
||||
cmpl $0,checkoverflow
|
||||
jnz .Loverflowchecked
|
||||
|
||||
orl %ecx,%edx
|
||||
movl f2,%edx
|
||||
movl f1,%eax
|
||||
@ -194,18 +196,70 @@
|
||||
.Lqwordmulready:
|
||||
movl %eax,r
|
||||
movl %edx,r+4
|
||||
end [ 'eax','edx','ecx' ];
|
||||
jmp .Lend
|
||||
|
||||
.Loverflowchecked:
|
||||
{ if both upper dwords are <>0 then it overflows always }
|
||||
or %ecx,%ecx
|
||||
jz .Loverok1
|
||||
or %edx,%edx
|
||||
jnz .Loverflowed
|
||||
.Loverok1:
|
||||
{ overflow checked code }
|
||||
orl %ecx,%edx
|
||||
movl f2,%edi
|
||||
movl f1,%esi
|
||||
jnz .Lqwordmultwomul2
|
||||
movl %edi,%eax
|
||||
mull %esi
|
||||
movl %eax,%esi
|
||||
movl %edx,%edi
|
||||
jmp .Lqwordmulready2
|
||||
|
||||
.Lqwordmultwomul2:
|
||||
movl f1+4,%eax
|
||||
mull %edi
|
||||
movl %eax,%edi
|
||||
jc .Loverflowed
|
||||
|
||||
movl %esi,%eax
|
||||
mull %ecx
|
||||
movl %eax,%ecx
|
||||
jc .Loverflowed
|
||||
|
||||
addl %edi,%ecx
|
||||
jc .Loverflowed
|
||||
|
||||
movl f2,%eax
|
||||
mull %esi
|
||||
movl %eax,%esi
|
||||
movl %edx,%edi
|
||||
|
||||
addl %ecx,%edi
|
||||
jc .Loverflowed
|
||||
|
||||
.Lqwordmulready2:
|
||||
movl %esi,r
|
||||
movl %edi,r+4
|
||||
jmp .Lend
|
||||
|
||||
.Loverflowed:
|
||||
movb $1,overflowed
|
||||
|
||||
.Lend:
|
||||
end [ 'eax','edx','ecx','edi','esi' ];
|
||||
fpc_mul_qword:=r;
|
||||
{ if one of the operands is greater than the result an
|
||||
overflow occurs }
|
||||
if checkoverflow and (_f1<>0) and (f2<>0) and
|
||||
((_f1>fpc_mul_qword) or (f2>fpc_mul_qword)) then
|
||||
|
||||
if overflowed then
|
||||
HandleErrorFrame(215,get_frame);
|
||||
end;
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.4 2004-07-25 11:50:39 florian
|
||||
Revision 1.5 2004-09-26 08:52:51 florian
|
||||
* fixed overflow checking in qword multiplication
|
||||
|
||||
Revision 1.4 2004/07/25 11:50:39 florian
|
||||
* assembler version of mod_qword_word reactivated
|
||||
|
||||
Revision 1.3 2004/05/10 20:58:20 florian
|
||||
|
Loading…
Reference in New Issue
Block a user