On 21/12/15 16:24, Eric Botcazou wrote: > Hi, > > the attached Ada testcase triggers an ICE with -mbig-endian -mhard-float: > > eric@polaris:~/build/gcc/arm-linux-gnueabi> gcc/xgcc -Bgcc -S p.adb -I > gcc/ada/rts -mbig-endian -mhard-float > +===========================GNAT BUG DETECTED==============================+ > | 6.0.0 20151220 (experimental) [trunk revision 231856] (arm-linux-gnueabi) > GCC error:| > | in emit_move_multi_word, at expr.c:3452 > > because the middle-end is trying to copy an OImode value from VFP registers > and the back-end refuses it in big-endian mode: > > In big-endian mode, modes greater than word size (i.e. DFmode) are stored in > VFP registers in little-endian order. We can't describe that accurately to > GCC, so avoid taking subregs of such values. > The only exception is going from a 128-bit to a 64-bit type. In that case > the data layout happens to be consistent for big-endian, so we explicitly > allow that case. */ > #define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \ > (TARGET_VFP && TARGET_BIG_END \ > && !(GET_MODE_SIZE (FROM) == 16 && GET_MODE_SIZE (TO) == 8) \ > && (GET_MODE_SIZE (FROM) > UNITS_PER_WORD \ > || GET_MODE_SIZE (TO) > UNITS_PER_WORD) \ > && reg_classes_intersect_p (VFP_REGS, (CLASS))) > > That's very likely not reproducible in the C family of languages because the > code generates a RECORD_TYPE with OImode. The other thing to note is that > this works for TImode because, in this case, the back-end returns a PARALLEL > instead of a bare REG for the return value register. > > Hence the attached patch, which extends this treatment to all integer modes > larger than TImode. Tested on arm-none-eabi, OK for the mainline? > > > 2015-12-21 Eric Botcazou <ebotca...@adacore.com> > > * config/arm/arm.c (aapcs_vfp_allocate_return_reg): Treat all integer > modes larger than TImode as TImode if NEON is not enabled. > >
OK. R.