RISC-V full size Instructions Formats (32bit):
==============================================
.. contents::
R-format: op(rs1, rs2) -> rd
----------------------------
``opcode[7] rd[5] funct3[3] rs1[5] rs2[5] funct7[7]``
OPR - register arithmetic/logic
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
opcode: 0b0110011 / 0x33
====== ====== =========
funct7 funct3 operation
====== ====== =========
0x0 0x0 ADD
0x20 0x0 SUB
0x0 0x1 SLL
0x0 0x2 SLT
0x0 0x3 SLTU
0x0 0x4 XOR
0x0 0x5 SRL
0x20 0x5 SRA
0x0 0x6 OR
0x0 0x7 AND
====== ====== =========
I-Format: op(rs1, imm12) -> rd
------------------------------
``opcode[7] rd[5] funct3[3] rs1[5] imm[12]``
LOAD - read memory
~~~~~~~~~~~~~~~~~~
opcode: 0b0000011 / 0x03
- rs1: base address
- imm12: offset (scaled/signed by funct3)
====== ========= ===
funct3 operation
====== ========= ===
0x0 LB i8
0x1 LH i16
0x2 LW i32
0x4 LBU u8
0x5 LHU u16
====== ========= ===
OPI - immediate arhitmetic/logic
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
opcode: 0b0010011 / 0x13
- rs1: base address
- imm12: offset (scaled/signed by funct3)
====== ========= ============================
funct3 operation
====== ========= ============================
0x0 ADDI
0x2 SLTI
0x3 SLTIU
0x4 XORI
0x6 ORI
0x7 ANDI
0x1 SLLI imm12 = 0b0000000 , shamt[5]
0x5 SRLI imm12 = 0b0000000 , shamt[5]
0x5 SRAI imm12 = 0b0100000 , shamt[5]
====== ========= ============================
JALR - jump relative to register
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
opcode = 0b1100111 / 0x67
- rs1: base address
- imm12: offset (bytes)
- save PC+4 in rd
- jump to offset
S-format: op(rs1, rs2, imm12)
-----------------------------
``opcode[7] imm4:0[5] funct3[3] rs1[5] rs2[5] imm11:5[7]``
STORE - write memory
~~~~~~~~~~~~~~~~~~~~
opcode: 0b0100011 / 0x23
- rs1: base address
- rs2: data
- imm12: offset (scaled/signed by funct3)
====== ========= ========================
funct3 operation
====== ========= ========================
0x0 SB i8, imm12 in bytes
0x1 SH i16, imm12 in half-words
0x2 SW i32, imm13 in words
====== ========= ========================
B-format: op(rs1, rs2, imm12/13)
--------------------------------
``opcode[7] imm11[1] imm4:1[4] funct3[3] rs1[5] rs2[5] imm10:5[6] imm12[1]``
BRANCH - conditional jump
~~~~~~~~~~~~~~~~~~~~~~~~~
opcode = 0b1100011 / 0x63
- rs1, rs2: registers to compare
- imm12/13: PC offset in half-words
====== =========
funct3 operation
====== =========
0x0 BEQ
0x1 BNE
0x4 BLT
0x5 BGE
0x6 BLTU
0x7 BGEU
====== =========
U-Format: op(imm20/32) -> rd
----------------------------
``opcode[7] rd[5] imm31:12[20]`` upper-bit immediates (lui, auipc)
LUI - load upper immediate
~~~~~~~~~~~~~~~~~~~~~~~~~~
opcode: 0b0110111 / 0x37
- imm20: top 20 bits of rd
- clears bottom 12 bits
- combine lui + addi to load 32bit immediate NOTE: sign extension
requires some trickery.
AUIPC - add upper immediate to PC
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
opcode: 0b0010111 / 0x17
- imm20: top 20 bits of offset added to PC
- result stored in rd
J-Format: op(imm20/21) -> rd
----------------------------
``opcode[7] rd[5] imm31:12[20]`` immediates on a 32bit scale (jal)
JAL - relative jump
~~~~~~~~~~~~~~~~~~~
opcode = 0b1101111 / 0x6f
- save PC+4 in rd
- imm20/21: PC offset in half-words