RISC V手册混淆:指令格式VS立即数格式
RISC V manual confusion: instruction format VS immediate format
我有一些关于 RISC V 手册的问题
它有R型、I型等不同类型的指令编码。
就像MIPS编码一样。
* R-type
31 25 24 20 19 15 14 12 11 7 6 0
+------------+---------+---------+------+---------+-------------+
| funct7 | rs2 | rs1 |funct3| rd | opcode |
+------------+---------+---------+------+---------+-------------+
* I-type
31 20 19 15 14 12 11 7 6 0
+----------------------+---------+------+---------+-------------+
| imm | rs1 |funct3| rd | opcode |
+----------------------+---------+------+---------+-------------+
* S-type
31 25 24 20 19 15 14 12 11 7 6 0
+------------+---------+---------+------+---------+-------------+
| imm | rs2 | rs1 |funct3| imm | opcode |
+------------+---------+---------+------+---------+-------------+
* U-type
31 11 7 6 0
+---------------------------------------+---------+-------------+
| imm | rd | opcode |
+---------------------------------------+---------+-------------+
但它也有一种叫做即时格式的东西:
比如I-immediate, S-immediate等等
* I-immediate
31 10 5 4 1 0
+-----------------------------------------+-----------+-------+--+
| <-- 31 | 30:25 | 24:21 |20|
+-----------------------------------------+-----------+-------+--+
* S-immediate
31 10 5 4 1 0
+-----------------------------------------+-----------+-------+--+
| <-- 31 | 30:25 | 11:8 |7 |
+-----------------------------------------+-----------+-------+--+
* B-immediate
31 12 11 10 5 4 1 0
+--------------------------------------+--+-----------+-------+--+
| <-- 31 |7 | 30:25 | 11:8 |z |
+--------------------------------------+--+-----------+-------+--+
* U-immediate
31 30 20 19 12 11 0
+--+-------------------+---------------+-------------------------+
|31| 30:20 | 19:12 | <-- z |
+--+-------------------+---------------+-------------------------+
* J-immediate
31 20 19 12 11 10 5 4 1 0
+----------------------+---------------+--+-----------+-------+--+
| <-- 31 | 19:12 |20| 30:25 | 24:21 |z |
+----------------------+---------------+--+-----------+-------+--+
手册上说那些立即数是由RISC-V指令产生的,但是它们之间有什么关系?
立即格式有什么意义?
第二组图表向您展示了如何将立即数位连接起来并将其符号扩展为 32 位整数(因此它们可以用作普通 32 位 ALU 指令的源操作数,例如 addi
这需要它们的输入大小相同)。
对于 I 型指令,这很简单,只需将指令字算术右移 20 位,因为只有一个立即字段,并且它在指令字的顶部是连续的。
对于 S 型立即数指令,指令字中有两个单独的字段:[31:25]
和 [11:7]
,这表明它们在 顺序,不是 [11:7, 31:25]
并且它们之间没有任何隐式零。
B 型立即数指令显然将第 7 位放在 [30:25]
前面,低位是隐式零。 (所以结果数总是偶数)。我假设 B 型用于分支。
U 型也很有趣,用尾随零填充 20 位立即数。它用于 lui
创建 32 位常量的高位(addi
提供其余部分)。 U型和I型加在一起有32个立即数位并不是巧合。
要访问静态数据,lui
可以创建地址的高位部分,而 lw
可以直接提供低位部分,而不是使用 addi
来创建完整地址在寄存器中。这对于像 MIPS 和 PowerPC 这样的 RISC ISA 也是典型的(参见示例 on the Godbolt compiler explorer). But unlike most other RISC ISAs, RISC-V has auipc
which adds the U-type immediate to the program counter,为了高效的 PIC 而不必从 GOT 加载地址(全局偏移量 table)。(最近的 MIPS 修订版还添加了一条添加到 PC 的指令,但很长一段时间 MIPS 在 PIC 方面表现不佳。
lui
可以编码任何 4k 对齐的地址,即具有 4k 页的页起始地址。
我有一些关于 RISC V 手册的问题 它有R型、I型等不同类型的指令编码。 就像MIPS编码一样。
* R-type
31 25 24 20 19 15 14 12 11 7 6 0
+------------+---------+---------+------+---------+-------------+
| funct7 | rs2 | rs1 |funct3| rd | opcode |
+------------+---------+---------+------+---------+-------------+
* I-type
31 20 19 15 14 12 11 7 6 0
+----------------------+---------+------+---------+-------------+
| imm | rs1 |funct3| rd | opcode |
+----------------------+---------+------+---------+-------------+
* S-type
31 25 24 20 19 15 14 12 11 7 6 0
+------------+---------+---------+------+---------+-------------+
| imm | rs2 | rs1 |funct3| imm | opcode |
+------------+---------+---------+------+---------+-------------+
* U-type
31 11 7 6 0
+---------------------------------------+---------+-------------+
| imm | rd | opcode |
+---------------------------------------+---------+-------------+
但它也有一种叫做即时格式的东西: 比如I-immediate, S-immediate等等
* I-immediate
31 10 5 4 1 0
+-----------------------------------------+-----------+-------+--+
| <-- 31 | 30:25 | 24:21 |20|
+-----------------------------------------+-----------+-------+--+
* S-immediate
31 10 5 4 1 0
+-----------------------------------------+-----------+-------+--+
| <-- 31 | 30:25 | 11:8 |7 |
+-----------------------------------------+-----------+-------+--+
* B-immediate
31 12 11 10 5 4 1 0
+--------------------------------------+--+-----------+-------+--+
| <-- 31 |7 | 30:25 | 11:8 |z |
+--------------------------------------+--+-----------+-------+--+
* U-immediate
31 30 20 19 12 11 0
+--+-------------------+---------------+-------------------------+
|31| 30:20 | 19:12 | <-- z |
+--+-------------------+---------------+-------------------------+
* J-immediate
31 20 19 12 11 10 5 4 1 0
+----------------------+---------------+--+-----------+-------+--+
| <-- 31 | 19:12 |20| 30:25 | 24:21 |z |
+----------------------+---------------+--+-----------+-------+--+
手册上说那些立即数是由RISC-V指令产生的,但是它们之间有什么关系?
立即格式有什么意义?
第二组图表向您展示了如何将立即数位连接起来并将其符号扩展为 32 位整数(因此它们可以用作普通 32 位 ALU 指令的源操作数,例如 addi
这需要它们的输入大小相同)。
对于 I 型指令,这很简单,只需将指令字算术右移 20 位,因为只有一个立即字段,并且它在指令字的顶部是连续的。
对于 S 型立即数指令,指令字中有两个单独的字段:[31:25]
和 [11:7]
,这表明它们在 顺序,不是 [11:7, 31:25]
并且它们之间没有任何隐式零。
B 型立即数指令显然将第 7 位放在 [30:25]
前面,低位是隐式零。 (所以结果数总是偶数)。我假设 B 型用于分支。
U 型也很有趣,用尾随零填充 20 位立即数。它用于 lui
创建 32 位常量的高位(addi
提供其余部分)。 U型和I型加在一起有32个立即数位并不是巧合。
要访问静态数据,lui
可以创建地址的高位部分,而 lw
可以直接提供低位部分,而不是使用 addi
来创建完整地址在寄存器中。这对于像 MIPS 和 PowerPC 这样的 RISC ISA 也是典型的(参见示例 on the Godbolt compiler explorer). But unlike most other RISC ISAs, RISC-V has auipc
which adds the U-type immediate to the program counter,为了高效的 PIC 而不必从 GOT 加载地址(全局偏移量 table)。(最近的 MIPS 修订版还添加了一条添加到 PC 的指令,但很长一段时间 MIPS 在 PIC 方面表现不佳。
lui
可以编码任何 4k 对齐的地址,即具有 4k 页的页起始地址。