On Day 8 the S suffix set the flags. Today we use them — and meet ARM's most distinctive trick: almost any instruction can run conditionally. It's how ARM does if without always paying for a branch.
From Day 3, the CPSR holds four condition flags: N (negative), Z (zero), C (carry), V (overflow). Instructions with the S suffix (or CMP/TST) set them. Now we read them to decide what runs.
A two-letter condition code names a test on the flags. Here are the ones you'll actually use:
| Code | Meaning | Type |
|---|---|---|
| EQ / NE | equal / not equal (Z=1 / Z=0) | any |
| GE / LT | ≥ / < (signed) | signed |
| GT / LE | > / ≤ (signed) | signed |
| HI / LS | > / ≤ (unsigned) | unsigned |
| HS / LO | ≥ / < (unsigned) (=CS/CC) | unsigned |
| MI / PL | negative / positive-or-zero | sign |
| VS / VC | overflow set / clear | overflow |
| AL | always (the default) | — |
Comparing signed integers? Use GT/LT/GE/LE. Comparing addresses, sizes, or unsigned values? Use HI/LS/HS/LO. Picking the wrong family is a classic bug — e.g. an address comparison that breaks when the top bit is set.
The everyday use is on branches: do the compare, then branch on the result.
Here's what makes classic ARM special. You can append a condition code to almost any instruction, not just branches. If the condition is false, the instruction simply does nothing (a no-op) — no branch needed:
Both moves are fetched; the CPU executes the one whose condition holds and skips the other. No branch means no pipeline flush (Day 7) — for a short if, that's faster and tighter.
The whole conditional body is two predicated instructions — elegant and flush-free.
A conditional instruction can also set flags by adding S (e.g. ADDEQS → written ADDSEQ). Order matters in syntax, and over-using flag-setting inside a conditional chain can break the next condition — keep chains short and deliberate.
IT = If-Then), which makes up to four following instructions conditional.CSEL) — modern branch predictors made wide predication less worthwhile.Compute → set flags (S / CMP) → react. React with a conditional branch, or — ARM's trick — a conditional instruction that runs only when the flags agree. Short ifs become a couple of predicated instructions with no branch penalty.
MOVEQ, SUBGT) — false = no-op.BGT or BHI?MOVNE r1, #2 do when Z=1?if be faster than branching?Appending a condition code so an instruction runs only when the flags match (e.g. ADDEQ); otherwise it's a no-op. ARM's signature feature.
Signed: GT/LT/GE/LE. Unsigned: HI/LS/HS/LO. Use unsigned for addresses and sizes.
A64 keeps conditional branches and conditional-select (CSEL) but dropped general predication of every instruction.