aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2023-12-10 19:46:06 +0000
committerRichard Sandiford <richard.sandiford@arm.com>2023-12-10 19:46:06 +0000
commitf5c8d6bc050a8a6120aff2be25b6892d91baac99 (patch)
tree42029648ef66163cf0f45b57499f8e91750327a9
parent8c1df4022546cc783c4ab666751c9a2e9b3637b0 (diff)
downloadgcc-f5c8d6bc050a8a6120aff2be25b6892d91baac99.zip
gcc-f5c8d6bc050a8a6120aff2be25b6892d91baac99.tar.gz
gcc-f5c8d6bc050a8a6120aff2be25b6892d91baac99.tar.bz2
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.
-rw-r--r--gcc/config/aarch64/aarch64.cc15
1 files changed, 9 insertions, 6 deletions
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 5cffdab..2a64053 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;