RV64I是RV32I的超集,RV32I是RV64I的子集。RV64I包括RV32I的所有40条指令,另外增加了12条RV32I中没有的指令,还有三条移位指令(slli, srli,srai)也进行小小的改动。
在RV64I中,整数寄存器是64位的,即xlen=64,所以每条指令中的寄存器都是64位运算,立即数符号位扩展也是到64位。
下面介绍一下RV64I中新增的指令,对于同一条指令在RV64I和RV32I中,操作的不同,会在RV32I指令集的介绍中给出备注。
ld
ld rd, offset(rs1) //x[rd] = M[x[rs1] + sext(offset)][63:0]
双字加载 (Load Doubleword). I-type, RV64I.
从地址 x[rs1] + sign-extend(offset)读取八个字节,写入 x[rd]。
压缩形式: c.ldsp rd, offset; c.ld rd, offset(rs1)
imm | |||||||||||||||||||||||||||||||||
11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | rs1 | func3 | rd | opcode | ||||||||||||||||||
name | type | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
ld | I | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
例子:
0000000000000000 <.text>:
0: 00513503 ld x10,5(x2)
4: fec1b283 ld x5,-20(x3)
lwu
lwu rd, offset(rs1) //x[rd] = M[x[rs1] + sext(offset)][31:0]
无符号字加载 (Load Word, Unsigned). I-type, RV64I.
从地址 x[rs1] + sign-extend(offset)读取四个字节,零扩展后写入 x[rd]。
imm | |||||||||||||||||||||||||||||||||
11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | rs1 | func3 | rd | opcode | ||||||||||||||||||
name | type | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
lwu | I | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
例子:
0: 00516503 lwu x10,5(x2)
4: fec1e283 lwu x5,-20(x3)
sd
sd rs2, offset(rs1) //M[x[rs1] + sext(offset) ]= x[rs2][63: 0]存双字(Store Doubleword). S-type, RV64I.
将 x[rs2]中的 8 字节存入内存地址 x[rs1]+sign-extend(offset)。
压缩形式: c.sdsp rs2, offset; c.sd rs2, offset(rs1)
imm | imm | ||||||||||||||||||||||||||||||||
11 | 10 | 9 | 8 | 7 | 6 | 5 | rs2 | rs1 | func3 | 4 | 3 | 2 | 1 | 0 | opcode | ||||||||||||||||||
name | type | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
sd | S | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 1 | 1 |
例子:
0: 00a132a3 sd x10,5(x2)
4: fe51b623 sd x5,-20(x3)
addiw
addiw rd, rs1, immediate //x[rd] = sext((x[rs1] + sext(immediate))[31:0])加立即数字(Add Word Immediate). I-type, RV64I.
把符号位扩展的立即数加到 x[rs1],将结果截断为 32 位,把符号位扩展的结果写入 x[rd]。忽略算术溢出。
压缩形式: c.addiw rd, imm
imm | |||||||||||||||||||||||||||||||||
11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | rs1 | func3 | rd | opcode | ||||||||||||||||||
name | type | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
addiw | I | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 1 |
例子:
0: 0142851b addiw x10,x5,20
4: fec2851b addiw x10,x5,-20
slliw
slliw rd, rs1, shamt //x[rd] = sext((x[rs1] ≪ shamt)[31: 0])立即数逻辑左移字(Shift Left Logical Word Immediate). I-type, RV64I.
把寄存器 x[rs1]左移 shamt 位,空出的位置填入 0,结果截为 32 位,进行有符号扩展后写入x[rd]。仅当 shamt[5]=0 时,指令才是有效的。
shamt | |||||||||||||||||||||||||||||||||
5 | 4 | 3 | 2 | 1 | 0 | rs1 | func3 | rd | opcode | ||||||||||||||||||||||||
name | type | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
slliw | I | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 1 |
例子:
0: 0064951b slliw x10,x9,0x6
4: 0024951b slliw x10,x9,0x2
srliw
srliw rd, rs1, shamt //x[rd] = sext(x[rs1][31: 0] ≫u shamt)
立即数逻辑右移字(Shift Right Logical Word Immediate). I-type, RV64I.
把寄存器 x[rs1]右移 shamt 位,空出的位置填入 0,结果截为 32 位,进行有符号扩展后写入x[rd]。仅当 shamt[5]=0 时,指令才是有效的。
shamt | |||||||||||||||||||||||||||||||||
5 | 4 | 3 | 2 | 1 | 0 | rs1 | func3 | rd | opcode | ||||||||||||||||||||||||
name | type | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
srliw | I | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 1 |
例子:
0: 0064d51b srliw x10,x9,0x6
4: 0024d51b srliw x10,x9,0x2
sraiw
sraiw rd, rs1, shamt //x[rd] = sext(x[rs1][31: 0] ≫s shamt)
立即数算术右移字(Shift Right Arithmetic Word Immediate). I-type, RV64I.
把寄存器 x[rs1]的低 32 位右移 shamt 位,空位用 x[rs1][31]填充,结果进行有符号扩展后写入 x[rd]。仅当 shamt[5]=0 时指令有效。
压缩形式: c.srai rd, shamt
shamt | |||||||||||||||||||||||||||||||||
5 | 4 | 3 | 2 | 1 | 0 | rs1 | func3 | rd | opcode | ||||||||||||||||||||||||
name | type | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
sraiw | I | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 1 |
例子:
0: 4064d51b sraiw x10,x9,0x6
4: 4024d51b sraiw x10,x9,0x2
addw
addw rd, rs1, rs2 //x[rd] = sext((x[rs1] + x[rs2])[31:0])
加字(Add Word). R-type, RV64I.
把寄存器 x[rs2]加到寄存器 x[rs1]上,将结果截断为 32 位,把符号位扩展的结果写入 x[rd]。忽略算术溢出。
压缩形式: c.addw rd, rs2
func7 | rs2 | rs1 | func3 | rd | opcode | ||||||||||||||||||||||||||||
name | type | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
addw | R | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 1 |
例子:
0: 0034853b addw x10,x9,x3
subw
subw rd, rs1, rs2 //x[rd] = sext((x[rs1] - x[rs2])[31: 0])
减去字(Substract Word). R-type, RV64I.
x[rs1]减去 x[rs2],结果截为 32 位,有符号扩展后写入 x[rd]。忽略算术溢出。
压缩形式: c.subw rd, rs2
func7 | rs2 | rs1 | func3 | rd | opcode | ||||||||||||||||||||||||||||
name | type | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
subw | R | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 1 |
例子:
4: 4034853b subw x10,x9,x3sllw
sllw rd, rs1, rs2 //x[rd] = sext((x[rs1] ≪ x[rs2][4: 0])[31: 0])
逻辑左移字(Shift Left Logical Word). R-type, RV64I.
把寄存器 x[rs1]的低 32 位左移 x[rs2]位,空出的位置填入 0,结果进行有符号扩展后写入x[rd]。 x[rs2]的低 5 位代表移动位数,其高位则被忽略。
func7 | rs2 | rs1 | func3 | rd | opcode | ||||||||||||||||||||||||||||
name | type | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
sllw | R | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 0 | 1 | 1 |
例子:
8: 0034953b sllw x10,x9,x3srlw
srlw rd, rs1, rs2 //x[rd] = sext(x[rs1][31: 0] ≫u x[rs2][4: 0])
逻辑右移字(Shift Right Logical Word). R-type, RV64I.
把寄存器 x[rs1]的低 32 位右移 x[rs2]位,空出的位置填入 0,结果进行有符号扩展后写入x[rd]。 x[rs2]的低 5 位代表移动位数,其高位则被忽略。
func7 | rs2 | rs1 | func3 | rd | opcode | ||||||||||||||||||||||||||||
name | type | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
srlw | R | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | 0 | 1 | 1 |
例子:
c: 0034d53b srlw x10,x9,x3sraw
sraw rd, rs1, rs2 //x[rd] = sext(x[rs1][31: 0] ≫s x[rs2][4: 0])
算术右移字(Shift Right Arithmetic Word). R-type, RV64I only.
把寄存器 x[rs1]的低 32 位右移 x[rs2]位,空位用 x[rs1][31]填充,结果进行有符号扩展后写
入 x[rd]。 x[rs2]的低 5 位为移动位数,高位则被忽略。
func7 | rs2 | rs1 | func3 | rd | opcode | ||||||||||||||||||||||||||||
name | type | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
sraw | R | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | 0 | 1 | 1 |
例子:
10: 4034d53b sraw x10,x9,x3