Menu Close

RISC-V指令集讲解(4)R-Type 整数寄存器-寄存器指令

1. R-Type整数寄存器-寄存器指令

 

相关参考文章:

RISC-V教学教案

 

上文RISC-V指令集讲解(3)I-Type 移位指令和U-type指令介绍完了整数寄存器-立即数指令,本文开始进行整数寄存器-寄存器指令的讲解。

RV32I定义了几种算术R-type运算。 所有操作都将rs1和rs2寄存器作为源操作数读取,并将结果写入寄存器rd,注意R-type指令没有立即数,只有寄存器rs1,rs2和rd。

funct7和funct3字段选择操作类型,如图1所示。

R-type一共有10条指令,opcode名称为OP,值为011_0011(所有的R-type指令的opcode都相同)。

 

RISC-V整数寄存器-寄存器指令

图1 整数寄存器-寄存器指令机器编码格式 [1]

 

 

1.1. ADD

ADD指令与RISC-V指令集讲解(2)I-Type整数寄存器-立即数指令中提到的ADDI指令的操作原理类似,唯一区别是原本是12位立即数的位置,拆分为了7位的funct7和5位的rs2。

ADD指令格式为ADD rd,rs1,rs2。x[rd] = x[rs1] + x[rs2]

如图2所示,ADD指令的funct7为000_0000,funct3为000。该指令是将rs1 + rs2的结果写入rd中。注意:不是由机器码位置的bit 15-19和bit 20-24相加,而是索引号对应的寄存器的值相加。

与ADDI类似,溢出的部分忽略(溢出处理可以由软件实现,这里介绍如何处理),只将低XLEN位写入rd。

加法溢出的举例为,两个8位二进制有符号数相加,0100_0000(64) + 0111_0000(112) = 1011_0000(-80),结果明显是错误的。

指令示例:

ADD x14,x12,x13

将x12和x13寄存器中的数相加,并将结果放入x14寄存器中。

OP-IMM为011_0011

funct3为000

funct7为7’b000_0000

rs2为5’b0_1101

rs1为 5’b0_1100

rd为 5’b0_1110

所以ADD x14,x12,x13 对应的机器码为0000000_01101_01100_000_01110_0110011,对应的16进制为32’h00d6_0733

RISC-V ADD机器码

图2 ADD机器编码格式 [2]

%title插图%num

 

1.2. SLT

同样,SLT与SLTI类似,SLT指令格式为SLT rd,rs1,rs2。x[rd] = x[rs1] <𝑠  x[rs2]

如图3所示,SLT指令的funct7为000_0000,funct3为010。rs1和rs2当作有符号数进行比较, 如果rs1 < rs2, rd置1,否则置0。

指令示例:

SLT x14,x12,x13

将x12和x13寄存器中的数当作有符号数进行比较,如果x12寄存器中的数小于x13寄存器中的数,将x14寄存器中的数置为1,否则置为0。RISC-V SLT机器码

图3 SLT机器编码格式 [2]

 

1.3. SLTU

SLTU的指令格式为SLTU rd,rs1,rs2。x[rd] = x[rs1] <𝑢 x[rs2]

如图4所示,SLTU指令的funct7为000_0000,funct3为011无符号比较rs1和rs2,如果rs1 < rs2,rd置1,否则置0。

注意,在SLTU rd,x0,rs2中如果rs2不等于0,则rd被置为1,否则,将rd置为0。对应的伪指令为SNEZ rd,rs2

指令示例:

SLTU x14,x12,x13

将x12和x13寄存器中的数当作无符号数进行比较,如果x12寄存器中的数小于x13寄存器中的数,将x14寄存器置为1,否则置为0。

RISC-V STLU机器码

图4 SLTU机器编码格式 [2]

 

1.4. AND

AND的指令格式为AND rd,rs1,rs2。x[rd] = x[rs1] & x[rs2]

如图5所示,AND指令指令的funct7为000_0000,funct3为111。该指令将rs1 & rs2的结果写入rd中,“&”表示rs1与rs2逐位相与。

指令示例:

AND x14,x12,x13

将x12和x13寄存器中的数按位与的结果写入x14寄存器。

RISC-V AND机器码

图5 AND机器编码格式 [2]

 

1.5. OR

