1.14. CONDITIONAL JUMPS
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 theCSELinstruction, which works just asMOVccin ARM orCMOVccin x86, just the name is
different: “Conditional SELect”.
Listing 1.137: 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
MIPS
Unfortunately, GCC 4.4.5 for MIPS is not that good:
Listing 1.138: Optimizing GCC 4.4.5 (IDA)
my_max:
; set $v1 to 1 if $a1<$a0, or clear otherwise (if $a1>$a0):
slt $v1, $a1, $a0
; jump, if $v1 is 0 (or $a1>$a0):
beqz $v1, locret_10
; this is branch delay slot
; prepare $a1 in $v0 in case of branch triggered:
move $v0, $a1
; no branch triggered, prepare $a0 in $v0:
move $v0, $a0
locret_10:
jr $ra
or $at, $zero ; branch delay slot, NOP
; the min() function is same, but input operands in SLT instruction are swapped:
my_min:
slt $v1, $a0, $a1
beqz $v1, locret_28
move $v0, $a1
move $v0, $a0