AUPIC and LUI

422 views
Skip to first unread message

Anthony Fox

unread,
Jan 29, 2016, 10:05:41 AM1/29/16
to isa...@lists.riscv.org
Hello,

I���ve been working on supporting RISC-V (RV64I) as a target for the CakeML compiler (https://cakeml.org). To do this I���ve been using a specification written by Prashanth Mundkur at SRI. I discussed one aspect of the architecture with him and he suggested that I share this with the ISA-dev list.

Page 14 of The RISC-V Instruction Set Manual (Volume 1) discusses using AUIPC (with a 20-bit immediate) in combination with a regular load or store (with a 12-bit immediate). The question is whether or not any 32-bit PC-relative data address can be accessed in RV64I? For example, consider the pair of instruction

AUPIC rs, imm20
LB rd, rs, imm12

If X is a 64-bit offset in the (signed) 32-bit range

0xFFFFFFFF80000000 <= X <= 0x7FFFFFFF

then imm12 would be the bottom twelve bits, i.e. imm12 = X<11:0>. The top twenty bits could then be computed as follows

imm20 = (X - SignExtend (imm12))<31:12>

This method works fine when X is in the range

0xFFFFFFFF80000000 <= X <= 0x7FFFF7FF

but fails when X is within the range

0x7FFFF800 <= X <= 0x7FFFFFFF

For example, if we want PC + 0x7FFFF800 then imm12 is 0x800 and imm20 is computed to be 0x80000, which gives us PC - 0x80000800 (which is PC + 0xFFFFFFFF7FFFF800).


This is based on the following instruction semantics:

��� AUPIC is specified as computing the address

PC + SignExtend (imm20 : 0`12) // Pad to the right with zero (12-bits wide) and then sign-extend

��� LB computes the address

GPR(rs) + SignExtend (imm12)


A similar situation seems to arise for LUI and ADDI when trying to construct a 32-bit value. As a workaround I used

LUI rd, ~(X<31:12>) // 1���s complement of top 20 bits
XORI rd, rd, X<11:0> // bottom 12 bits

when imm<11> is ���1���. (Building up large immediate values was easier in ARMv8, since MOVK, MOVN and MOVZ are quite nice to work with.)

Regards,
Anthony

Andrew Waterman

unread,
Jan 29, 2016, 1:40:08 PM1/29/16
to Anthony Fox, isa-dev
Right--in RV64, you can't directly address 0x7ffff800 - 0x7fffffff
with LUI+LD, and you can't construct offsets in that range with just
AUIPC+LD. The RV64 linker enforces these constraints.

GCC uses LUI+XORI to construct constants like you describe. You could
alternatively use LUI+ADDIW for generating any 32-bit sign-extended
constant, since the ADDIW forces sign-extension from bit 31.

Reply all
Reply to author
Forward
0 new messages