OR的指令格式为OR rd,rs1,rs2。x[rd] = x[rs1] | x[rs2]

如图6所示,OR指令的funct7为000_0000,funct3为110。该指令将rs1 | rs2的结果写入rd中,“|”表示rs1与rs2逐位相或。

指令示例:

OR x14,x12,x13

将x12和x13寄存器中的数按位或的结果写入x14寄存器。

RISC-V OR机器码

图6 OR机器编码格式 [2]

 

1.6. XOR

XOR的指令格式为XOR rd,rs1,rs2。x[rd] = x[rs1] ^ x[rs2]

如图7所示,XOR指令的funct7为000_0000,funct3为100。该指令将rs1 按位异或 rs2的结果写入rd中。

指令示例:

XOR x14,x12,x13

将x12和x13寄存器中的数按位异或的结果写入x14寄存器。

RISC-V XOR机器码

图7 XOR机器编码格式 [2]

 

1.7. SLL

SLL(shift left logical,逻辑左移)的指令格式为SLL rd,rs1,rs2。x[rd] = x[rs1] ≪ x[rs2]

如图8所示,SLL指令的funct7为000_0000,funct3为001。该指令将rs1 左移rs2(该寄存器中的值)位,空出的位置填0,结果写入rd寄存器。rs2寄存器中低5位为有效移动位数(最多可移动2^5 – 1 = 31位),其高位被忽略。

指令示例:

SLL x14,x12,x13

将x12左移,左移的位数由x13寄存器中存储数的低5位(高位被忽略)决定,空出的位置填入0,并将结果写入x14寄存器。

SLL机器码

图8 SLL机器编码格式 [2]

 

1.8. SRL

SRL(shift right logical,逻辑右移)的指令格式为SRL rd,rs1,rs2。x[rd] = x[rs1] ≫𝑢 x[rs2]

如图9所示,SRL指令的funct7为000_0000,funct3为101。该指令将rs1 右移rs2(该寄存器中的值)位,空出的位置填0,结果写入rd寄存器。rs2寄存器中低5位为有效移动位数(最多可移动2^5 – 1 = 31位),其高位被忽略。

指令示例:

SRL x14,x12,x13

将x12右移,右移的位数由x13寄存器中存储数的低5位(高位被忽略)决定,空出的位置填入0,并将结果写入x14寄存器。

SRL机器码

图9 SRL机器编码格式 [2]

 

1.9. SRA

SRA(shift right arithmetic,算术右移)的指令格式为SRA rd,rs1,rs2。x[rd] = x[rs1] ≫𝑠 x[rs2]

如图10所示,SRA指令的funct7为010_0000,funct3为101。该指令将rs1 右移rs2(该寄存器中的值)位,空出的位置由rs1寄存器值中的最高位(rs1[31])填充,结果写入rd寄存器。rs2寄存器中低5位为有效移动位数(最多可移动2^5 – 1 = 31位),其高位被忽略。

指令示例:

SRA x14,x12,x13

将x12右移,右移的位数由x13寄存器中存储数的低5位(高位被忽略)决定,空出的位置填入rs1寄存器中存储数的最高位(符号位),并将结果写入x14寄存器。

SRA机器码

图10 SRA机器编码格式 [2]

注意:以上三条移动指令中,rs1寄存器的值只是被复制了,原值保持不变。

 

1.10. SUB

SUB的指令格式为SUB rd,rs1,rs2。x[rd] = x[rs1] − x[rs2]

如图11所示,SUB指令的funct7为010_0000,funct3为000。该指令将rs1寄存器中的值减去rs2寄存器中的值,并忽略算数溢出。

指令示例:

SUB x14,x12,x13

将x12寄存器中存储的数减去x13寄存器中存储的数,并将结果写入x14寄存器(忽略算数溢出)。

SUB机器码

图11 SUB机器编码格式 [2]

 

2.文章参考

[1] Riscv.org, 2021. [Online]. Available: https://riscv.org/wp-content/uploads/2019/12/riscv-spec-20191213.pdf. [Accessed: 22- Feb- 2021].

[2] D. Patterson and A. Waterman, The RISC-V reader. Berkeley: Strawberry Canyon LLC, 2018.

Posted in RISC-V, RISC-V 教案, 指令集, 教材与教案, 文章

发表评论

相关链接