Chapter 8 Integer Optimizations 173
Software Optimization Guide for AMD64 Processors
25112 Rev. 3.06 September 2005
64-Bit Signed Division
; _lldiv divides two signed 64-bit numbers and delivers the quotient
;
; In: [ESP+8]:[ESP+4] = dividend
; [ESP+16]:[ESP+12] = divisor
; Out: EDX:EAX = quotient of division
; Destroys: EAX, ECX,E DX, EFlags
_lldiv PROC
push ebx ; Save EBX as per calling convention.
push esi ; Save ESI as per calling convention.
push edi ; Save EDI as per calling convention.
mov ecx, [esp+28] ; divisor_hi
mov ebx, [esp+24] ; divisor_lo
mov edx, [esp+20] ; dividend_hi
mov eax, [esp+16] ; dividend_lo
mov esi, ecx ; divisor_hi
xor esi, edx ; divisor_hi ^ dividend_hi
sar esi, 31 ; (quotient < 0) ? -1 : 0
mov edi, edx ; dividend_hi
sar edi, 31 ; (dividend < 0) ? -1 : 0
xor eax, edi ; If (dividend < 0),
xor edx, edi ; compute 1's complement of dividend.
sub eax, edi ; If (dividend < 0),
sbb edx, edi ; compute 2's complement of dividend.
mov edi, ecx ; divisor_hi
sar edi, 31 ; (divisor < 0) ? -1 : 0
xor ebx, edi ; If (divisor < 0),
xor ecx, edi ; compute 1's complement of divisor.
sub ebx, edi ; If (divisor < 0),
sbb ecx, edi ; compute 2's complement of divisor.
jnz big_divisor ; divisor > 2^32 - 1
cmp edx, ebx ; Only one division needed (ECX = 0)?
jae two_divs ; Need two divisions.
div ebx ; EAX = quotient_lo
mov edx, ecx ; EDX = quotient_hi = 0 (quotient in EDX:EAX)
xor eax, esi ; If (quotient < 0),
xor edx, esi ; compute 1's complement of result.
sub eax, esi ; If (quotient < 0),
sbb edx, esi ; compute 2's complement of result.
pop edi ; Restore EDI as per calling convention.
pop esi ; Restore ESI as per calling convention.
pop ebx ; Restore EBX as per calling convention.
ret ; Done, return to caller.
two_divs:
mov ecx, eax ; Save dividend_lo in ECX.
mov eax, edx ; Get dividend_hi.
xor edx, edx ; Zero-extend it into EDX:EAX.
div ebx ; quotient_hi in EAX
xchg eax, ecx ; ECX = quotient_hi, EAX = dividend_lo