diff options
author | Richard Sandiford <richard.sandiford@arm.com> | 2023-12-10 19:46:06 +0000 |
---|---|---|
committer | Richard Sandiford <richard.sandiford@arm.com> | 2023-12-10 19:46:06 +0000 |
commit | f5c8d6bc050a8a6120aff2be25b6892d91baac99 (patch) | |
tree | 42029648ef66163cf0f45b57499f8e91750327a9 | |
parent | 8c1df4022546cc783c4ab666751c9a2e9b3637b0 (diff) | |
download | gcc-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.cc | 15 |
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; |