+ x86-64: assembler implementation for u128_div_u64_to_u64 for SysV ABI

* reminder => remainder (thanks to Stefan Kanthak for pointing it out)

git-svn-id: trunk@43695 -
This commit is contained in:
florian 2019-12-17 21:54:47 +00:00
parent 5f2410b871
commit 33fa211b84
2 changed files with 34 additions and 2 deletions

View File

@ -1276,6 +1276,7 @@ begin
end;
{$if defined(VALREAL_80) or defined(VALREAL_128)}
{$ifndef FPC_SYSTEM_HAS_U128_DIV_U64_TO_U64}
(*-------------------------------------------------------
| u128_div_u64_to_u64 [local]
|
@ -1286,7 +1287,7 @@ end;
| 128-bit integer into two 64-bit ones before converting it to ASCII.
|
*-------------------------------------------------------*)
function u128_div_u64_to_u64( const xh, xl: qword; const y: qword; out quotient, reminder: qword ): boolean;
function u128_div_u64_to_u64( const xh, xl: qword; const y: qword; out quotient, remainder: qword ): boolean;
var
b, // Number base
v, // Norm. divisor
@ -1342,10 +1343,11 @@ begin
break;
end;
// Result
reminder := ( un21 * b + un0 - q0 * v ) shr s;
remainder := ( un21 * b + un0 - q0 * v ) shr s;
quotient := q1 * b + q0;
u128_div_u64_to_u64 := true;
end;
{$endif FPC_SYSTEM_HAS_U128_DIV_U64_TO_U64}
{$endif VALREAL_80 | VALREAL_128}
(*-------------------------------------------------------

View File

@ -1073,3 +1073,33 @@ asm
{$endif win64}
bswap %rax
end;
{$ifndef win64}
{$define FPC_SYSTEM_HAS_U128_DIV_U64_TO_U64}
function u128_div_u64_to_u64( const xh, xl: qword; const y: qword; out quotient, remainder: qword ): boolean;nostackframe;assembler;
{
SysV:
xh: RDI
xl: RSI
y: RDX
quotient: RCX
remainder: R8
}
label
dodiv;
asm
cmpq %rdi,%rdx
ja dodiv
xorl %eax,%eax
ret
dodiv:
movq %rdx,%r9
movq %rsi,%rax
movq %rdi,%rdx
divq %r9
movq %rax,(%rcx)
movq %rdx,(%r8)
movl $1,%eax
end;
{$endif win64}