The following C code:
int Rem8(int n) { return n % 8 ; }
is recognized as a special case (divisor is power of 2) and compiled by gcc version 5.4 with -O3 into:
Rem8: ldr r3, .L5 ands r3, r3, r0 cmp r3, #0 blt .L4 mov r0, r3 bx lr .L4: subs r3, r3, #1 orn r3, r3, #7 adds r3, r3, #1 mov r0, r3 bx lr .L5: .word -2147483641 // Same as 0x80000007
However, there's a much simpler and faster solution:
Rem8: AND R1,R0,7 // R1 = n MOD 8 TST R1,R0,ASR 31 // Is n < 0 && (n MOD 8) != 0 ? ITE NE SUBNE R0,R1,8 // Yes: Return (n MOD 8) - 8 MOVEQ R0,R1 // No: Return (n MOD 8) BX LR
The following C code:
int Rem8(int n)
{
return n % 8 ;
}
is recognized as a special case (divisor is power of 2) and compiled by gcc version 5.4 with -O3 into:
Rem8: ldr r3, .L5
ands r3, r3, r0
cmp r3, #0
blt .L4
mov r0, r3
bx lr
.L4: subs r3, r3, #1
orn r3, r3, #7
adds r3, r3, #1
mov r0, r3
bx lr
.L5: .word -2147483641 // Same as 0x80000007
However, there's a much simpler and faster solution:
Rem8: AND R1,R0,7 // R1 = n MOD 8
TST R1,R0,ASR 31 // Is n < 0 && (n MOD 8) != 0 ?
ITE NE
SUBNE R0,R1,8 // Yes: Return (n MOD 8) - 8
MOVEQ R0,R1 // No: Return (n MOD 8)
BX LR