1.14. CONDITIONAL JUMPS
; skip RSBS instruction then
BGE |L0.6|
; subtract input value from 0:
RSBS r0,r0,#0
|L0.6|
BX lr
ENDP
ARM lacks a negate instruction, so the Keil compiler uses the “Reverse Subtract” instruction, which just
subtracts with reversed operands.
Optimizing Keil 6/2013: ARM mode
It is possible to add condition codes to some instructions in ARM mode, so that is what the Keil compiler
does:
Listing 1.120: Optimizing Keil 6/2013: ARM mode
my_abs PROC
CMP r0,#0
; execute "Reverse Subtract" instruction only if input value is less than 0:
RSBLT r0,r0,#0
BX lr
ENDP
Now there are no conditional jumps and this is good:2.10.1 on page 466.
Non-optimizing GCC 4.9 (ARM64)
ARM64 has instructionNEGfor negating:
Listing 1.121: Optimizing GCC 4.9 (ARM64)
my_abs:
sub sp, sp, #16
str w0, [sp,12]
ldr w0, [sp,12]
; compare input value with contents of WZR register
; (which always holds zero)
cmp w0, wzr
bge .L2
ldr w0, [sp,12]
neg w0, w0
b .L3
.L2:
ldr w0, [sp,12]
.L3:
add sp, sp, 16
ret
MIPS
Listing 1.122: Optimizing GCC 4.4.5 (IDA)
my_abs:
; jump if $a0<0:
bltz $a0, locret_10
; just return input value ($a0) in $v0:
move $v0, $a0
jr $ra
or $at, $zero ; branch delay slot, NOP
locret_10:
; negate input value and store it in $v0:
jr $ra
; this is pseudoinstruction. in fact, this is "subu $v0,$zero,$a0" ($v0=0-$a0)
negu $v0, $a0