如何在 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。这​​些位是分配到指令中的两个位置,以便 rdrs1 字段可以在不同指令类型中位于相同的位位置。 (从人类的角度来看,这显然有点令人困惑,但它使实现硬件更容易。)立即数的最后三位(索引为 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位。在本例中,即 10011。那只有 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,我们会发现这意味着寄存器目标是 x13a3rs1,寄存器源1,在位[9:7]中,也就是000。这映射到寄存器 x8s0.

所以,综上所述,这条指令的实现就是把rs1中存储的值,加到imm,也就是zero-extended,加载一个doubleword(64bits ) 从内存中的那个位置到 rd。对于指令0x5074,224 的立即数被添加到寄存器x8 的内容中,从内存中的结果地址中检索一个双字,并将值存储在寄存器x13 中。