1.2 模块化与增量型 ISA

​和几乎所有以往的 ISA不同,RISC-V是模块化的。它的核心是一个名为RV32I的基础 ISA,运行一个完整的软件栈。RV32I是固定的,永远不会改变。模块化来源于可选的标准扩展,根据应用程序的需要,硬件可以包含或不包含这些扩展。可以生成当前硬件条件下的最佳代码。惯例是把代表扩展的字母附加到指令集名称之后作为指示。例如,RV32IMFD将乘法( RV32M),单精度浮点(RV32F)和双精度浮点(RV32D)的扩展添加到了基础指令集 RV32I)中。

2.2 RV32I 指令格式

图2.1: RV32指令图示

​用于寄存器-寄存器操作的R类型指令,用于短立即数和访存load操作的I型指令,用于访存store操作的S型指令,用于条件跳转操作的B类型指令,用于长立即数的U型指令和用于无条件跳转的J型指令。

图2.2

图2.3

2.3 RV32I 寄存器

​RV32I有31寄存器加上一个值恒为0的x0寄存器。

图2.4

2.4 RV32I 整数计算

​简单的算术指令(add, sub)、逻辑指令(and, or, xor),以及图2.1中的移位指令(sll, srl, sra)和其他ISA差不多。他们从寄存器读取两个32位的值,并将32位结果写入目标寄存器。

​程序可以根据比较结果生成布尔值。为应对这种使用场景下,RV32I提供一个当小于时置位的指令(slt)。

​图2.1剩下的两条整数计算指令主要用于构造大的常量数值和链接。加载立即数到高位(lui)将20位常量加载到寄存器的高20位。接着便可以使用标准的立即指令来创建32位常量。

有什么不同之处?

  • RISC-V中没有字节或半字宽度的整数计算操作。操作始终是以完整的寄存器宽度。
  • RV32I也不包含乘法和除法,它们包含在可选的RV32M扩展中。

2.5 RV32I 的Load 和 Store

​除了提供32位字(lw,sw)的加载和存储外,图2.1中说明,RV32I 支持加载有符号和无符号字节和半字(lb,lbu,lh,lhu)和存储字节和半字(sb,sh)。有符号字节和半字符号扩展为32位再写入目的寄存器。即使是自然数据类型更窄,低位宽数据也是被扩展后再处理,这使得后续的整数计算指令能正确处理所有的32位。在文本和无符号整数中常用的无符号字节和半字,在写入目标寄存器之前都被无符号扩展到32位。

RV32I 条件分支

​相等(beq),不相等 (bne),大于等于(bge),或小于(blt)。最后两种比较有符号比较,RV32I也提供相应的无符号版本比较的:bgeu和bltu。分支指令的寻址方式是12位的立即数乘以2,符号扩展它,然后将得到值加到PC上作为分支的跳转地址。{% label danger @这句话没理解 %}

{% note info %}

补充说明:获取PC

当前的PC可以通过将auipc的U立即数字段设置为0来获得。

{% endnote %}

2.7 RV32I无条件跳转

​图2.1中的跳转并链接指令(jal)具有双重功能。若将下一条指令PC + 4的地址保存到目标寄存器中,通常是返回地址寄存器ra(见图2.4),便可以用它来实现过程调用。如果使用零寄存器(x0)替换ra作为目标寄存器,则可以实现无条件跳转,因为x0不能更改。像分支一样,jal将其20位分支地址乘以2,进行符号扩展后再添加到PC上,便得到了跳转地址。

{% note info %}

jal x1, X means jump to X, and save the return address which is normally PC+4 to the x1.

jal x0 0(x1) use indirect address (x1) plus a constant of 12bits (0 in your example). set x0 as return address register because you «don’t care».

{% endnote %}

2.8 RV32I 杂项

​图2.1中的控制状态寄存器指令 (csrrc、csrrs、csrrw、csrrci、csrrsi、csrrwi),使我们可以轻松地访问一些程序性能计数器。对于这些64位计数器, 我们一次可以读取32位。这些计数器包括了系统时间, 时钟周期以及执行的指令数目。

​在RISC-V指令集中,ecall指令用于向运行时环境发出请求,例如系统调用。调试器使用ebreak指令将控制转移到调试环境。

fence指令对外部可见的访存请求,如设备I / O和内存访问等进行串行化。外部可见指对处理器的其他核心、线程,外部设备或协处理器可见。fence.i指令同步指令和数据流。在执行fence.i指令之前,对于同一个硬件线程,RISC-V不保证用存储指令写到内存指令区的数据可以被取指令取到。

2.10 结束语

  • 32位字节可寻址的地址空间
  • 所有指令均为32位长
  • 31个寄存器,全部32位宽,寄存器0硬连线为零
  • 所有操作都在寄存器之间(没有寄存器到内存的操作)
  • 加载/存储字加上有符号和无符号加载/存储字节和半字
  • 所有算术,逻辑和移位指令都有立即数版本的指令
  • 立即数总是符号扩展
  • 仅提供一种数据寻址模式(寄存器+立即数)和PC相对分支
  • 无乘法或除法指令
  • 一个指令,用于将大立即数加载到寄存器的高位,这样加载32位常量到寄存器只需要两条指令

References

RISC-V Green Card

RISC-V-Reader-Chinese-v2p1.pdf