From: Richard Sandiford Date: Sun, 10 Dec 2023 19:46:06 +0000 (+0000) Subject: aarch64: Fix SMSTART/SMSTOP save/restore for BE X-Git-Tag: basepoints/gcc-15~3753 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f5c8d6bc050a8a6120aff2be25b6892d91baac99;p=thirdparty%2Fgcc.git aarch64: Fix SMSTART/SMSTOP save/restore for BE VNx16QI (the SVE register byte mode) is the only SVE mode for which LD1 and LDR result in the same register layout for big-endian. It is therefore the only mode for which we allow LDR and STR to be used for big-endian SVE moves. The SME support sometimes needs to use LDR and STR to save and restore Z register contents around an SMSTART/SMSTOP SM. It therefore needs to use VNx16QI regardless of the type of value that is stored in the Z registers. gcc/ PR target/112930 * config/aarch64/aarch64.cc (aarch64_sme_mode_switch_regs::add_reg): Force specific SVE modes for single registers as well as structures. --- diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index 5cffdabc62e5..2a64053f675c 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -4956,14 +4956,17 @@ aarch64_sme_mode_switch_regs::add_reg (machine_mode mode, unsigned int regno) gcc_assert ((vec_flags & VEC_STRUCT) || end_regno == regno + 1); for (; regno < end_regno; regno++) { + /* Force the mode of SVE saves and restores even for single registers. + This is necessary because big-endian targets only allow LDR Z and + STR Z to be used with byte modes. */ machine_mode submode = mode; - if (vec_flags & VEC_STRUCT) + if (vec_flags & VEC_SVE_PRED) + submode = VNx16BImode; + else if (vec_flags & VEC_SVE_DATA) + submode = SVE_BYTE_MODE; + else if (vec_flags & VEC_STRUCT) { - if (vec_flags & VEC_SVE_PRED) - submode = VNx16BImode; - else if (vec_flags & VEC_SVE_DATA) - submode = SVE_BYTE_MODE; - else if (vec_flags & VEC_PARTIAL) + if (vec_flags & VEC_PARTIAL) submode = V8QImode; else submode = V16QImode;