0
votes

As shown in the reference pic [1] for RISC-V compressed instruction, immediate bit for C.LD instruction is shown in 2 different places - bit [12:10] and [4:2]. It is also shown that offset[5:3] and offset [7:6] is marked in imm field - [12:10] and [7:6].

Questions/Doubts: How to implement it? Do offset and immediate values mean the same?

More details to the question - The fact which seems to be confusing is - bits 3 and 4 in C.LD belongs to the destination register (rd') and bit 5 belongs to the immediate field. So, should we take those values individually and set it as the second immediate field? If so, then what is the use of offset mentioned herewith?

Reference pic - [1]: https://i.stack.imgur.com/9oen3.png

(RISC-V ISA version for reference- RISC-V Unprivileged ISA V20191213)

1

1 Answers

0
votes

Yes, you're right, in this case offset and immediate are essentially the same thing. In the RISC-V ISA, you'll see immediates for memory operations (loads and stores) referred to as "offsets" because of the way they are used -- they're added to the value held in register rs1 to derive the final memory address being loaded from / stored to, so they can be thought of as the "offset" from the address in rs1.

In the case of the C.LD (compressed load doubleword) instruction specifically, you can think of the immediate as being an unsigned number that is eight bits long, with bits indexed 0 to 7. The bits are distributed into two locations in the instruction so that the rd and rs1 field can be in the same bit positions across instruction types. (This is obviously a bit confusing to read as a human, but it makes it easier to implement the hardware.) The last three bits of the immediate (the bits indexed 0, 1, and 2) are not encoded, because they're assumed to be 0 -- the byte address of a doubleword is assumed to be doubleword (64-bit / 8-byte) aligned, meaning it must be divisible by 8.

Description of the C.LD function from pg. 103 of the RISC-V ISA spec, "C.LD is an RV64C/RV128C-only instruction that loads a 64-bit value from memory into register rd'. It computes an effective address by adding the zero-extended offset, scaled by 8, to the base address in register rs1'. It expands to ld, rd', offset(rs1')."

For a bit more clarity since you asked about how to implement the instruction, as an example, let me break down the instruction 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 |

The immediate comes from bits [6:5|12:10]. Bits [12:10] represent bits 5, 4, and 3 of the immediate, and bits [6:5] represent bits 7 and 6 of the immediate. In this case, that's 100 and 11. That's only 5 bits, so the whole immediate becomes 11100000 -- we plug in 0's for bits 2, 1, and 0 of the immediate. The immediate is zero-extended, so it becomes 0x0000_00e0, or 224 in decimal. (Note the zero-extension -- many RISC-V immediates, including for the standard load word instruction, are sign-extended).

I know your question was specifically about the immediate, but if it's useful, as for the rest of the instruction:

Bits [1:0] here are the opcode, 00. This is one of the compressed instruction opcodes (non-compressed instructions have 7-bit opcodes, and bits [1:0] are 11). Bits [15:13], which are 010, are the opcode for a C.LD instruction.

Table 16.2: Registers specified by the three-bit rs1 ′, rs2 ′, and and CB formats. from page 100 of the RISC-V ISA spec

rd, the register destination, is in bits [4:2], which in this case are 101. If we look at the compressed instruction register mapping table, we see that means that the register destination is x13 or a3. rs1, register source 1, is in bits [9:7], which are 000. This maps to register x8 or s0.

So, in summary, the implementation of this instruction means taking the value stored in rs1, adding it to imm, which is zero-extended, and loading a doubleword (64bits) from that location in memory into rd. For the instruction 0x5074, the immediate of 224 is added to the contents of register x8, a doubleword is retrieved from the resulting address in memory, and the value is stored in register x13.