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