Lesson 11 of 28

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.

ARM64 runtime loading...
Loading...
Click "Run" to execute your code.