The following instruction sequence generates an invalid address offset: .org 0x100100 data0: .short 0x1234 e_lis r4, data0@ha e_lhz r4, data0@l(r4) ... this will assemble to code that disassembles to: e_lis r4, word_0x100000@ha e_lhz r4, word_0x100000@l In other words, it does not calculate the lower 16 bit offset correctly. This also fails: e_lis r4, data0@ha e_addi16 r4, r4, data0@l e_lhz r4, 0(r4) Again, this assembles to reference address 0x100000 for data0. However, the following sequence WORKS correctly: e_lis r4, data0@ha e_ori r4, r4, data0@l e_lhz r4, 0(r4)
Seems to already be fixed, if this bug ever existed. Disassembly of relocatable object files won't always show you what you might expect, since the instruction fields may have relocations. It pays to use objdump -dr to see the relocs. Note that this e_lis r4, data0@ha e_ori r4, r4, data0@l is incorrect and *will* result in wrong addresses in the final linked object for half the possible addresses of data0. You need to use @hi to set the high 16 bits when using ori to set the low 16 bits.
Created attachment 10381 [details] Assembly file to illustrate low 16 bit address problem
Thanks, can you confirm whether this is correct? It doesn't seem like it: Original assembly (attached as test.s): .org 0x100100 e_b begin data0: .short 0x1234 .align 2, 0x44 begin: e_lis r4, data0@ha e_lhz r4, data0@l(r4) _@photon ~/asm $ powerpc-linux-as -many -mvle -mregnames test.s _@photon ~/asm $ powerpc-linux-objdump -dr a.out a.out: file format elf32-powerpc Disassembly of section .text: 00000000 <data0-0x100104>: ... 100100: 78 00 00 08 e_b 100108 <begin> 00100104 <data0>: 100104: 12 34 44 44 .long 0x12344444 00100108 <begin>: 100108: 70 80 e0 10 e_lis r4,16 100108: R_PPC_VLE_HA16A .text+0x100104 10010c: 58 84 00 00 e_lhz r4,0(r4) 10010e: R_PPC_ADDR16_LO .text+0x100104 It seems to correctly set the symbol to 0x100104, but note the low 16 bit decoding is wrong, it's using 0 instead of 0x0104.
Ok, I think it's been sorted out. I was converting the assembler objection file directly to binary, skipping the linker step. I added this: ld -melf32ppc --section-start=.text=0x100100 test.o -o test_vle.bin ...and it produces the correct machine code.