CHAPTER 12. CONDITIONAL JUMPS CHAPTER 12. CONDITIONAL JUMPS
ldr x1, [sp,8]
ldr x0, [sp]
cmp x1, x0
bge .L5
ldr x0, [sp,8]
b .L6
.L5:
ldr x0, [sp]
.L6:
add sp, sp, 16
ret
Branchless
No need to load function arguments from the stack, as they are already in the registers:
Listing 12.31: Optimizing GCC 4.9.1 x64
my_max:
; RDI=A
; RSI=B
; compare A and B:
cmp rdi, rsi
; prepare B in RAX for return:
mov rax, rsi
; if A>=B, put A (RDI) in RAX for return.
; this instruction is idle if otherwise (if A<B)
cmovge rax, rdi
ret
my_min:
; RDI=A
; RSI=B
; compare A and B:
cmp rdi, rsi
; prepare B in RAX for return:
mov rax, rsi
; if A<=B, put A (RDI) in RAX for return.
; this instruction is idle if otherwise (if A>B)
cmovle rax, rdi
ret
MSVC 2013 does almost the same.
ARM64 has the CSEL instruction, which works just as MOVcc in ARM or CMOVcc in x86, just the name is different: “Conditional
SELect”.
Listing 12.32: Optimizing GCC 4.9.1 ARM64
my_max:
; X0=A
; X1=B
; compare A and B:
cmp x0, x1
; select X0 (A) to X0 if X0>=X1 or A>=B (Greater or Equal)
; select X1 (B) to X0 if A<B
csel x0, x0, x1, ge
ret
my_min:
; X0=A
; X1=B
; compare A and B:
cmp x0, x1
; select X0 (A) to X0 if X0<=X1 or A<=B (Less or Equal)
; select X1 (B) to X0 if A>B
csel x0, x0, x1, le
ret