mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-16 01:39:27 +02:00
* Fixed overflow handling in i386 assembler implementations of fpc_div_qword and fpc_mod_qword.
Resolves #23963. git-svn-id: trunk@24362 -
This commit is contained in:
parent
1fea5a82c1
commit
97152cc41b
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -13383,6 +13383,7 @@ tests/webtbs/tw2382.pp svneol=native#text/plain
|
||||
tests/webtbs/tw2388.pp svneol=native#text/plain
|
||||
tests/webtbs/tw23912.pp svneol=native#text/plain
|
||||
tests/webtbs/tw23962.pp svneol=native#text/plain
|
||||
tests/webtbs/tw23963.pp svneol=native#text/plain
|
||||
tests/webtbs/tw2397.pp svneol=native#text/plain
|
||||
tests/webtbs/tw24007.pp svneol=native#text/plain
|
||||
tests/webtbs/tw2409.pp svneol=native#text/plain
|
||||
|
@ -18,10 +18,10 @@
|
||||
{$define FPC_SYSTEM_HAS_DIV_QWORD}
|
||||
function fpc_div_qword(n,z : qword) : qword;assembler;[public,alias: 'FPC_DIV_QWORD']; compilerproc;
|
||||
var
|
||||
shift,lzz,lzn : longint;
|
||||
saveebx,saveedi : longint;
|
||||
saveebx,saveedi,saveesi : longint;
|
||||
asm
|
||||
movl %ebx,saveebx
|
||||
movl %esi,saveesi
|
||||
movl %edi,saveedi
|
||||
{ the following piece of code is taken from the }
|
||||
{ AMD Athlon Processor x86 Code Optimization manual }
|
||||
@ -68,18 +68,23 @@
|
||||
roll $1,%edi
|
||||
divl %ebx
|
||||
movl z,%ebx
|
||||
movl %eax,%ecx
|
||||
movl %eax,%esi // save quotient to esi
|
||||
imull %eax,%edi
|
||||
mull n
|
||||
addl %edi,%edx
|
||||
setcb %cl // cl:edx:eax = 65 bits quotient*divisor
|
||||
|
||||
movl z+4,%edi // edi:ebx = dividend
|
||||
subl %eax,%ebx
|
||||
movl %ecx,%eax
|
||||
movl z+4,%ecx
|
||||
sbbl %edx,%ecx
|
||||
sbbl $0,%eax
|
||||
movb $0,%al
|
||||
sbbl %edx,%edi
|
||||
sbbb %cl,%al
|
||||
sbbl $0,%esi
|
||||
xorl %edx,%edx
|
||||
movl %esi,%eax
|
||||
.Lexit:
|
||||
movl saveebx,%ebx
|
||||
movl saveesi,%esi
|
||||
movl saveedi,%edi
|
||||
end;
|
||||
|
||||
@ -87,7 +92,6 @@
|
||||
{$define FPC_SYSTEM_HAS_MOD_QWORD}
|
||||
function fpc_mod_qword(n,z : qword) : qword;assembler;[public,alias: 'FPC_MOD_QWORD']; compilerproc;
|
||||
var
|
||||
shift,lzz,lzn : longint;
|
||||
saveebx,saveedi : longint;
|
||||
asm
|
||||
movl %ebx,saveebx
|
||||
@ -139,19 +143,22 @@
|
||||
roll $1,%edi
|
||||
divl %ebx
|
||||
movl z,%ebx
|
||||
movl %eax,%ecx
|
||||
imull %eax,%edi
|
||||
mull n
|
||||
addl %edi,%edx
|
||||
subl %eax,%ebx
|
||||
movl z+4,%ecx
|
||||
setcb %cl // cl:edx:eax = 65 bits quotient*divisor
|
||||
movl z+4,%edi
|
||||
subl %eax,%ebx // subtract (quotient*divisor) from dividend
|
||||
movb $0,%al
|
||||
sbbl %edx,%edi
|
||||
sbbb %cl,%al // if carry is set now, the quotient was off by 1,
|
||||
// and we need to add divisor to result
|
||||
movl n,%eax
|
||||
sbbl %edx,%ecx
|
||||
sbbl %edx,%edx
|
||||
andl %edx,%eax
|
||||
andl n+4,%edx
|
||||
addl %ebx,%eax
|
||||
adcl %ecx,%edx
|
||||
adcl %edi,%edx
|
||||
.Lexit:
|
||||
movl saveebx,%ebx
|
||||
movl saveedi,%edi
|
||||
|
14
tests/webtbs/tw23963.pp
Normal file
14
tests/webtbs/tw23963.pp
Normal file
@ -0,0 +1,14 @@
|
||||
{$mode objfpc}
|
||||
|
||||
var
|
||||
Dividend, Divisor, Quotient : QWord;
|
||||
begin
|
||||
Dividend := QWord( $ffffffffffffffff );
|
||||
Divisor := QWord( $100000003 );
|
||||
Quotient := dividend div divisor;
|
||||
if quotient <> $FFFFFFFD then
|
||||
Halt(1);
|
||||
Quotient := dividend mod divisor;
|
||||
if quotient <> 8 then
|
||||
Halt(2);
|
||||
end.
|
Loading…
Reference in New Issue
Block a user