]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
aarch64: Fix SMSTART/SMSTOP save/restore for BE
authorRichard Sandiford <richard.sandiford@arm.com>
Sun, 10 Dec 2023 19:46:06 +0000 (19:46 +0000)
committerRichard Sandiford <richard.sandiford@arm.com>
Sun, 10 Dec 2023 19:46:06 +0000 (19:46 +0000)
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.

gcc/config/aarch64/aarch64.cc

index 5cffdabc62e547bbafaedcd46215120e5c7da888..2a64053f675c44945ac5edee72d3f29fee81eec7 100644 (file)
@@ -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;