Re: [Tack-devel] change in RELOPPC with hi16, ha16, lo16
Moved to https://github.com/davidgiven/ack
Brought to you by:
dtrg
From: George K. <ke...@gm...> - 2017-02-09 00:25:35
|
After I sent the last mail about the RELOPPC change, I decided to throw it away and do it differently. I did rewind my branch https://github.com/kernigh/ack/tree/kernigh-linuxppc to before the RELOPPC change. I then added a new relocation type RELOLIS. I transplanted my ncg changes from the old branch to the new branch. The old branch is now https://github.com/kernigh/ack/tree/zzz-old-reloppc RELOLIS handles a single instruction, a PowerPC lis using ha16 or hi16: lis RT, ha16[expr] == addis RT, r0, ha16[expr] lis RT, hi16[expr] == addis RT, r0, hi16[expr] The relocated expr is a symbol plus a signed 26-bit offset. The trick is how RELOLIS stores the offset in the program text. The lis instruction takes 32 bits. There are 6 bits for the addis opcode, 5 bits for register RT, 5 bits for register r0, and 16 bits for the immediate value. RELOLIS is only for lis instructions, so it doesn't need to store the addis opcode or register r0. This frees 11 bits. I need 5 bits to store register RT, but I have 27 other bits. I use 1 bit as a flag, set for ha16, clear for hi16. The other 26 bits are the offset. RELOLIS stores the value with the flag in the high bit, the register RT in the next 5 bits, and the offset in the low 26 bits. During relocation, the linker does symbol plus offset. The high 16 bits of the sum become the immediate value of the lis. If the ha16 flag is set, the linker does the sign adjustment. Then the linker assembles the lis instruction, filling in the addis opcode and the register r0. RELOLIS is simple because it handles a single ha16 or hi16 instruction. It doesn't need to find a second instruction with a matching lo16. -George Koehler |