http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27619



Segher Boessenkool <segher at gcc dot gnu.org> changed:



           What    |Removed                     |Added

----------------------------------------------------------------------------

             Status|NEW                         |ASSIGNED

                 CC|                            |segher at gcc dot gnu.org

         AssignedTo|unassigned at gcc dot       |segher at gcc dot gnu.org

                   |gnu.org                     |



--- Comment #15 from Segher Boessenkool <segher at gcc dot gnu.org> 2012-10-23 
16:10:34 UTC ---

Things become a little clearer if you compile with -ffast-math, so

that the floatdisf2_internal2 pattern is not used.



The function then starts as:



        stwu 1,-16(1)

        lis 9,i@ha

        lwa 9,i@l(9)

        mflr 0

        std 9,8(1)



and stepi shows that the lwa insn already loads the wrong value!

Of course, GDB will not show the instruction because it does not

want to disassemble 64-bit insns in a 32-bit binary; but it shows



   0x100002fc <+12>:    .long 0xe9290890



which is wrong: it should be e9290892, low two bits zero means it

is an ld insn, not lwa.



The lwa patterns use the wrong constraint (they use "m", should

be "Y", because the low 2 bits of the offset are required to be

zero); but that does not fix it.



For 64-bit binaries, the relocations formed by @l for ld and lwa

and friends are ADDR16_LO_DS relocations; but for 32-bit binaries,

GAS simply makes ADDR16_LO relocations, which do set the low two

vits from the offset.  Oops.



Now of course ADDR16_LO_DS relocations do not exist for the 32-bit

PowerPC ABI, but overwriting the low bits of the instruction isn't

terribly helpful.



On GCC's side, I don't think we have any other choice than to disable

all instructions that need DS relocations when targetting an ABI

that does not have relocations for those; except we can get away

with it for insns that should have the low two bits zero.



So we need to disable (for -m32 -mpowerpc64): lwa, ldu, stdu; but

we can keep: ld, std (and ldx, ldux, stdx, stdux -- those aren't

DS-form, do not need relocations).

Reply via email to