Conditional Selection
Branchless Conditional Logic
Branches (B.EQ, B.GT, etc.) work well, but they can be expensive on modern processors because they disrupt the instruction pipeline. ARM64 provides conditional selection instructions that choose between two values without branching.
Much like the Kobayashi Maru, sometimes you pick one outcome, sometimes another -- but with CSEL, the CPU always has a choice and never needs to cheat the no-win scenario.
CSEL -- Conditional Select
CSEL picks one of two registers based on a condition:
CMP X0, X1
CSEL X2, X3, X4, GT // if X0 > X1 then X2 = X3 else X2 = X4
This is like the C ternary operator: X2 = (X0 > X1) ? X3 : X4.
CSINC -- Conditional Select and Increment
CSINC selects the first register if true, or the second register plus one if false:
CMP X0, #10
CSINC X1, X2, X3, EQ // if X0 == 10 then X1 = X2 else X1 = X3 + 1
A common pattern is using CSINC with XZR to create a boolean flag. Remember: CSINC Xd, XZR, XZR, cond returns 0 when the condition is true and 1 when it is false (because the "increment" path runs on the false branch). So to set X2 to 1 when X0 equals X1, you use the opposite condition (NE):
CMP X0, X1
CSINC X2, XZR, XZR, NE // condition NE is false when equal, so X2 = 0 + 1 = 1
// condition NE is true when not equal, so X2 = 0
In other words, CSINC Xd, XZR, XZR, NE means "set Xd to 1 if equal, 0 otherwise." This is exactly what the CSET pseudo-instruction does: CSET X2, EQ is shorthand for CSINC X2, XZR, XZR, NE. The inverted condition is intentional -- CSET always encodes the opposite condition because the +1 happens on the false path of CSINC.
CSNEG -- Conditional Select and Negate
CSNEG selects the first register if true, or the negation of the second register if false:
CMP X0, #0
CSNEG X1, X0, X0, GE // if X0 >= 0 then X1 = X0 else X1 = -X0
This computes the absolute value of X0 in a single instruction (after CMP)!
CSINV -- Conditional Select and Invert
CSINV selects the first register if true, or the bitwise NOT of the second register if false:
CMP X0, #0
CSINV X1, X0, X0, GE // if X0 >= 0 then X1 = X0 else X1 = ~X0
Branchless Max and Min
Finding the maximum of two values without any branches:
CMP X0, X1
CSEL X2, X0, X1, GT // X2 = max(X0, X1)
CSEL X3, X0, X1, LT // X3 = min(X0, X1)
Branchless Clamping
Clamping a value to a range [lo, hi]:
// Clamp X0 to [10, 50]
CMP X0, #10
CSEL X0, X0, X10, GT // X0 = max(X0, 10) -- where X10 holds 10
CMP X0, #50
CSEL X0, X0, X11, LT // X0 = min(X0, 50) -- where X11 holds 50
Your Task
Compute the absolute value of -17 using CSNEG (no branches). Load -17 by computing 0 - 17, then use CMP and CSNEG to get the absolute value (17). Print it followed by a newline.