How are conditional branches implemented differently on Intel x86 versus RISC-V?
Intel splits it into two instructions — a cmp that sets flags, then a flag-reading conditional jump; RISC-V does the compare-and-branch in a single instruction.
* x86 splits a conditional branch into cmp (sets flags) plus jcc (reads flags); RISC-V fuses compare and branch into one instruction. *
For the high-level idea if (operand1 <cond> operand2) goto label:
| Architecture | Instructions |
|---|---|
| Intel x86 | cmp operand2, operand1 (note the reversed order in AT&T syntax), then j<cond> label |
| RISC-V | b<cond> operand1, operand2, label (one instruction) |
# Intel: is %r8 < %rsi ?
cmp %rsi, %r8 # sets the flags from (%r8 - %rsi)
jl .L2 # jump if the result was "less than"
Why two instructions on x86? The cmp records the outcome in CPU condition flags, and the jump reads those flags. Decoupling them means one comparison can drive several different decisions (e.g. a cmp followed by both a jl and later a je), and the same flags can also feed a setX or cmovX.
Watch out: In AT&T syntax cmp %rsi, %r8 computes %r8 - %rsi, so the second operand is the left-hand side of the comparison — easy to misread.
Go deeper:
Jcc — x86 conditional-jump reference — the x86 Jcc family that reads the flags.
CMP — x86 instruction reference — CMP, the instruction that sets those flags.
FLAGS register (Wikipedia) — the condition flags that sit between the two instructions.