Chapter 17: Conditional Select
The ARM64 instruction set includes some special instructions that are known as Conditional Select Instructions.
Conditional Select:
csel xD, xN, xM, cond
csel wD, wN, wM, cond
cond would be something such as "eq", "lt", or "ne". Simply put, you are using a conditional branch instruction name but excluding the "b".
In plane English, the csel instruction (extended version) does this...
Conditional Increment:
cinc xD, xN, cond
cinc wD, wN, cond
In plane English, the cinc instruction (extended version) does this...
Conditional Select Increment:
csinc xD, xN, xM, cond
csinc wD, wN, wM, cond
In plane English, the csinc instruction (extended version) does this..
The csel, cinc, and csinc instructions can optimize some traditional code that used typical compare and branch instructions.
Example 1 (if w0 = 0 then w4 == w3, or else w4 == w2)
A beginner may write out the example with this sequence....
cmp w0, #0
bne else
mov w4, w3
b end
else:
mov w4, w2
end:
Alternatively a beginner may also write the example like this...
cmp w0, #0
mov w4, w3 // Preload w4 with w3 for it the cond is true when its determined by the following beq branch
beq cond_was_true
mov w4, w2 // Condition not met, update w4 with w2 instead
cond_was_true:
Regardless, we can fully optimize it to this...
cmp w0, #0
csel w4, w3, w2, eq
---
Example 2 (If w0 =/= 0 then w1 will be incremented by 1, or else do nothing)
A beginner may write out the example like this...
cmp w0, #0
beq else
add w1, w1, #1
else:
We can optimize the above to this...
cmp w0, #0
cinc w1, w1, ne
---
Example 3 (If w0 == 0 then increment w1 by 1 or else decrement it by 1)
A beginner may write out the example like this...
cmp w0, #0
bne else
add w1, w1, #1
b end
else:
sub w1, w1, #1
end:
We can optimize the above to this...
cmp w0, #0
sub w2, w1, #1 //using w2 as a temp scratch register
csinc w1, w2, w1, ne