RISC-V的指令格式,官方总结的格式不够细致,有一些细节没有覆盖到,下面是我自己总结的(如有错误,以官方文档为准):
RISC-V基础非压缩指令格式非常简单,非常容易学习,而且硬件设计友好
基础压缩指令格式比较复杂,这是为了尽可能在16位编码空间装下更多指令,但指令数量有限,并且可以对应32位指令,也是很容易处理的
RISC-V并不需要硬件识别出所有非法指令,只需要将全0的最短编码和全1的最长编码识别为非法指令即可
基础非压缩指令(最低两位为11):
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
+-----------------------------------------------------------------------------------------------+
| funct7 | rs2 | rs1 | funct3 | rd | opcode | R
+-----------------------------------------------------------------------------------------------+
| funct5 |aq|rl| rs2 | rs1 | funct3 | rd | opcode | R.atomic
+-----------------------------------------------------------------------------------------------+
| funct5 | fmt | rs2 | rs1 | rm | rd | opcode | R.float
+-----------------------------------------------------------------------------------------------+
| rs3 | fmt | rs2 | rs1 | rm | rd | opcode | R4(fma)
+-----------------------------------------------------------------------------------------------+
| imm[11:0] | rs1 | funct3 | rd | opcode | I
+-----------------------------------------------------------------------------------------------+
| 0?00000 | shamt | rs1 | funct3 | rd | opcode | I.shift32i
+-----------------------------------------------------------------------------------------------+
| 0?0000 | shamt | rs1 | funct3 | rd | opcode | I.shift64i
+-----------------------------------------------------------------------------------------------+
| fm |PI|PO|PR|PW|SI|SO|SR|SW| rs1 | funct3 | rd | opcode | I.fence
+-----------------------------------------------------------------------------------------------+
| csr | rs1 | funct3 | rd | opcode | I.csr
+-----------------------------------------------------------------------------------------------+
| csr | uimm | funct3 | rd | opcode | I.csri
+-----------------------------------------------------------------------------------------------+
| imm[11:5] | rs2 | rs1 | funct3 | imm[4:0] | opcode | S
+-----------------------------------------------------------------------------------------------+
| imm[12|10:5] | rs2 | rs1 | funct3 | imm[4:1|11] | opcode | B
+-----------------------------------------------------------------------------------------------+
| imm[31:12] | rd | opcode | U
+-----------------------------------------------------------------------------------------------+
| imm[20|10:1|11|19:12] | rd | opcode | J
+-----------------------------------------------------------------------------------------------+
opcode(其中OP-V是V扩展加入的opcode,在基础指令集中为reserved,本文并不涉及V扩展):
+-------------------------------------------------------------------------------------------------+
|inst[4:2]| 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 |
|inst[6:5]| | | | | | | | |
+-------------------------------------------------------------------------------------------------+
| 00 | LOAD | LOAD-FP | custom-0 | MISC-MEM | OP-IMM | AUIPC | OP-IMM-32 | 48b |
| 01 | STORE | STORE-FP | custom-1 | AMO | OP | LUI | OP-32 | 64b |
| 10 | MADD | MSUB | NMSUB | NMADD | OP-FP | (OP-V) | custom-2/rv128 | 48b |
| 11 | BRANCH | JALR | reserved | JAL | SYSTEM | reserved | custom-3/rv128 | >=80b |
+-------------------------------------------------------------------------------------------------+
基础压缩指令(去掉了RV128)(最低两位为00 01 10):
注意:RV32/RV64有些操作码被分配给了不同指令:
1、op=00,funct3=011 C.FLW(RV32) <-> C.LD(RV64)
2、op=00,funct3=111 C.FSW(RV32) <-> C.SD(RV64)
3、op=01,funct3=001 C.JAL(RV32) <-> C.ADDIW(RV64)
4、op=10,funct3=011 C.FLWSP(RV32) <-> C.LDSP(RV64)
5、op=10,funct3=111 C.FSWSP(RV32) <-> C.SDSP(RV64)
短寄存器地址和长寄存器地址的换算关系:
rd/rs1/rs2 = { 2'b01, rd'/rs1'/rs2' } = rd'/rs1'/rs2' + 8
也就是说短寄存器地址只能访问x8~x15或f8~f15
其中:
1、Illegal Instruction表示非法指令
2、Reserved或RES表示保留给未来标准扩展的指令,可以视为非法指令,也可以don't care
3、NSE表示保留给非标准扩展的指令,可以定义为自定义指令,也可以视为非法指令,也可以don't care
4、HINT表示保留给微架构hint的指令,可以定义为自定义hint指令,也可以视为无可见效果的合法指令
15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
+-------------------------------------------------------------------------------+
| 000 | 0 | 0 | 00 | Illegal instruction
| 000 | nzuimm[5:4|9:6|2|3] | rd' | 00 | C.ADDI4SPN (RES, nzuimm=0)
+-------------------------------------------------------------------------------+
| 001 | uimm[5:3] | rs1' |uimm[7:6]| rd' | 00 | C.FLD
+-------------------------------------------------------------------------------+
| 010 | uimm[5:3] | rs1' |uimm[2|6]| rd' | 00 | C.LW
+-------------------------------------------------------------------------------+
| 011 | uimm[5:3] | rs1' |uimm[2|6]| rd' | 00 | C.FLW (RV32)
| 011 | uimm[5:3] | rs1' |uimm[7:6]| rd' | 00 | C.LD (RV64)
+-------------------------------------------------------------------------------+
| 100 | - | 00 | Reserved
+-------------------------------------------------------------------------------+
| 101 | uimm[5:3] | rs1' |uimm[7:6]| rs2' | 00 | C.FSD
+-------------------------------------------------------------------------------+
| 110 | uimm[5:3] | rs1' |uimm[2|6]| rs2' | 00 | C.SW
+-------------------------------------------------------------------------------+
| 111 | uimm[5:3] | rs1' |uimm[2|6]| rs2' | 00 | C.FSW (RV32)
| 111 | uimm[5:3] | rs1' |uimm[7:6]| rs2' | 00 | C.SD (RV64)
+-------------------------------------------------------------------------------+
15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
+-------------------------------------------------------------------------------+
| 000 |[5] | 0 | nzimm[4:0] | 01 | C.NOP (HINT, nzimm!=0)
| 000 |[5] | rs1/rd!=0 | nzimm[4:0] | 01 | C.ADDI (HINT, nzimm=0)
+-------------------------------------------------------------------------------+
| 001 | imm[11|4|9:8|10|6|7|3:1|5] | 01 | C.JAL (RV32)
| 001 |[5] | rs1/rd!=0 | imm[4:0] | 01 | C.ADDIW (RV64; RES, rd=0)
+-------------------------------------------------------------------------------+
| 010 |[5] | rd!=0 | imm[4:0] | 01 | C.LI (HINT, rd=0)
+-------------------------------------------------------------------------------+
| 011 |[9] | 2 | nzimm[4|6|8:7:5] | 01 | C.ADDI16SP (RES, nzimm=0)
| 011 |[17]| rd!={0,2} | nzimm[16:12] | 01 | C.LUI (RES, nzimm=0; HINT, rd=0)
+-------------------------------------------------------------------------------+
| 100 |[5] | 00 | rs1'/rd' | nzuimm[4:0] | 01 | C.SRLI (RV32 NSE, nzuimm[5]=1; HINT, nzuimm=0)
| 100 |[5] | 01 | rs1'/rd' | nzuimm[4:0] | 01 | C.SRAI (RV32 NSE, nzuimm[5]=1; HINT, nzuimm=0)
| 100 |[5] | 10 | rs1'/rd' | imm[4:0] | 01 | C.ANDI
| 100 | 0 | 11 | rs1'/rd' | 00 | rs2' | 01 | C.SUB
| 100 | 0 | 11 | rs1'/rd' | 01 | rs2' | 01 | C.XOR
| 100 | 0 | 11 | rs1'/rd' | 10 | rs2' | 01 | C.OR
| 100 | 0 | 11 | rs1'/rd' | 11 | rs2' | 01 | C.AND
| 100 | 1 | 11 | rs1'/rd' | 00 | rs2' | 01 | C.SUBW (RV64; RV32 RES)
| 100 | 1 | 11 | rs1'/rd' | 01 | rs2' | 01 | C.ADDW (RV64; RV32 RES)
| 100 | 1 | 11 | - | 10 | - | 01 | Reserved
| 100 | 1 | 11 | - | 11 | - | 01 | Reserved
+-------------------------------------------------------------------------------+
| 101 | imm[11|4|9:8|10|6|7|3:1|5] | 01 | C.J
+-------------------------------------------------------------------------------+
| 110 | imm[8|4:3] | rs1'/rd' | imm[7:6|2:1|5] | 01 | C.BEQZ
+-------------------------------------------------------------------------------+
| 111 | imm[8|4:3] | rs1'/rd' | imm[7:6|2:1|5] | 01 | C.BNEZ
+-------------------------------------------------------------------------------+
15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
+-------------------------------------------------------------------------------+
| 000 |[5] | rs1/rd!=0 | nzuimm[4:0] | 10 | C.SLLI (HINT, rd=0 or nzuimm=0; RV32 NSE, nzuimm[5]=1)
+-------------------------------------------------------------------------------+
| 001 |[5] | rd | uimm[4:3|8:6] | 10 | C.FLDSP
+-------------------------------------------------------------------------------+
| 010 |[5] | rd!=0 | uimm[4:2|7:6] | 10 | C.LWSP
+-------------------------------------------------------------------------------+
| 011 |[5] | rd | uimm[4:2|7:6] | 10 | C.FLWSP (RV32)
| 011 |[5] | rd!=0 | uimm[4:3|8:6] | 10 | C.LDSP (RV64)
+-------------------------------------------------------------------------------+
| 100 | 0 | rs1!=0 | 0 | 10 | C.JR (RES, rs1=0)
| 100 | 0 | rd!=0 | rs2!=0 | 10 | C.MV (HINT, rd=0)
| 100 | 1 | 0 | 0 | 10 | C.EBREAK
| 100 | 1 | rs1!=0 | 0 | 10 | C.JALR
| 100 | 1 | rs1/rd!=0 | rs2!=0 | 10 | C.ADD (HINT, rd=0)
+-------------------------------------------------------------------------------+
| 101 | uimm[5:3|8:6] | rs2 | 10 | C.FSDSP
+-------------------------------------------------------------------------------+
| 110 | uimm[5:2|7:6] | rs2 | 10 | C.SWSP
+-------------------------------------------------------------------------------+
| 111 | uimm[5:2|7:6] | rs2 | 10 | C.FSWSP (RV32)
| 111 | uimm[5:3|8:6] | rs2 | 10 | C.SDSP (RV64)
+-------------------------------------------------------------------------------+
版权声明:本文为defrag257原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。