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.