2

I have some question related the RISC V manual It has different types of instruction encoding such as R-type,I-type. Just like the MIPS encoding.

* 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      |
 +---------------------------------------+---------+-------------+

But it also have something called immediate format: such as I-immediate, S-immediate and so on

* 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 |
 +----------------------+---------------+--+-----------+-------+--+

According to the manual, it say those immediate is produced by RISC-V instruction but how are the things related?

What is the point to have immediate format?

Billy
  • 701
  • 1
  • 8
  • 26
  • 1
    The I-U-S-B-immediate formats are not instructions format - but rather, as well explained by Peter Cordes - how the immediates are encoded accross each of the instruction format. – Pierre G. Jul 07 '18 at 12:00

1 Answers1

5

The 2nd set of diagrams is showing you how the immediate bits are concatenated and sign-extended into a 32-bit integer (so they can work as a source operand for normal 32-bit ALU instructions like addi which need both their inputs to be the same size).

For I-type instructions it's trivial, just arithmetic right-shift the instruction word by 20 bits, because there's only one immediate field, and it's contiguous at the top of the instruction word.

For S-type immediate instructions, there are two separate fields in the instruction word: [31:25] and [11:7], and this shows you that they're in that order, not [11:7, 31:25] and not with any implicit zeros between them.

B-type immediate instructions apparently put bit 7 in front of [30:25], and the low bit is an implicit zero. (So the resulting number is always even). I assume B-type is for branches.

U-type is also interesting, padding the 20-bit immediate with trailing zeros. It's used for lui to create the upper bits of 32-bit constants (with addi supplying the rest). It's not a coincidence that U-type and I-type together have 32 total immediate bits.

To access static data, lui can create the high part of an address while lw can supply the low part directly, instead of using an addi to create the full address in a register. This is typical for RISC ISAs like MIPS and PowerPC as well (see an example 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, for efficient PIC without having to load addresses from a GOT (global offset table). (A recent MIPS revision also added an add-to-PC instruction, but for a long time MIPS was quite bad at PIC).

lui can encode any 4k-aligned address, i.e. a page-start address with 4k pages.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • May I ask why the immediate bits are needed to be extended into 32 bits? Is it because the immediate is decoded into 32 bits in order to keep the same size as the content in register? – Billy Jul 08 '18 at 20:43
  • @Billy: An instruction like `add r0, r1, 1234` (or whatever the syntax is for RISC-V) is doing 32-bit addition, so both inputs need to be the same size. Thus immediates need a rule for extending to register width; otherwise each instruction itself could have its own rule for extending immediates if necessary. (A shift instruction doesn't need to care about the high bits, though.) BTW, MIPS `ori` zero-extends immediates while MIPS `addiu` sign-extends. IDK if RISC-V has any instructions that re-interpret the immediate overriding the general rule. – Peter Cordes Jul 08 '18 at 20:46
  • 1
    What's U-type used for: It's for loading the upper bits of a register. Usually paired with an I-type or S-type which provides the remaining bits. E.g., to add 0x12345678 to a register, you would `lui rt, 0x12345` (U-type) to set `rt = 0x12345000` and then `addi rd, rt, 0x678` (I-type) to finish the job. Similarly, to perform an absolute store to `0x12345678` you would follow with `sw rs, 0x678(rt)` (S-type). – Raymond Chen Jul 12 '18 at 14:04
  • @RaymondChen: thanks; that makes perfect sense. I'm more familiar with MIPS, which has 16-bit immediates; I think MIPS `lui` just uses the same I-type format as other instructions. (Allowing creating of an arbitrary 32-bit constant in 2 instructions). With smaller immediates for RISC-V's I-type instructions, it makes sense using enough coding space on `lui` to still get 32 total immediate bits in 2 instructions. – Peter Cordes Jul 13 '18 at 01:19