mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-16 12:39:24 +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
|
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}
|
function fpc_mul_qword(f1,f2 : qword;checkoverflow : longbool) : qword;[public,alias: 'FPC_MUL_QWORD']; {$ifdef hascompilerproc} compilerproc; {$endif}
|
||||||
|
|
||||||
var
|
var
|
||||||
_f1 : qword;
|
r : qword;
|
||||||
r : qword;
|
overflowed : boolean;
|
||||||
begin
|
begin
|
||||||
_f1:=f1;
|
overflowed:=false;
|
||||||
{ the following piece of code is taken from the
|
{ the following piece of code is taken from the
|
||||||
AMD Athlon Processor x86 Code Optimization manual }
|
AMD Athlon Processor x86 Code Optimization manual }
|
||||||
asm
|
asm
|
||||||
movl f1+4,%edx
|
movl f1+4,%edx
|
||||||
movl f2+4,%ecx
|
movl f2+4,%ecx
|
||||||
|
cmpl $0,checkoverflow
|
||||||
|
jnz .Loverflowchecked
|
||||||
|
|
||||||
orl %ecx,%edx
|
orl %ecx,%edx
|
||||||
movl f2,%edx
|
movl f2,%edx
|
||||||
movl f1,%eax
|
movl f1,%eax
|
||||||
@ -194,18 +196,70 @@
|
|||||||
.Lqwordmulready:
|
.Lqwordmulready:
|
||||||
movl %eax,r
|
movl %eax,r
|
||||||
movl %edx,r+4
|
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;
|
fpc_mul_qword:=r;
|
||||||
{ if one of the operands is greater than the result an
|
|
||||||
overflow occurs }
|
if overflowed then
|
||||||
if checkoverflow and (_f1<>0) and (f2<>0) and
|
|
||||||
((_f1>fpc_mul_qword) or (f2>fpc_mul_qword)) then
|
|
||||||
HandleErrorFrame(215,get_frame);
|
HandleErrorFrame(215,get_frame);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{
|
{
|
||||||
$Log$
|
$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
|
* assembler version of mod_qword_word reactivated
|
||||||
|
|
||||||
Revision 1.3 2004/05/10 20:58:20 florian
|
Revision 1.3 2004/05/10 20:58:20 florian
|
||||||
|
Loading…
Reference in New Issue
Block a user