diff --git a/rtl/i386/int64p.inc b/rtl/i386/int64p.inc index 39cd8c1c4d..d375e40561 100644 --- a/rtl/i386/int64p.inc +++ b/rtl/i386/int64p.inc @@ -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