问题
LUI (load upper immediate) is used to build 32-bit constants and uses the U-type format. LUI places the U-immediate value in the top 20 bits of the destination register rd, filling in the lowest 12 bits with zeros.
I found this in manual, but if I want to move 0xffffffff to a register, all the code I need is:
LUI x2, 0xfffff000
ADDI x2, x2, 0xfff
But a problem occurred, ADDI will extend sign to make a immediate data to a signed number, so 0xfff
will be extend to 0xffffffff
.
It make x2
to 0xffffefff
but not 0xffffffff
and what is an good implementation to move a 32bits immediate to register?
回答1:
The RISC-V assembler supports the pseudo-instruction li x2, 0xFFFFFFFF
.
Let N
is a signed, 2's complement 32 bit integer.
Common case implementation of li x2,N
is:
# sign extend low 12 bits
M=(N << 20) >> 20
# Upper 20 bits
K=((N-M) >> 12) <<12
# Load upper 20 bits
LUI x2,K
# Add lower bits
ADDI x2,x2,M
Of course, to load short immediate li
can use
addi x2,x0,imm
So, li x2, 0xFFFFFFFF
is addi x2,x0,-1
.
回答2:
I was going to say "use ORI
instead of ADDI
" but then I read the Instruction Set Manual and it turns out that that doesn't work either, because all of the lower-12 Immediate operands get sign-extended, even for logical operations.
AFAICT you have to bias the value you put into the upper 20 bits in a way that anticipates the effect of the instruction you use to set the lower 12 bits. So if you want to end up with a value X in the top 20 bits and you're going to use ADDI
to set the lower 12 bits, and those lower 12 bits have a 1 in the leftmost position, you must do LUI (X+1)
rather than LUI X
. Similarly if you are going to use XORI
to set the lower 12 bits, and those lower 12 bits have a 1 in the leftmost position, you must do LUI (~X)
(that is, the bitwise inverse of X) rather than LUI X
.
But before you do any of that, I'd look to see whether your assembler already has some sort of "load immediate" pseudo-op or macro that will take care of this for you. If it doesn't, then see if you can write one :-)
It's not unusual for RISC processors to need this kind of extra effort from the programmer (or, more usually, from the compiler). The idea is "keep the hardware simple so it can go fast, and it doesn't matter if that makes it harder to construct the software".
来源:https://stackoverflow.com/questions/50742420/risc-v-build-32-bit-constants-with-lui-and-addi