riscv指令
https://riscv.org/wp-content/uploads/2017/05/riscv-spec-v2.2.pdf
1.异常中断与陷阱
我们使用术语“异常(exception)”来指代在当前RISC-V线程中,与指令运行时相关联的非正常情况。我们使用术语“陷阱(trap)”来指代因RISC-V线程中发生的异常情况而引发的同步控制转移至陷阱处理程序。陷阱处理程序通常在更加特权的环境中执行。
我们使用术语“中断(interrupt)”来指代一个与当前RISC-V线程异步发生的外部事件。当必须处理的中断发生时,某条指令会被选中接收到中断异常,随后引发陷阱。
接下来的章节描述了在执行过程中会引发异常的条件。这些条件如何转变为陷阱取决于执行环境,尽管大多数情况下,当发生异常时,系统通常会引发精确陷阱(precise trap)(除了标准浮点扩展中的浮点异常,这种异常不会引发陷阱)。
就像实验里看到的那样,异常是强制处理的,而中断是可控的,他们都会陷入(trap)处理程序
2.base integer subset
3.instruction format
总体分为四种
四种核心指令格式:
- R-type(寄存器类型):用于纯寄存器到寄存器的操作。
- I-type(立即数类型):用于包含立即数的指令,立即数与寄存器进行操作。
- S-type(存储类型):用于存储指令,将数据存储到内存中。
- U-type(上半部分立即数类型):用于加载大数值,特别是32位宽的立即数。
对齐要求:
- 指令的长度为固定的32位,并且必须在内存中按照4字节边界对齐。如果在分支或跳转时,目标地址未对齐,会生成地址未对齐异常。
- 如果有16位或16位倍数的扩展指令加入,指令的对齐要求可以放宽到2字节边界。
立即数扩展:
- 各指令类型中的立即数通常使用符号扩展(sign-extended),尤其是最高位(bit 31)保留为符号位,以简化硬件的符号扩展操作。
统一寄存器位置:
- 在所有指令格式中,寄存器的位置(如
rs1
、rs2
和rd
)被设计为在同一个位置,以简化指令解码。
3.1 extented instruction format
There are a further two variants of the instruction formats (B/J) based on the handling of immediates
进一步的变体,为B和J型指令,S型指令的立即数最低位是空闲的,因此可以给B型指令的最高位。
因为S指令要左移2位,而B只需左移一位,因此需要上述调整
同理,J型指令和U型指令也是这个意思
U型格式和J型格式的唯一区别在于,20位的立即数在U型格式中左移12位以形成U型立即数,而在J型格式中左移1位以形成J型立即数。U型和J型格式中立即数字段的位置选择是为了最大限度地与其他格式以及彼此之间重叠。
4.Basic Instructions
这一部分讲解基本指令,不涉及扩展,RISCV-32
4.1 Integer Computational Instructions
Integer computational instructions are either encoded as register-immediate operations using the I-type format or as register-register operations using the R-type format. The destination is register rd for both register-immediate and register-register instructions. No integer computational instructions cause arithmetic exceptions.
多为R型,I型,U型指令
ADDI adds the sign-extended 12-bit immediate to register rs1. Arithmetic overflow is ignored and the result is simply the low XLEN bits of the result. ADDI rd, rs1, 0 is used to implement the MV rd, rs1 assembler pseudo-instruction.
**SLTI (set less than immediate) **places the value 1 in register rd if register rs1 is less than the signextended immediate when both are treated as signed numbers, else 0 is written to rd. SLTIU is similar but compares the values as unsigned numbers (i.e., the immediate is first sign-extended to XLEN bits then treated as an unsigned number). Note, SLTIU rd, rs1, 1 sets rd to 1 if rs1 equals zero, otherwise sets rd to 0 (assembler pseudo-op SEQZ rd, rs).
ANDI, ORI, XORI are logical operations that perform bitwise AND, OR, and XOR on register rs1 and the sign-extended 12-bit immediate and place the result in rd. Note, XORI rd, rs1, -1 performs a bitwise logical inversion of register rs1 (assembler pseudo-instruction NOT rd, rs).
Shifts by a constant are encoded as a specialization of the I-type format. The operand to be shifted is in rs1, and the shift amount is encoded in the lower 5 bits of the I-immediate field. The right shift type is encoded in a high bit of the I-immediate. SLLI is a logical left shift (zeros are shifted into the lower bits); SRLI is a logical right shift (zeros are shifted into the upper bits); and SRAI is an arithmetic right shift (the original sign bit is copied into the vacated upper bits).
**LUI (load upper immediate) **is used to build 32-bit constants and uses the U-type format. LUI places the U-immediate value in the top 20 bits of the destination register rd, filling in the lowest 12 bits with zeros.
AUIPC (add upper immediate to pc) is used to build pc-relative addresses and uses the U-type format. AUIPC forms a 32-bit offset from the 20-bit U-immediate, filling in the lowest 12 bits with zeros, adds this offset to the pc, then places the result in register rd.
ADD and SUB perform addition and subtraction respectively. Overflows are ignored and the low XLEN bits of results are written to the destination. SLT and SLTU perform signed and unsigned compares respectively, writing 1 to rd if rs1 < rs2, 0 otherwise. Note, SLTU rd, x0, rs2 sets rd to 1 if rs2 is not equal to zero, otherwise sets rd to zero (assembler pseudo-op SNEZ rd, rs). AND, OR, and XOR perform bitwise logical operations. SLL, SRL, and SRA perform logical left, logical right, and arithmetic right shifts on the value in register rs1 by the shift amount held in the lower 5 bits of register rs2
需要注意的是,移位指令只有寄存器中的低五位是有效的
The NOP instruction does not change any user-visible state, except for advancing the pc. NOP is encoded as ADDI x0, x0, 0.
可以用来particular对齐,或者inline代码嵌入
4.2 Control Transfer Instructions
主要提供了两种,一种条件跳转,一种无条件跳转
4.2.1 Unconditional Jumps
主要是JAL和JALR指令,分别以J型和I型的格式编码,因此跳转的地址范围有所不同,并且目标地址的计算方式也不同。
JAL:The offset is sign-extended and added to the pc to form the jump target address. Jumps can therefore target a ±1 MiB range. JAL stores the address of the instruction following the jump (pc+4) into register rd
Plain unconditional jumps (assembler pseudo-op J) are encoded as a JAL with rd=x0.
JALR:The indirect jump instruction JALR (jump and link register) uses the I-type encoding. The target address is obtained by adding the 12-bit signed I-immediate to the register rs1, then setting the least-significant bit of the result to zero. The address of the instruction following the jump (pc+4) is written to register rd. Register x0 can be used as the destination if the result is not required.
The standard software calling convention uses x1 as the return address register and x5 as an alternate link register.
x1 是主要的返回地址寄存器,处理一般的函数调用。
x5 是备用寄存器,在某些特殊情况下用作保存临时返回地址,避免与 x1 冲突。
细节:关于返回地址调用栈
4.2.2Conditional Jumps
All branch instructions use the B-type instruction format. The 12-bit B-immediate encodes signed offsets in multiples of 2, and is added to the current pc to give the target address. The conditional branch range is ±4 KiB.
Branch instructions compare two registers. BEQ and BNE take the branch if registers rs1 and rs2 are equal or unequal respectively. BLT and BLTU take the branch if rs1 is less than rs2, using signed and unsigned comparison respectively. BGE and BGEU take the branch if rs1 is greater than or equal to rs2, using signed and unsigned comparison respectively. Note, BGT, BGTU, BLE, and BLEU can be synthesized by reversing the operands to BLT, BLTU, BGE, and BGEU, respectively.
软件应该根据架构的分支预测特性来优化代码。