Jeff Kenton <jkenton@xxxxxxxxxx> writes: > Our chip is 64 bits / 64 registers, and the little-endian tool chain > works fine. I have configured "as" and "ld" to be big-endian and they > work. For gcc I have set BYTES_BIG_ENDIAN to 1 and left the rest of > the *_ENDIAN definitions as 0, which is appropriate for the > architecture. > > But, I have a problem which shows up (at least) two ways, for the same > reason: > > Compiling: > > if (x != x) > { > x = 1.0; > } > > causes an assertion failure in emit-rtl.c:gen_rtx_SUBREG() because > validate_subreg() thinks the value of the compare is in the high half > of a register, but needs to be in the bottom half. [ Note: The > required value is actually in the bottom half, where it belongs, and > the generated code is correct if I comment out the assert. ] This sounds like a problem in your port. It sounds like you have some code, or an insn pattern, which is using a specific value when generating a subreg, rather than using gen_lowpart or something along those lines. > Compiling with -O0: > > void > test_48(long arg) > { > PASS((signed char)arg); > } > > results in the following broken code: > > 00000000000101a0 <test_48>: > <prologue> > 101d0: { addi r1, r52, -16 } // save "arg" on stack > 101d8: { st r1, r0 } // 64 bit store > 101e0: { addi r0, r52, -16 } // retrieve "arg" > 101e8: { addi r0, r0, 7 } // BROKEN!!! -- the > hardware makes this adjustment in BE mode. > 101f0: { ld1s r0, r0 } // 1 byte load > 101f8: { mtspr PASS, r0 } > <epilogue> > > [ Note: compiling -O3 gives the right code because it doesn't waste > instructions storing arg into memory and retrieving it. ] Could be the same problem or could be something different. You will have to find out which part of gcc is adding 7 there. Ian