I don't like very much the distributed style of RISC-V instruction description of the official RISC-V ISA https://riscv.org/wp-content/uploads/2017/05/riscv-spec-v2.2.pdf
So I try to do my own, maybe someone else find it useful
Registers
Register | ABI Name | Description |
x0 | zero | Hardwired zero (READ ONLY) |
x1 | ra | Return Address |
x2 | sp | Stack Pointer |
x3 | gp | Global Pointer |
x4 | tp | Thread Pointer |
x5 | t0 | Temporary/alternate link register |
x6-x7 | t1-t2 | Temporaries |
x8 | s0/fp | Saved register/frame pointer |
x9 | s1 | Saved register |
x10-x11 | a0-a1 | Function arguments/return values |
x12-x17 | a2-a7 | Function arguments |
x18-x27 | s2-s11 | Saved registers |
x28-x31 | t3-t6 | Temporaries |
Types of Instructions
assuming the Instruction is a 32 bit value IR , we describe bit vectors in Verilog style IR[6:0] means the lower 7 bits of variable IR.
opcode=IR[6:0] (7 bits)
funct3=IR[14:12] (3 bits)
funct7=IR[31:25] (7 bits)
rs1=IR[19:15] (5 bits)
rs2=IR[24:20] (5 bits)
rd=IR[11:7] (5 bits)
imm12=IR[31:20]
imm20=IR[31:12]
shamt=IR[24:20]
imm_btype={IR[31],IR[7],IR[30:25],IR[11:8],0}
imm_stype={IR[31:25],IR[11:7]}
imm_btype={IR[]}
imm_jtype={IR[31],IR[19:12],IR[20],IR[30:21], 0}
Type | Description | Meaningful Fields |
R | Register | opcode, funct3, funct7, rs1, rs2, rd |
I | Immediate | opcode, funct3, rs1, rd, imm12 |
S | Store | opcode, funct3, rs1, rs2, imm_stype |
B | Branch offset | opcode, funct3, rs1, rs2, imm_btype |
U | ? | opcode, rd, imm20 |
J | Jump | opcode, rd, imm_jtype |
Instructions
ADDI (opcode=0x13, funct3=0x00, I-Type)
Add immediate
[rd] = [rs1] + signExtend(imm12)
BNE (opcode=0x63, funct3=0x01)
Branch Not Equal
if ([rs1] != [rs2]) pc = pc + signExtend(imm_btype)
ECALL (opcode=0x73, )
Executive System Call
JAL (opcode=0x6F, J-Type)
Jump and link. x0 is allowed as rd register, but it is obviously not written.
[rd] = [pc]+4
[pc] = [pc] + signExtend(imm_jtype)
JALR (opcode=0x67, I-Type)
Jump and link register. x0 is allowed as rd register, but it is obviously not written.
[rd] = [pc]+4
[pc] = ([rs1] + signExtend(imm12) ) & ~0x1
LBU (opcode=0x03, funct3=0x04, I-Type)
Load Byte Unsigned
add = [rs1]+signExtend(imm12)
add32 = add & ~0x3
addby = add & 0x3
[rd] = zeroExtend(([add]>>addby) & 0xFF)
LW (opcode=0x03, funct3=0x02, I-Type)
Load Word
add = [rs1]+signExtend(imm12)
[rd] = [add]
SW (opcode, S-Type)
Store Word
add = [rs1]+signExtend(imm_stype)
SLLI (opcode=0x13, funct3=0x01, I-Type)
Shift Left Immediate
[rd] = [rs1] << shamt
Fast Table
Opcode | Funct3 | Funct7 | Instruction | ISA |
0x03 | 0x0 | LB | RV32I | |
0x03 | 0x1 | LH | RV32I | |
0x03 | 0x2 | LW | RV32I | |
0x03 | 0x4 | LBU | RV32I | |
0x03 | 0x5 | LHU | RV32I | |
0x13 | 0x0 | ADDI | RV32I | |
0x13 | 0x1 | 0x0 | SLLI | RV32I |
0x13 | 0x5 | 0x0 | SRLI | RV32I |
0x13 | 0x2 | SLTI | RV32I | |
0x13 | 0x3 | SLTIU | RV32I | |
0x13 | 0x4 | XORI | RV32I | |
0x13 | 0x6 | ORI | RV32I | |
0x13 | 0x7 | ANDI | RV32I | |
0x17 | AUIPC | RV32I | ||
0x23 | 0x0 | SB | RV32I | |
0x23 | 0x1 | SH | RV32I | |
0x23 | 0x2 | SW | RV32I | |
0x23 | 0x3 | SD | RV64I | |
0x33 | 0x0 | 0x00 | ADD | RV32I |
0x33 | 0x0 | 0x01 | MUL | RV32M |
0x33 | 0x0 | 0x20 | SUB | RV32I |
0x33 | 0x1 | 0x00 | SLL | RV32M |
0x33 | 0x1 | 0x01 | MULH | RV32M |
0x33 | 0x2 | 0x01 | MULHSU | RV32M |
0x33 | 0x3 | 0x00 | SLTU | RV32I |
0x33 | 0x3 | 0x01 | MULHU | RV32M |
0x33 | 0x4 | 0x00 | XOR | RV32I |
0x33 | 0x4 | 0x01 | DIV | RV32M |
0x33 | 0x5 | 0x01 | DIVU | RV32M |
0x33 | 0x6 | 0x00 | OR | RV32I |
0x33 | 0x6 | 0x01 | REM | RV32M |
0x33 | 0x7 | 0x00 | AND | RV32M |
0x33 | 0x7 | 0x01 | REMU | RV32M |
0x33 | 0x7 | 0x05 | MAXU | RV32B |
0x37 | LUI | RV32I | ||
0x63 | 0x0 | BEQ | RV32I | |
0x63 | 0x1 | BNE | RV32I | |
0x63 | 0x4 | BLT | RV32I | |
0x63 | 0x5 | BGE | RV32I | |
0x63 | 0x6 | BLTU | RV32I | |
0x63 | 0x7 | BGEU | RV32I | |
0x67 | 0x0 | JALR | ||
0x6F | JAL | |||
0x73 | SYSTEM |