如何在 RISC-V 中为 C.LD 压缩指令获取立即数/偏移位?
How to take immediate / offset bits for C.LD compressed instruction in RISC-V?
如 RISC-V 压缩指令的参考图片 [1] 所示,C.LD 指令的立即数位显示在 2 个不同的位置 - 位 [12:10] 和 [4:2]。还显示在imm字段中标记了offset[5:3]和offset[7:6]——[12:10]和[7:6].
Questions/Doubts:
如何实施?
偏移量和立即数是同一个意思吗?
问题的更多细节 -
似乎令人困惑的事实是 - C.LD 中的第 3 位和第 4 位属于目标寄存器 (rd'),而第 5 位属于立即字段。那么,我们是否应该单独获取这些值并将其设置为第二个直接字段?如果是这样,那么这里提到的偏移量有什么用?
参考图片 -
[1]: https://i.stack.imgur.com/9oen3.png
(RISC-V ISA版本参考- RISC-V Unprivileged ISA V20191213)
是的,你是对的,在这种情况下,offset 和 immediate 本质上是一样的。在 RISC-V ISA 中,您会看到内存操作(加载和存储)的立即数由于它们的使用方式而被称为“偏移量”——它们被添加到寄存器 [=11 中保存的值中=] 来导出从中加载/存储到的最终内存地址,因此它们可以被认为是 rs1
.
中地址的“偏移量”
在 C.LD
(压缩加载双字)指令的具体情况下,您可以将立即数视为八位长的无符号数,位索引为 0 到 7。这些位是分配到指令中的两个位置,以便 rd
和 rs1
字段可以在不同指令类型中位于相同的位位置。 (从人类的角度来看,这显然有点令人困惑,但它使实现硬件更容易。)立即数的最后三位(索引为 0、1 和 2 的位)未编码,因为它们是假定为 0 -- 双字的字节地址假定为双字(64 位/8 字节)对齐,这意味着它必须能被 8 整除。
为了更清楚一点,因为您询问了如何实施该指令,例如,让我分解一下指令 0x5074
:
| 15| 14| 13| 12| 11| 10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 0 |
立即数来自位[6:5|12:10]。 [12:10]位代表立即数的第5、4、3位,[6:5]位代表立即数的第7、6位。在本例中,即 100
和 11
。那只有 5 位,所以整个立即数变为 11100000
——我们为立即数的第 2、1 和 0 位插入 0。立即数是zero-extended,所以十进制变成0x0000_00e0
,或者224
。 (注意 zero-extension——许多 RISC-V 立即数,包括标准加载字指令,都是 sign-extended)。
我知道你的问题是关于直接的,但如果它有用,那么对于指令的其余部分:
[1:0] 位是操作码,00
。这是压缩指令操作码之一(non-compressed 指令有 7 位操作码,[1:0] 位是 11
)。 010
位 [15:13] 是 C.LD 指令的操作码。
rd
,寄存器目标,在位 [4:2] 中,在本例中为 101
。如果我们查看压缩指令寄存器映射 table,我们会发现这意味着寄存器目标是 x13
或 a3
。 rs1
,寄存器源1,在位[9:7]中,也就是000
。这映射到寄存器 x8
或 s0
.
所以,综上所述,这条指令的实现就是把rs1
中存储的值,加到imm
,也就是zero-extended,加载一个doubleword(64bits ) 从内存中的那个位置到 rd
。对于指令0x5074
,224 的立即数被添加到寄存器x8
的内容中,从内存中的结果地址中检索一个双字,并将值存储在寄存器x13
中。
如 RISC-V 压缩指令的参考图片 [1] 所示,C.LD 指令的立即数位显示在 2 个不同的位置 - 位 [12:10] 和 [4:2]。还显示在imm字段中标记了offset[5:3]和offset[7:6]——[12:10]和[7:6].
Questions/Doubts: 如何实施? 偏移量和立即数是同一个意思吗?
问题的更多细节 - 似乎令人困惑的事实是 - C.LD 中的第 3 位和第 4 位属于目标寄存器 (rd'),而第 5 位属于立即字段。那么,我们是否应该单独获取这些值并将其设置为第二个直接字段?如果是这样,那么这里提到的偏移量有什么用?
参考图片 - [1]: https://i.stack.imgur.com/9oen3.png
(RISC-V ISA版本参考- RISC-V Unprivileged ISA V20191213)
是的,你是对的,在这种情况下,offset 和 immediate 本质上是一样的。在 RISC-V ISA 中,您会看到内存操作(加载和存储)的立即数由于它们的使用方式而被称为“偏移量”——它们被添加到寄存器 [=11 中保存的值中=] 来导出从中加载/存储到的最终内存地址,因此它们可以被认为是 rs1
.
在 C.LD
(压缩加载双字)指令的具体情况下,您可以将立即数视为八位长的无符号数,位索引为 0 到 7。这些位是分配到指令中的两个位置,以便 rd
和 rs1
字段可以在不同指令类型中位于相同的位位置。 (从人类的角度来看,这显然有点令人困惑,但它使实现硬件更容易。)立即数的最后三位(索引为 0、1 和 2 的位)未编码,因为它们是假定为 0 -- 双字的字节地址假定为双字(64 位/8 字节)对齐,这意味着它必须能被 8 整除。
为了更清楚一点,因为您询问了如何实施该指令,例如,让我分解一下指令 0x5074
:
| 15| 14| 13| 12| 11| 10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 0 |
立即数来自位[6:5|12:10]。 [12:10]位代表立即数的第5、4、3位,[6:5]位代表立即数的第7、6位。在本例中,即 100
和 11
。那只有 5 位,所以整个立即数变为 11100000
——我们为立即数的第 2、1 和 0 位插入 0。立即数是zero-extended,所以十进制变成0x0000_00e0
,或者224
。 (注意 zero-extension——许多 RISC-V 立即数,包括标准加载字指令,都是 sign-extended)。
我知道你的问题是关于直接的,但如果它有用,那么对于指令的其余部分:
[1:0] 位是操作码,00
。这是压缩指令操作码之一(non-compressed 指令有 7 位操作码,[1:0] 位是 11
)。 010
位 [15:13] 是 C.LD 指令的操作码。
rd
,寄存器目标,在位 [4:2] 中,在本例中为 101
。如果我们查看压缩指令寄存器映射 table,我们会发现这意味着寄存器目标是 x13
或 a3
。 rs1
,寄存器源1,在位[9:7]中,也就是000
。这映射到寄存器 x8
或 s0
.
所以,综上所述,这条指令的实现就是把rs1
中存储的值,加到imm
,也就是zero-extended,加载一个doubleword(64bits ) 从内存中的那个位置到 rd
。对于指令0x5074
,224 的立即数被添加到寄存器x8
的内容中,从内存中的结果地址中检索一个双字,并将值存储在寄存器x13
中。