Hi Richard, > aarch64_simd_valid_imm tries to decompose a constant into a repeating > series of 64 bits, since most Advanced SIMD and SVE immediate forms > require that. (The exceptions are handled first.) It does this by > building up a byte-level register image, lsb first. If the image does > turn out to repeat every 64 bits, it loads the first 64 bits into an > integer. > > At this point, endianness has mostly been dealt with. Endianness > applies to transfers between registers and memory, whereas at this > point we're dealing purely with register values. > > However, one of things we try is to bitcast the value to a float > and use FMOV. This involves splitting the value into 32-bit chunks > (stored as longs) and passing them to real_from_target. The problem > being fixed by this patch is that, when a value spans multiple 32-bit > chunks, real_from_target expects them to be in memory rather than > register order. Thus index 0 is the most significant chunk if > FLOAT_WORDS_BIG_ENDIAN and the least significant chunk otherwise. > > This fixes aarch64/sve/cond_fadd_1.c and various other tests > for aarch64_be-elf. > > Tested on aarch64-linux-gnu and aarch64_be-elf. OK to install?
LGTM. OK. Cheers. Wilco gcc/ * config/aarch64/aarch64.cc (aarch64_simd_valid_imm): Account for FLOAT_WORDS_BIG_ENDIAN when building a floating-point value. --- gcc/config/aarch64/aarch64.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index 6d5b2009b2a..27c315fc35e 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -23687,6 +23687,8 @@ aarch64_simd_valid_imm (rtx op, simd_immediate_info *info, long int as_long_ints[2]; as_long_ints[0] = ival & 0xFFFFFFFF; as_long_ints[1] = (ival >> 32) & 0xFFFFFFFF; + if (imode == DImode && FLOAT_WORDS_BIG_ENDIAN) + std::swap (as_long_ints[0], as_long_ints[1]); REAL_VALUE_TYPE r; real_from_target (&r, as_long_ints, fmode); -- 2.43.0