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

View File

@ -1073,3 +1073,33 @@ asm
{$endif win64} {$endif win64}
bswap %rax bswap %rax
end; 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}