1.Control Transfer Instruction
In RV32I, control transfer instructions are mainly divided into two categories: unconditional jump and conditional jump.
2. Unconditional Jump Instructions
Unconditional jump instructions all use PC-relative addressing. The unconditional jump mainly includes two instructions: JAL and JALR.
2.1 JAL
Jump And Link
The JAL instruction uses the J-type format (JAL is the only J-type instruction in RV32I).
Instruction Format
JAL rd,offset x[rd] = pc+4; pc += sext(offset)
Its machine code format is shown in Figure 1. Its opcode is 110_1111. The instruction stores the address of the next instruction (PC + 4) in the rd register, and then sets the PC to the current value plus the sign-extended offset.
Note that the offset is sign-extended. As can be seen, the offset is aligned with 2 bytes (offset [20:1]), although all instruction addresses in RV32I are aligned with 4 bytes, JAL may also be used for compatibility with the C extension instruction set. Therefore, it defaults that bit 0 of the offset is 0 (that is, aligned with 2 bytes).
Therefore, the address range of JAL jump is +/- 1MB. (2^21 = 2MB = +/- 1MB)
The standard software calling convention uses x1 register as the return address register (rd), and x5 can be used as a backup link register. Because the offset in the JAL instruction is the offset relative to the PC, precise address differences are required when writing, and if any assembly instructions are added or deleted, the offset in JAL may need to be modified again, which imposes a great burden on the use of the JAL instruction. Therefore, when using the JAL instruction, it is generally better to use JAL rd, label
instead of JAL rd, offset
.
The label in JAL rd, label
is a tag used to mark the position of a certain segment of the program, which provides a jump entry for jump and branch statements in the program (examples of using labels can be found here). The compiler will automatically calculate the label and the offset from the current instruction.
2.1.1 Example
JAL x1,main
To jump to the main function and store the address of the next instruction in the x1 register
The pseudo-instruction “JAL main” corresponds to the actual instruction “JAL x1, main”.
The pseudo-instruction “J main” corresponds to the actual instruction “JAL x0, main”.
Notice:
- There are two reasons why x5 register is chosen as a backup link register:
-
- It is used as a temporary variable in the standard calling convention.
- It differs from the regular link register x1 by only 1 bit, as x1 is
0_0001
and x5 is0_0101.
- If the rd operand is omitted in the JAL instruction, then the default value for rd is x1.
- The pseudo-instruction “J label”, the corresponding actual instruction is “JAL x0, label”. So the rd operand is set to x0 in this case
2.2 JALR
Jump And Link Redirect
The JALR instruction uses the I-type encoding format in RISC-V architecture.
Instruction Format
JALR rd,offset(rs1)
t = pc + 4; pc = (x[rs1]+sext(offset)) & ~1;
x[rd]=t
Equivalent to
t = pc + 4; pc = (x[rs1]+sext(offset)) & 0xffff_fffe; x[rd]=t // RV32I
Machine code as above Figure 2.
- opcode: 110_0111
- funct3: 000
The instruction sets the PC to the value in the rs1 register plus the sign-extended offset, sets the least significant bit of the calculated address to 0, and writes the original value of PC + 4 to the rd register. If the destination register is not needed, rd can be set to x0.
The offset of JALR is also sign-extended, and the address range of the offset in JALR is +/-2KB (2^12 = 4096 = 4KB = +/-2KB) relative to the address stored in the rs1 register. The JALR instruction is designed to allow two instruction sequences to jump to any position within the 32-bit absolute address range (because the jump range of the JAL instruction is not large enough).
2.2.1 Example
JALR x13,0(x1)
The instruction jumps to the address stored in register x1 and stores the address of the next instruction (PC+4) in register x13.
Other examples of pseudo instructions:
JR x1 => JALR x0, x1, 0
RET => JALR x0, x1, 0
JALR x13 => JALR x1, x13, 0
Generally, LUI and JALR can be used together to jump to a 32-bit absolute address range, while AUIPC and JALR can be used together to jump to a 32-bit address range relative to PC.
3. Conditional Branch Jump
All branch instructions are encoded in B-type format, and their machine code is shown in Figure 3. The 12-bit immediate value is encoded as a signed offset (offset[12:1]) in multiples of 2 bytes.
Although all instruction addresses in RV32I are aligned to 4-byte boundaries, JAL may still be used for compatibility with the C extension instruction set, so offset bit 0 is assumed to be 0 (i.e., 2-byte alignment) by default.
The target address is composed of the address of the branch instruction plus the sign-extended offset, with a range of : 2
13
= 8192 = 8 KB = +/- 4 KB
Similar to JAL, the branch instruction can also use labels instead of offsets, for example BEQ rs1, rs2, label
.
3.1 BEQ
Branch If EQual
Instruction Format:
BEQ rs1,rs2,offset. if (rs1 == rs2) pc += sext(offset)
As Shown in Figure 4,
- opcode: 110_0011
- funct3: 000
This instruction compares the values in the rs1 and rs2 registers. If they are equal, it sets the value of the PC to the current value plus the sign-extended offset.
3.1.1 Example
BEQ x12,x13,LOOP
Compare the values in registers x12 and x13. If they are equal, jump to the label LOOP.
3.2 BNE
Branch if Not Equal
Instruction Format:
BNE rs1,rs2,offset. if (rs1 ≠ rs2) pc += sext(offset)
As Shown in Figure 5,
- opcode: 110_0011
- funct3: 001
This instruction compares the values in the rs1 and rs2 registers. If they are not equal, it sets the value of the PC to the current value plus the sign-extended offset.
3.2.1 Example
BNE x12,x13,LOOP
Compare the values in registers x12 and x13. If they are not equal, jump to the label LOOP.
3.3 BLT
Branch if Less Than
Instruction Format:
BLT rs1,rs2,offset. if (rs1 <s rs2) pc += sext(offset)
As Shown in Figure 6,
- opcode: 110_0011
- funct3: 100
This instruction compares the value in the rs1 register with the value in the rs2 register (both considered as signed numbers). If the value in rs1 is less than the value in rs2, it sets the value of the PC to the current value plus the sign-extended offset.
3.3.1 Example
BLT x12,x13,LOOP
Compare the signed values in registers x12 and x13. If the value in register x12 is less than that in register x13, jump to the label LOOP.
3.4 BLTU
Branch if Less Than,Unsigned
Instruction Format:
BLTU rs1,rs2,offset. if (rs1 <u rs2) pc += sext(offset)
As Shown in Figure 7,
- opcode: 110_0011
- funct3: 110
This instruction compares the value in the rs1 register with the value in the rs2 register (both considered as unsigned numbers). If the value in rs1 is less than the value in rs2, it sets the value of the PC to the current value plus the sign-extended offset.
3.4.1 Example
BLTU x12,x13,LOOP
Compare the values in registers x12 and x13 as unsigned numbers, and if the value in register x12 is less than the value in register x13, jump to the label LOOP.
3.5 BGE
Branch if Greater than or Equal
Instruction Format:
BGE rs1,rs2,offset. if (rs1 ≥s rs2) pc += sext(offset)
As Shown in Figure 8,
- opcode: 110_0011
- funct3: 101
The instruction compares the value in register rs1 with the value in register rs2 (both treated as signed numbers), and if rs1 is greater than or equal to rs2, it sets the PC to the current value plus a sign-extended offset.
3.5.1 Example
BGE x12,x13,LOOP
Compare the values in registers x12 and x13 as signed integers. If the value in x12 is greater than or equal to the value in x13, jump to the label LOOP.
3.6 BGEU
Branch if Greater than or Equal,Unsigned
Instruction Format:
BGEU rs1,rs2,offset. if (rs1 ≥u rs2) pc += sext(offset)
As Shown in Figure 9,
- opcode: 110_0011
- funct3: 111
The instruction is to compare the value in register rs1 with the value in register rs2 as unsigned integers. If rs1 is greater than or equal to rs2, then the PC value is set to the current value plus the sign-extended offset.
3.6.1 Example
BGEU x12,x13,LOOP
Unsigned compare the values in register x12 and x13, if the value in x12 is greater than or equal to the value in x13, jump to label LOOP.