bge
bge
rs1, rs2, label
if (rs1 >= rs2) goto label
R
31–25funct7
24–20rs2
19–15rs1
14–12funct3
11–7rd
6–0opcode
I
31–20imm[11:0]
19–15rs1
14–12funct3
11–7rd
6–0opcode
S
31–25imm[11:5]
24–20rs2
19–15rs1
14–12funct3
11–7imm[4:0]
6–0opcode
B
31–25imm[12,10:5]
24–20rs2
19–15rs1
14–12funct3
11–7imm[4:1,11]
6–0opcode
U
31–12imm[31:12]
11–7rd
6–0opcode
J
31–12imm[20,10:1,11,19:12]
11–7rd
6–0opcode

bge is the partner of blt and its exact opposite. The name is branch if greater than or equal: bge rs1, rs2, label jumps to the labelled position when rs1 is at least rs2 (greater than *or* equal to it), and continues to the next instruction otherwise. For any two values, exactly one of blt and bge will branch — they divide every case between them. (See blt for the comparison itself and beq for branches in general.)

Its most common role is ending a loop from the top. A very standard loop shape puts the exit test first: bge t1, t2, done leaves the loop the moment the counter t1 reaches its limit t2, with the loop body below and an unconditional jump back to the top at the bottom. Testing first like this handles the zero-times case correctly — if the condition is already met, the body never runs at all.

The or equal part is what separates bge from a strictly-greater test: when the two values are equal, bge does branch. Getting this boundary right is the usual cure for loops that run one time too many or too few, so it is worth being deliberate — counting from 0 while staying below n means leaving exactly when the counter reaches n.

Like blt, the comparison is signed (values may be negative); bgeu is the unsigned version for addresses and sizes. Checking that a value is non-negative — bge t0, zero, ok — is a typical use.

bge t1, t2, done   # leave the loop once i >= n