RISC-V的指令格式

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版权协议,转载请附上原文出处链接和本声明。