Risc-V支持16位壓縮格式,壓縮格式立即數位數更少,能使用的寄存器也比較少,有些指令只能用常用8個整數寄存器(x8-x15)或者(f8-f15)。16 位指令只對匯編器和鏈接器可見,並且是否以短指令取代對應的寬指令由它們決定。編譯器編寫者和匯編語言程序員可以幸福地忽略 RV32C 指令及其格式,他們能感知到的則是最后的程序大小小於大多數其它 ISA 的程序。
為了能在一系列的程序上得到良好的代碼壓縮效果, RISC-V 架構師精心挑選了 RVC擴展中的指令。同時,基於以下的三點觀察,架構師們成功地將指令壓縮到了 16 位。第一,對十個常用寄存器(a0-a5, s0-s1, sp 以及 ra)訪問的頻率遠超過其他寄存器;第二,許多指令的寫入目標是它的源操作數之一;第三,立即數往往很小,而且有些指令比較喜歡某些特定的立即數。因此,許多 RV32C 指令只能訪問那些常用寄存器;一些指令隱式寫入源操作數的位置;幾乎所有的立即數都被縮短了, load 和 store 操作只使用操作數整數倍尺寸的無符號數偏移量。
下圖為RVC指令格式:
其中rs1’,rs2’, rd’如下圖所示,只能用x8-x15,f8-f15這些寄存器。但有些指令可以使用所有通用寄存器作為操作數。
每個RVC指令都有對應的32位指令,下面列出所有的RV32C指令。
c.addispn
c.addi4spn rd’, uimm //x[8+rd’] = x[2] + uimm
加 4 倍立即數到棧指針 (Add Immediate, Scaled by 4, to Stack Pointer, Nondestructive). RV32IC and RV64IC.
擴展形式為 addi rd, x2, uimm, 其中 rd=8+rd’. uimm=0 時非法。
imm | |||||||||||||||||
func3 | 5 | 4 | 9 | 8 | 7 | 6 | 2 | 3 | rd' | opcode | |||||||
name | type | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
c.addi4spn | CIW | 0 | 0 | 0 | 0 | 0 |
示例:
to do
c.fld
c.fld rd’, uimm(rs1’) //f[8+rd’] = M[x[8+rs1’] + uimm][63:0]
浮點雙字加載 (Floating-point Load Doubleword). RV32DC and RV64DC.
擴展形式為 fld rd, uimm(rs1), 其中 rd=8+rd’, rs1=8+rs1’
imm | imm | ||||||||||||||||
func3 | 5 | 4 | 3 | rs1' | 7 | 6 | rd' | opcode | |||||||||
name | type | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
c.fld | CL | 0 | 0 | 1 | 0 | 0 |
示例:
to do
c.fsd
c.fsd rs2’, uimm(rs1’) //M[x[8+rs1’] + uimm][63:0] = f[8+rs2’]
浮點雙字存儲 (Floating-point Store Doubleword). RV32DC and RV64DC.
擴展形式為 fsd rs2, uimm(rs1), 其中 rs2=8+rs2’, rs1=8+rs1’
imm | imm | ||||||||||||||||
func3 | 5 | 4 | 3 | rs1' | 7 | 6 | rd' | opcode | |||||||||
name | type | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
c.fsd | CL | 1 | 0 | 1 | 0 | 0 |
示例:
to do
c.lw
c.lw rd’, uimm(rs1’) //x[8+rd’] = sext(M[x[8+rs1’] + uimm][31:0])
字加載 (Load Word). RV32IC and RV64IC.
擴展形式為 lw rd, uimm(rs1), 其中 rd=8+rd’, rs1=8+rs1’.
imm | imm | ||||||||||||||||
func3 | 5 | 4 | 3 | rs1' | 2 | 6 | rd' | opcode | |||||||||
name | type | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
c.lw | CL | 0 | 1 | 0 | 0 | 0 |
示例:
to do
c.addi
c.addi rd, imm //x[rd] = x[rd] + sext(imm)
加立即數 (Add Immediate). RV32IC and RV64IC.
擴展形式為 addi rd, rd, imm.
imm | imm | ||||||||||||||||
func3 | 5 | rd | 4 | 3 | 2 | 1 | 0 | opcode | |||||||||
name | type | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
c.addi | CI | 0 | 0 | 0 | 0 | 1 |
示例:
to do
c.jal
c.jal offset //x[1] = pc+2; pc += sext(offset)
鏈接跳轉 (Jump and Link). RV32IC.
擴展形式為 jal x1, offset.
imm | |||||||||||||||||
func3 | 11 | 4 | 9 | 8 | 10 | 6 | 7 | 3 | 2 | 1 | 5 | opcode | |||||
name | type | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
c.jal | CJ | 0 | 0 | 1 | 0 | 1 |
示例:
to do
c.li
c.li rd, imm //x[rd] = sext(imm)
立即數加載 (Load Immediate). RV32IC and RV64IC.
擴展形式為 addi rd, x0, imm.
imm | imm | ||||||||||||||||
func3 | 5 | rd | 4 | 3 | 2 | 1 | 0 | opcode | |||||||||
name | type | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
c.li | CI | 0 | 1 | 0 | 0 | 1 |
示例:
to do
c.lui
c.lui rd, imm //x[rd] = sext(imm[17:12] << 12)
高位立即數加載 (Load Upper Immediate). RV32IC and RV64IC.
擴展形式為 lui rd, imm. 當 rd=x2 或 imm=0 時非法。
imm | imm | ||||||||||||||||
func3 | 17 | rd | 16 | 15 | 14 | 13 | 12 | opcode | |||||||||
name | type | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
c.lui | CI | 0 | 1 | 1 | 0 | 1 |
示例:
to do
c.srli
c.srli rd’, uimm //x[8+rd’] = x[8+rd’] >>u uimm
立即數邏輯右移 (Shift Right Logical Immediate). RV32IC and RV64IC.
擴展形式為 srli rd, rd, uimm, 其中 rd=8+rd’
imm | imm | ||||||||||||||||
func3 | 5 | rd' | 4 | 3 | 2 | 1 | 0 | opcode | |||||||||
name | type | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
c.srli | CA | 1 | 0 | 0 | 0 | 0 | 0 | 1 |
示例:
to do
c.srai
c.srai rd’, uimm //x[8+rd’] = x[8+rd’] >>s uimm
立即數算術右移 (Shift Right Arithmetic Immediate). RV32IC and RV64IC.
擴展形式為 srai rd, rd, uimm, 其中 rd=8+rd’.
imm | imm | ||||||||||||||||
func3 | 5 | rd' | 4 | 3 | 2 | 1 | 0 | opcode | |||||||||
name | type | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
c.srai | CA | 1 | 0 | 0 | 0 | 1 | 0 | 1 |
示例:
to do
c.andi
c.andi rd’, imm //x[8+rd’] = x[8+rd’] & sext(imm)
與立即數 (AND Immediate). RV32IC and RV64IC.
擴展形式為 andi rd, rd, imm, 其中 rd=8+rd’.
imm | imm | ||||||||||||||||
func3 | 5 | rd' | 4 | 3 | 2 | 1 | 0 | opcode | |||||||||
name | type | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
c.andi | CA | 1 | 0 | 0 | 1 | 0 | 0 | 1 |
示例:
to do
c.sub
c.sub rd’, rs2’ //x[8+rd’] = x[8+rd’] - x[8+rs2’]
減 (Subtract). RV32IC and RV64IC.
擴展形式為 sub rd, rd, rs2. 其中 rd=8+rd’, rs2=8+rs2’.
rd' | rs2' | opcode | |||||||||||||||
name | type | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
c.sub | CA | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 1 |
示例:
to do
c.xor
c.xor rd’, rs2’ //x[8+rd’] = x[8+rd’] ^ x[8+rs2’]
異或 (Exclusive-OR). RV32IC and RV64IC.
擴展形式為 xor rd, rd, rs2, 其中 rd=8+rd’, rs2=8+rs2’.
rd' | rs2' | opcode | |||||||||||||||
name | type | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
c.xor | CA | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 1 |
示例:
to do
c.or
c.or rd’, rs2’ //x[8+rd’] = x[8+rd’] | x[8+rs2’]
或 (OR). RV32IC and RV64IC.
擴展形式為 or rd, rd, rs2, 其中 rd=8+rd’, rs2=8+rs2’.
rd' | rs2' | opcode | |||||||||||||||
name | type | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
c.or | CA | 1 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 0 | 1 |
示例:
to do
c.and
c.and rd’, rs2’ //x[8+rd’] = x[8+rd’] & x[8+rs2’]
與 (AND). RV32IC and RV64IC.
擴展形式為 and rd, rd, rs2, 其中 rd=8+rd’, rs2=8+rs2’
rd' | rs2' | opcode | |||||||||||||||
name | type | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
c.and | CA | 1 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 1 |
示例:
to do
c.subw
c.subw rd’, rs2’ //x[8+rd’] = sext((x[8+rd’] - x[8+rs2’])[31:0])
減字 (Subtract Word). RV64IC.
擴展形式為 subw rd, rd, rs2. 其中 rd=8+rd’, rs2=8+rs2’. .
rd' | rs2' | opcode | |||||||||||||||
name | type | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
c.subw | CA | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 1 |
示例:
to do
c.addw
c.addw rd’, rs2’ //x[8+rd’] = sext((x[8+rd’] + x[8+rs2’])[31:0])
加字 (Add Word). RV64IC.
擴展形式為 addw rd, rd, rs2, 其中 rd=8+rd’, rs2=8+rs2’.
rd' | rs2' | opcode | |||||||||||||||
name | type | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
c.addw | CA | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 1 |
示例:
to do
c.j
c.j offset //pc += sext(offset)
跳轉 (Jump). RV32IC and RV64IC.
擴展形式為 jal x0, offset.
imm | |||||||||||||||||
func3 | 11 | 4 | 9 | 8 | 10 | 6 | 7 | 3 | 2 | 1 | 5 | opcode | |||||
name | type | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
c.j | CJ | 1 | 0 | 1 | 0 | 1 |
示例:
to do
c.bnez
c.bnez rs1’, offset //if (x[8+rs1’] ≠ 0) pc += sext(offset)
不等於零時分支 (Branch if Not Equal to Zero). RV32IC and RV64IC.
擴展形式為 bne rs1, x0, offset, 其中 rs1=8+rs1’.
imm | imm | ||||||||||||||||
func3 | 8 | 4 | 3 | rs1' | 7 | 6 | 2 | 1 | 5 | opcode | |||||||
name | type | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
c.bnez | CI | 1 | 1 | 1 | 0 | 1 |
示例:
to do
c.beqz
c.beqz rs1’, offset //if (x[8+rs1’] == 0) pc += sext(offset)
等於零時分支 (Branch if Equal to Zero). RV32IC and RV64IC.
擴展形式為 beq rs1, x0, offset, 其中 rs1=8+rs1’.
imm | imm | ||||||||||||||||
func3 | 8 | 4 | 3 | rs1' | 7 | 6 | 2 | 1 | 5 | opcode | |||||||
name | type | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
c.beqz | CI | 1 | 1 | 0 | 0 | 1 |
示例:
to do
c.slli
c.slli rd, uimm //x[rd] = x[rd] << uimm
立即數邏輯左移 (Shift Left Logical Immediate). RV32IC and RV64IC.
擴展形式為 slli rd, rd, uimm.
imm | imm | ||||||||||||||||
func3 | 5 | rd | 4 | 3 | 2 | 1 | 0 | opcode | |||||||||
name | type | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
c.slli | CI | 0 | 0 | 0 | 1 | 0 |
示例:
to do
c.fldsp
c.fldsp rd, uimm(x2) //f[rd] = M[x[2] + uimm][63:0]
棧指針相關浮點雙字加載 (Floating-point Load Doubleword, Stack-Pointer Relative). RV32DC
and RV64DC.
擴展形式為 fld rd, uimm(x2).
imm | imm | ||||||||||||||||
func3 | 5 | rd | 4 | 3 | 8 | 7 | 6 | opcode | |||||||||
name | type | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
c.fldsp | CI | 0 | 0 | 1 | 1 | 0 |
示例:
to do
c.lwsp
c.lwsp rd, uimm(x2) //x[rd] = sext(M[x[2] + uimm][31:0])
棧指針相關字加載 (Load Word, Stack-Pointer Relative). RV32IC and RV64IC.
擴展形式為 lw rd, uimm(x2). rd=x0 時非法。
imm | imm | ||||||||||||||||
func3 | 5 | rd | 4 | 3 | 2 | 7 | 6 | opcode | |||||||||
name | type | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
c.lwsp | CI | 0 | 1 | 0 | 1 | 0 |
示例:
to do
c.flwsp
c.flwsp rd, uimm(x2) //f[rd] = M[x[2] + uimm][31:0]
棧指針相關浮點字加載 (Floating-point Load Word, Stack-Pointer Relative). RV32FC.
擴展形式為 flw rd, uimm(x2).
imm | imm | ||||||||||||||||
func3 | 5 | rd | 4 | 3 | 2 | 7 | 6 | opcode | |||||||||
name | type | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
c.flwsp | CI | 0 | 1 | 1 | 1 | 0 |
示例:
to do
c.mv
c.mv rd, rs2 //x[rd] = x[rs2]
移動 (Move). RV32IC and RV64IC.
擴展形式為 add rd, x0, rs2. rs2=x0 時非法
rd | rs2 | opcode | |||||||||||||||
name | type | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
c.mv | CA | 1 | 0 | 0 | 0 | 1 | 0 |
示例:
to do
c.fsdsp
c.fsdsp rs2, uimm(x2) //M[x[2] + uimm][63:0] = f[rs2]
棧指針相關浮點雙字存儲 (Floating-point Store Doubleword, Stack-Pointer Relative). RV32DC and RV64DC.
擴展形式為 fsd rs2, uimm(x2).
imm | |||||||||||||||||
5 | 4 | 3 | 8 | 7 | 6 | rs2 | opcode | ||||||||||
name | type | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
c.fsdsp | CSS | 1 | 0 | 1 | 1 | 0 |
示例:
to do
c.fswsp
c.fswsp rs2, uimm(x2) //M[x[2] + uimm][31:0] = f[rs2]
棧指針相關浮點字存儲 (Floating-point Store Word, Stack-Pointer Relative). RV32FC.
擴展形式為 fsw rs2, uimm(x2)
imm | |||||||||||||||||
5 | 4 | 3 | 2 | 7 | 6 | rs2 | opcode | ||||||||||
name | type | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
c.fswsp | CSS | 1 | 1 | 1 | 1 | 0 |
示例:
to do
c.nop
空操作,只增加PC值。對應 addi x0,x0,0
imm | imm | ||||||||||||||||
func3 | 5 | rd | 4 | 3 | 2 | 1 | 0 | opcode | |||||||||
name | type | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
c.nop | CI | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
示例:
to do
c.ebreak
c.ebreak RaiseException(Breakpoint)
環境斷點 (Environment Breakpoint). RV32IC and RV64IC.
擴展形式為 ebreak.
imm | imm | ||||||||||||||||
func3 | 5 | rd | 4 | 3 | 2 | 1 | 0 | opcode | |||||||||
name | type | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
c.nop | CI | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
示例:
to do
c.addi16sp
c.addi16sp imm //x[2] = x[2] + sext(imm)
加 16 倍立即數到棧指針 (Add Immediate, Scaled by 16, to Stack Pointer). RV32IC and RV64IC.
擴展形式為 addi x2, x2, imm. imm=0 時非法。
func3 | 9 | 4 | 6 | 8 | 7 | 5 | opcode | ||||||||||
name | type | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
c.addi16spn | CIW | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 |
示例:
to do
c.jr
c.jr rs1 //pc = x[rs1]
寄存器跳轉 (Jump Register). RV32IC and RV64IC.
擴展形式為 jalr x0, 0(rs1). 當 rs1=x0 時非法。
func3 | 9 | rs1 | opcode | ||||||||||||||
name | type | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
c.jr | CI | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
示例:
to do
c.jalr
c.jalr rs1 t = pc+2; pc = x[rs1]; x[1] = t
寄存器鏈接跳轉 (Jump and Link Register). RV32IC and RV64IC.
擴展形式為 jalr x1, 0(rs1). 當 rs1=x0 時非法
func3 | 9 | rs1 | opcode | ||||||||||||||
name | type | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
c.jalr | CI | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
示例:
to do
xxxxx
示例:
to do
xxxxx
示例:
to do