shecc
shecc copied to clipboard
Support Arm/RISC-V targets without integer division instructions
Some Arm targets such as Cortex-A9 might lack of integer division instructions, and the current shecc
would not generate the correct instruction sequence for them. Consequently, we have to provide the fallback by means of software emulation. Here is the reference implementation for integer division:
__div:
push {fp, lr}
add fp, sp, #4
// check for divide by zero
cmp r1, #0
beq __div_end
push {r0, r1}
// variables
mov r0, #0 // quotient
pop {r1, r2} // dividend / remainder, divisor
mov r3, #1 // bit field
__div_shift:
// shift divisor left until it exceeds dividend
// the bit field will be shifted by one less
cmp r2, r1
lslls r2, r2, #1
lslls r3, r3, #1
bls __div_shift
__div_sub:
// cmp sets the carry flag if r1 - r2 is positive, which is weird
cmp r1, r2
// subtract divisor from the remainder if it was smaller
// this also sets the carry flag since the result is positive
subcs r1, r1, r2
// add bit field to the quotient if the divisor was smaller
addcs r0, r0, r3
// shift bit field right, setting the carry flag if it underflows
lsrs r3, r3, #1
// shift divisor right if bit field has not underflowed
lsrcc r2, r2, #1
// loop if bit field has not underflowed
bcc __div_sub
__div_end:
sub sp, fp, #4
pop {fp, pc}
Reference:
- Simple division algorithm for ARM assembler
- Assembly Language - Division
- Pull request #56