Dividing signed integers by powers of 2Assembler/80386

These set of gems deals with dividing signed integers by powers of 2, and negated powers of 2. These also appear in the AMD K6 optimization guide. Please note that the gems can easily be converted to run on CPUs lower than 386:s.
These first two do signed division by powers of 2:

;
; signed division by 2
;
; input:
;   eax = dividend
;
; output:
;   eax = quotient
;
; destroys:
;   eflags
;

        cmp     eax,080000000h  ; CY = 1, if dividend >= 0
        sbb     eax,-1          ; increment dividend if it is < 0
        sar     eax,1           ; now do right shift

;
; signed division by d = 2^k
; 
; input:
;   eax = dividend
;
; output:
;   eax = quotient
;
; destroys:
;   edx
;   eflags
;

        cdq                     ; EDX = 0xFFFFFFFF if dividend < 0
        and     edx,(d-1)       ; mask correction (use divisor-1)
        add     eax,edx         ; apply correction if necessary
        sar     eax,k           ; now do right shift by log2(divisor)
The next two covers signed divison by negated power of 2:
;
; signed division by -2
;
; input:
;   eax = dividend
;
; output:
;   eax = quotient
;
; destroys:
;   eflags
;

        cmp     eax,080000000h  ; CY = 1, if dividend >= 0
        sbb     eax,-1          ; increment dividend if it is < 0
        sar     eax,1           ; now do right shift
        neg     eax             ; use (x / -2) ==  -(x / 2)

;
; signed division by d = -(2^k)
;
; input:
;   eax = dividend
;
; output:
;   eax = quotient
;
; destroys:
;   edx
;   eflags
;

        cdq                     ; EDX = mask = 0xFFFFFFFF if divdnd < 0
        and     edx,(-d-1)      ; mask correction (-divisor - 1)
        add     eax,edx         ; apply correction if necessary
        sar     eax,k           ; do right shift by log2(-divisor)
        neg     eax             ; use (x / -(2^n)) == (- (x / 2^n))
The next two gems covers remainder of signed divisons, both by powers of 2 and negated powers of 2.
;
; remainder of signed division by 2 or -2
;
; input:
;   eax = dividend
;
; output:
;   eax = remainder
;
; destroys:
;   edx
;   eflags
;

        cdq                     ; flag = EDX = 0xFFFFFFFF if divdnd < 0
        and     eax,1           ; compute remainder
        xor     eax,edx         ; negate remainder if
        sub     eax,edx         ;  dividend was < 0

;
; remainder of signed division by d = 2^k or -(2^k)
;
; input:
;   eax = dividend
;
; output:
;   eax = remainder
;
; destroys:
;   edx
;   eflags
;

        cdq                     ; EDX = mask = 0xFFFFFFFF if divdnd < 0
        and     edx,(abs(d)-1)  ; mask correction (abs(divisor)-1)
        add     eax,edx         ; apply pre-correction
        and     eax,(abs(d)-1)  ; mask out remainder (abs(divisor)-1)
        sub     eax,edx         ; apply post-correction if necessary
Gem writer: Norbert Juffa
last updated: 1998-03-16