S3C2440A RISC MICROPROCESSOR THUMB INSTRUCTION SET
4-41
GENERAL PURPOSE SIGNED DIVIDE
This example shows a general purpose signed divide and remainder routine in both Thumb and ARM code.
Thumb code
;signed_divide ; Signed divide of R1 by R0: returns quotient in R0,
; remainder in R1
;Get abs value of R0 into R3
ASR R2, R0, #31 ; Get 0 or -1 in R2 depending on sign of R0
EOR R0, R2 ; EOR with -1 (0×FFFFFFFF) if negative
SUB R3, R0, R2 ; and ADD 1 (SUB -1) to get abs value
;SUB always sets flag so go & report division by 0 if necessary
BEQ divide_by_zero
;Get abs value of R1 by xoring with 0xFFFFFFFF and adding 1 if negative
ASR R0, R1, #31 ; Get 0 or -1 in R3 depending on sign of R1
EOR R1, R0 ; EOR with -1 (0×FFFFFFFF) if negative
SUB R1, R0 ; and ADD 1 (SUB -1) to get abs value
;Save signs (0 or -1 in R0 & R2) for later use in determining ; sign of quotient & remainder.
PUSH {R0, R2}
;Justification, shift 1 bit at a time until divisor (R0 value) ; is just <= than dividend (R1 value). To do this shift
dividend ; right by 1 and stop as soon as shifted value becomes >.
LSR R0, R1, #1
MOV R2, R3
B %FT0
just_l LSL R2, #1
0 CMP R2, R0
BLS just_l
MOV R0, #0 ; Set accumulator to 0
B %FT0 ; Branch into division loop
div_l LSR R2, #1
0 CMP R1, R2 ; Test subtract
BCC %FT0
SUB R1, R2 ; If successful do a real subtract
0 ADC R0, R0 ; Shift result and add 1 if subtract succeeded
CMP R2, R3 ; Terminate when R2 == R3 (ie we have just
BNE div_l ; tested subtracting the 'ones' value).