public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/vendors/ARM/heads/morello)] aarch64: Split out LDR/STR offset range check
@ 2022-05-05 12:06 Matthew Malcomson
0 siblings, 0 replies; only message in thread
From: Matthew Malcomson @ 2022-05-05 12:06 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:7e31e09b7dcb31114114b5719c9f198c013da0e4
commit 7e31e09b7dcb31114114b5719c9f198c013da0e4
Author: Richard Sandiford <richard.sandiford@arm.com>
Date: Thu Apr 7 11:41:28 2022 +0100
aarch64: Split out LDR/STR offset range check
aarch64_classify_address contains tests against the LDR/STR range for
a particular mode (and by extension the LDUR/STUR range, via assembler
aliases). This patch splits the check out so that it can be reused in
a later patch.
No behavioural change intended.
Diff:
---
gcc/config/aarch64/aarch64.c | 115 ++++++++++++++++++++++++-------------------
1 file changed, 65 insertions(+), 50 deletions(-)
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 9b1e0d71dd1..e06a35bb702 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -9619,6 +9619,66 @@ aarch64_classify_index (struct aarch64_address_info *info, rtx x,
return false;
}
+/* Return true if REG + OFFSET is a valid addressing mode for mode MODE.
+ ALT_BASE_P is true if REG is an "alternative" base register and false
+ if it is a normal base register. TYPE is the type of address being
+ queried. */
+
+static bool
+aarch64_valid_ldr_str_offset_p (machine_mode mode, bool alt_base_p,
+ poly_int64 offset,
+ aarch64_addr_query_type type)
+{
+ unsigned int vec_flags = aarch64_classify_vector_mode (mode);
+
+ /* Make "m" use the LD1 offset range for SVE data modes, so
+ that pre-RTL optimizers like ivopts will work to that
+ instead of the wider LDR/STR range. */
+ if (vec_flags == VEC_SVE_DATA)
+ return (type == ADDR_QUERY_M
+ ? offset_4bit_signed_scaled_p (mode, offset)
+ : offset_9bit_signed_scaled_p (mode, offset));
+
+ if (vec_flags == (VEC_SVE_DATA | VEC_STRUCT))
+ {
+ poly_int64 end_offset = (offset
+ + GET_MODE_SIZE (mode)
+ - BYTES_PER_SVE_VECTOR);
+ return (type == ADDR_QUERY_M
+ ? offset_4bit_signed_scaled_p (mode, offset)
+ : (offset_9bit_signed_scaled_p (SVE_BYTE_MODE, offset)
+ && offset_9bit_signed_scaled_p (SVE_BYTE_MODE,
+ end_offset)));
+ }
+
+ if (vec_flags == VEC_SVE_PRED)
+ return offset_9bit_signed_scaled_p (mode, offset);
+
+ /* Match LDUR forms, which exist for all remaining
+ (access mode x base mode) combinations. */
+ if (aarch64_offset_9bit_signed_unscaled_p (mode, offset))
+ return true;
+
+ if (alt_base_p)
+ switch (mode)
+ {
+ case E_QImode:
+ case E_SImode:
+ case E_DImode:
+ case E_CADImode:
+ /* LDRB Wn, LDR Wn, LDR Xn and LDR Cn. */
+ return offset_9bit_unsigned_scaled_p (mode, offset);
+
+ default:
+ /* There is no immediate form of LDRH Wn. Similarly for
+ FP/SIMD versions of LDR, which take precedence over
+ the GPR forms when dealing with FP and vector modes. */
+ return false;
+ }
+
+ return offset_12bit_unsigned_scaled_p (mode, offset);
+}
+
/* Return true if MODE is one of the modes for which we
support LDP/STP operations. */
@@ -9781,10 +9841,9 @@ aarch64_classify_address (struct aarch64_address_info *info,
When performing the check for pairs of X registers i.e. LDP/STP
pass down DImode since that is the natural size of the LDP/STP
instruction memory accesses. */
- if (mode == TImode || mode == TFmode)
- return (aarch64_offset_7bit_signed_scaled_p (DImode, offset)
- && (aarch64_offset_9bit_signed_unscaled_p (mode, offset)
- || offset_12bit_unsigned_scaled_p (mode, offset)));
+ if ((mode == TImode || mode == TFmode)
+ && !aarch64_offset_7bit_signed_scaled_p (DImode, offset))
+ return false;
/* A 7bit offset check because OImode will emit a ldp/stp
instruction (only big endian will get here).
@@ -9809,58 +9868,14 @@ aarch64_classify_address (struct aarch64_address_info *info,
&& aarch64_offset_7bit_signed_scaled_p (TImode,
offset + 32));
- /* Make "m" use the LD1 offset range for SVE data modes, so
- that pre-RTL optimizers like ivopts will work to that
- instead of the wider LDR/STR range. */
- if (vec_flags == VEC_SVE_DATA)
- return (type == ADDR_QUERY_M
- ? offset_4bit_signed_scaled_p (mode, offset)
- : offset_9bit_signed_scaled_p (mode, offset));
-
- if (vec_flags == (VEC_SVE_DATA | VEC_STRUCT))
- {
- poly_int64 end_offset = (offset
- + GET_MODE_SIZE (mode)
- - BYTES_PER_SVE_VECTOR);
- return (type == ADDR_QUERY_M
- ? offset_4bit_signed_scaled_p (mode, offset)
- : (offset_9bit_signed_scaled_p (SVE_BYTE_MODE, offset)
- && offset_9bit_signed_scaled_p (SVE_BYTE_MODE,
- end_offset)));
- }
-
- if (vec_flags == VEC_SVE_PRED)
- return offset_9bit_signed_scaled_p (mode, offset);
-
if (load_store_pair_p)
return ((known_eq (GET_MODE_SIZE (mode), 4)
|| known_eq (GET_MODE_SIZE (mode), 8)
|| known_eq (GET_MODE_SIZE (mode), 16))
&& aarch64_offset_7bit_signed_scaled_p (mode, offset));
- /* Match LDUR forms, which exist for all remaining
- (access mode x base mode) combinations. */
- if (aarch64_offset_9bit_signed_unscaled_p (mode, offset))
- return true;
-
- if (alt_base_p)
- switch (mode)
- {
- case E_QImode:
- case E_SImode:
- case E_DImode:
- case E_CADImode:
- /* LDRB Wn, LDR Wn, LDR Xn and LDR Cn. */
- return offset_9bit_unsigned_scaled_p (mode, offset);
-
- default:
- /* There is no immediate form of LDRH Wn. Similarly for
- FP/SIMD versions of LDR, which take precedence over
- the GPR forms when dealing with FP and vector modes. */
- return false;
- }
-
- return offset_12bit_unsigned_scaled_p (mode, offset);
+ return aarch64_valid_ldr_str_offset_p (mode, alt_base_p, offset,
+ type);
}
if (allow_reg_index_p)
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2022-05-05 12:06 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-05 12:06 [gcc(refs/vendors/ARM/heads/morello)] aarch64: Split out LDR/STR offset range check Matthew Malcomson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).