1

In RISC-V assembly I wrote:

addi s0,x0,0x20000

Is this legal such that the assembler will prove the command and make it work right or I'm forced to change it to:

lui s0,0x20

Can someone kindly explain what lui does?

Mike
  • 2,146
  • 1
  • 14
  • 29
daniel
  • 21
  • 2
  • 6
  • 1
    I strongly suggest that for questions like this you write little snippets of code and try them out. Even if you don't have a RISC V chip lying around, there should be emulators. The *reason* I suggest this is that you generally learn the answer to your question, plus about half a dozen other questions -- and their answers, eventually -- that you didn't know to ask. – TimWescott Jan 28 '21 at 00:13
  • what part of the risc-v documentation do you not understand? – old_timer Jan 28 '21 at 23:36

1 Answers1

1

No, this won't work because ADDI can only add 12-bit immediate values which are sign-extended to 32 bits. RISC-V is not like ARM where almost any immediate value can be shifted before it's used. Therefore with ADDI you can add 0x000-0x7FF or subtract 0x001-0x800. The limitation to 12-bit immediate values is because of the encoding of ADDI:

RISC-V ADDI encoding However, ADDI with x0 as the source register is valid for loading smaller immediate values, so you could do ADDI s0, x0, #0x123, for example. NOP is also implemented this way, and is just a pseudo-instruction for ADDI x0, x0, #0x0. Other forms of NOP (for example adding 0 to a register other than x0) are considered non-canonical and are not recommended because they may be redefined to be a different, meaningful instruction in the future.

As for LUI, it loads a 20-bit immediate value into the upper 20 bits of a (32-bit) register and fills in other 12 bits with 0's. Notice how you can use LUI to set the upper 20 bits of a register and then ADDI set the lower 12 bits, thus loading a 32-bit constant into the register with just two instructions.

Zane Kaminski
  • 920
  • 6
  • 13