CHAPTER 12. CONDITIONAL JUMPS CHAPTER 12. CONDITIONAL JUMPS
12.2.4 Non-optimizing GCC 4.9 (ARM64)
ARM64 has instruction NEG for negating:
Listing 12.16: 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
12.2.5 MIPS.
Listing 12.17: 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
Here we see a new instruction: BLTZ (“Branch if Less Than Zero”). There is also the NEGU pseudoinstruction, which just
does subtraction from zero. The “U” suffix in both SUBU and NEGU implies that no exception to be raised in case of integer
overflow.
12.2.6 Branchless version?
You could have also a branchless version of this code. This we will review later:45 on page 493.
12.3 Ternary conditional operator
The ternary conditional operator in C/C++ has the following syntax:
expression? expression : expression
Here is an example:
const char* f (int a)
{
return a==10? "it is ten" : "it is not ten";
};