搜索文章

输入标题或内容中的关键词。

← 回到技术手记
硬件

RISC-V 学习笔记:RV32I 指令格式与常用指令

gemhack··6 分钟阅读

RV32I 指令格式

RV32I指令分为四个大类,分别为R(register)、I(immediate)、S(store)、U(upper immediate)类型,除此之外还有两个种类的变形,为B-TYPE和J-TYPE。每个指令都是32位,也就是IALIGN=32。每种指令的格式如下图所示:

RISC-V 指令格式

整数运算指令

  • immediate-register type:
  • ADDI(add immediate)将立即数加到rs1
  • SLTI(set less than immediate)如果rs1值小于立即数,则将1写入rd,否则将0写入rd.比较的两个数都视为带符号的数字。
  • SLTIU(set less than immediate unsigned)同上,但是两者视为无符号数字。
  • ANDI 与立即数与操作
  • ORI 或操作
  • XORI 异或操作 RISC-V 指令格式
  • SLLI(shift logical left immediate)逻辑左移,空位补零
  • SRLI(shift logical right immediate)逻辑右移,空位补零
  • SRAI(shift arithmetic right immediate) 算术右移,空位补符号位 RISC-V 指令格式
  • LUI(load upper immediate)将立即数加载到rd中,低12位使用0填充
  • AUIPC(add upper immediate to pc)将立即数扩充为32位大数,低12位使用0填充,将pc中的值加上该值之后写入rd. RISC-V 指令格式
  • register-register type:
    • ADD(add)加
    • SUB(sub)减
    • SLT(set less than)
    • SLTU(set less than unsigned)
    • AND
    • OR
    • XOR
    • SLL(shift logical left)即rd = rs1 << rs2.其中rs2只取低五位。下同。
    • SRL(shift logical right)
    • SRA(shift arithmetic right) RISC-V 指令格式
  • NOP指令 nop指令是指什么都不做,让cpu“发呆”。在RISC-V底层翻译为addi x0,x0,0,这个指令的好处在于:
  • 有一些处理器在处理跳转的时候如果内存对齐速度会变快,如果此时程序没有对齐可以使用nop来手动对齐。
  • 可以实现延时效果。
  • 在早期的时候占位,如果后续出现bug需要跳转到时候可以直接替换命令,对内存布局无影响。 选择 ADDI 用于 NOP 编码,是因为 ADDI 在多种系统中执行时最可能耗费最少的资源。

控制转移指令

  • unconditional jumps
    • JAL(jump and link)使用J-TYPE指令实现,操作pc寄存器的值,跳转到pc加上一个21位的带符号的偏移量,imm[20:1]为偏移量,没有0 bit位是因为offset必须是2字节的倍数。并将返回地址(当前 pc+4)写入 rd。
    • JALR(jump and link register)使用I-type指令实现,将rs1中的地址加上一个imme[11:0]的带符号的偏移量之后跳转。目标地址最低位清零,并将当前 pc+4 写入 rd 作为返回地址。 使用LUI+JALR可以实现32位地址的跳转,因为LUI可以将rs1的高20位设置为想要的地址,低12为设0,然后使用JALR将低12位设置为想要的地址之后跳转,就可以跳转到任意想要的32位地址。

返回地址预测栈(RAS)利用寄存器编号识别调用和返回。JAL 在 rd 为 x1 或 x5 时提示入栈;JALR 的推送、弹出行为取决于 rd 与 rs1 的组合,见下表。

表 2。返回地址栈预测提示编码在 JALR 指令的寄存器作数中。

rd is x1/x5 rs1 is x1/x5 rd = rs1 RAS action
No No — None
No Yes — Pop
Yes No — Push
Yes Yes No Pop, then push
Yes Yes Yes Push

使用 x1 或 x5 是返回地址预测提示,不限制指令使用其他寄存器。

  • conditional branches 所有分支指令都使用 B 型指令格式。B 型指令使用 12 个编码位表示以 2 字节为单位的偏移量,重建后是含最低零位的 13 位有符号偏移。偏移量通过符号扩展,添加到分支指令的地址上,以获得目标地址。条件分支范围为±4 KiB。
    • BEQ(be equal)
    • BNE(branch if not equal)
    • BGE(branch if greater than or equal)
    • BGEU(无符号大于或等于时跳转)
    • BLT(be less than)
    • BLTU(be less than unsigned) RISC-V 指令格式 如果条件成立则跳转到pc加对应的偏移量。

加载与存储指令

RV32I is a load-store architecture, where only load and store instructions access memory and arithmetic instructions only operate on CPU registers

RISC-V 指令格式

LOAD 将基地址加上偏移量的地址中的值读取到rd中。 STORE 将rs2中的值存储到rs1加上偏移量的地址中。

  • LW(load word)
  • LH(load half word) 加载低16位,高位拓展为符号位,也就是将17-32写成和第16位相同
  • LHU(load half word unsigned)
  • LB(load byte)
  • LBU(load byte unsigned)
  • SW(store word)
  • SH(store half word),存储低16位,高16位被丢弃。
  • SB(store byte)

参考资料

评论发表评论

评论

发表评论

邮箱不会公开。标有 * 的项目为必填项。