25112 Rev. 3.06 September 2005

Software Optimization Guide for AMD64 Processors

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

Chapter 8

Integer Optimizations

173

Page 189
Image 189
AMD 250 manual Bit Signed Division, 173