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?
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?
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:
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.