https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95285

--- Comment #7 from Bu Le <bule1 at huawei dot com> ---
(In reply to Wilco from comment #5)
> (In reply to Bu Le from comment #0)
> 
> Also it would be much more efficient to have a relocation like this if you
> wanted a 48-bit PC-relative offset:
> 
> adrp    x0, bar1.2782
> add     x0, x0, :lo12:bar1.2782
> movk    x0, :high32_47:bar1.2782

I am afraid that put the PC-relative offset into x0 is not correct, because x0
issuppose to be the final address of bar1 rather than an PC offset. Therefore
an extra register is needed to hold the offest temporarily. Later, we need to
add the PC address of the movk with the offset to calsulate 32:48 bits of the
final address of bar1. Finally, add this part of address with x0 to compute the
entire 48 bits final address. So the code sould be following sequence:

adrp    x0, bar1.2782
add     x0, x0, :lo12:bar1.2782  //x0 here hold the 0:31 bits of the final addr
movk    x4, :prel_g2:bar1.2782
adr     x1, .
sub     x1, x1, 0x4
add     x4, x4, x1   // x4 here hold the 32:47 bits of the final addr
add     x0, x4, x0

(By the way, the high32_47 relocation you suggested is the prel_g2 in the
officail aarch64 ABI released)

So acctually, if we just want a 48-bit PC-relevent relocation, your idea and
mine both need 6-7 instructions to get the symbol. In terms of efficiency, it
would be similar. 

And in terms of engineering, you idea can save the trouble to modify the linker
for calculating the offset for 3 movks. But we still need to make a new
relocation type for ADRP, because it currently checking the overflow of address
and gives the "relocation truncated to fit" error. Therefore, both idea need to
do works in binutils, which make it also equivalent.

Reply via email to