diff options
author | Richard Sandiford <richard.sandiford@linaro.org> | 2017-12-21 06:57:04 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2017-12-21 06:57:04 +0000 |
commit | a97d8b982793ba5bf1e54a41d9bb110182b8baf8 (patch) | |
tree | 62aaefa775450b5e1cecb47fd10b0360dec12e5a /gcc/config | |
parent | 75b7462e1ac607a9107ef8a158dafdef0728f01d (diff) | |
download | gcc-a97d8b982793ba5bf1e54a41d9bb110182b8baf8.zip gcc-a97d8b982793ba5bf1e54a41d9bb110182b8baf8.tar.gz gcc-a97d8b982793ba5bf1e54a41d9bb110182b8baf8.tar.bz2 |
[AArch64] Tweak aarch64_classify_address interface
Previously aarch64_classify_address used an rtx code to distinguish
LDP/STP addresses from normal addresses; the code was PARALLEL
to select LDP/STP and anything else to select normal addresses.
This patch replaces that parameter with a dedicated enum.
The SVE port will add another enum value that didn't map naturally
to an rtx code.
2017-12-21 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
gcc/
* config/aarch64/aarch64-protos.h (aarch64_addr_query_type): New enum.
(aarch64_legitimate_address_p): Use it instead of an rtx code,
as an optional final parameter.
* config/aarch64/aarch64.c (aarch64_classify_address): Likewise.
(aarch64_legitimate_address_p): Likewise.
(aarch64_print_address_internal): Take an aarch64_addr_query_type
instead of an rtx code.
(aarch64_address_valid_for_prefetch_p): Update calls accordingly.
(aarch64_legitimate_address_hook_p): Likewise.
(aarch64_print_ldpstp_address): Likewise.
(aarch64_print_operand_address): Likewise.
(aarch64_address_cost): Likewise.
* config/aarch64/constraints.md (Uml, Umq, Ump, Utq): Likewise.
* config/aarch64/predicates.md (aarch64_mem_pair_operand): Likewise.
(aarch64_mem_pair_lanes_operand): Likewise.
Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>
From-SVN: r255911
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/aarch64/aarch64-protos.h | 16 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64.c | 38 | ||||
-rw-r--r-- | gcc/config/aarch64/constraints.md | 14 | ||||
-rw-r--r-- | gcc/config/aarch64/predicates.md | 8 |
4 files changed, 45 insertions, 31 deletions
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h index 15c3b46..002ac33 100644 --- a/gcc/config/aarch64/aarch64-protos.h +++ b/gcc/config/aarch64/aarch64-protos.h @@ -111,6 +111,19 @@ enum aarch64_symbol_type SYMBOL_FORCE_TO_MEM }; +/* Classifies the type of an address query. + + ADDR_QUERY_M + Query what is valid for an "m" constraint and a memory_operand + (the rules are the same for both). + + ADDR_QUERY_LDP_STP + Query what is valid for a load/store pair. */ +enum aarch64_addr_query_type { + ADDR_QUERY_M, + ADDR_QUERY_LDP_STP +}; + /* A set of tuning parameters contains references to size and time cost models and vectors for address cost calculations, register move costs and memory move costs. */ @@ -440,7 +453,8 @@ bool aarch64_float_const_representable_p (rtx); #if defined (RTX_CODE) -bool aarch64_legitimate_address_p (machine_mode, rtx, RTX_CODE, bool); +bool aarch64_legitimate_address_p (machine_mode, rtx, bool, + aarch64_addr_query_type = ADDR_QUERY_M); machine_mode aarch64_select_cc_mode (RTX_CODE, rtx, rtx); rtx aarch64_gen_compare_reg (RTX_CODE, rtx, rtx); rtx aarch64_load_tp (rtx); diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index d10fa16..fc27b40 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -4437,21 +4437,21 @@ virt_or_elim_regno_p (unsigned regno) || regno == ARG_POINTER_REGNUM); } -/* Return true if X is a valid address for machine mode MODE. If it is, - fill in INFO appropriately. STRICT_P is true if REG_OK_STRICT is in - effect. OUTER_CODE is PARALLEL for a load/store pair. */ +/* Return true if X is a valid address of type TYPE for machine mode MODE. + If it is, fill in INFO appropriately. STRICT_P is true if + REG_OK_STRICT is in effect. */ static bool aarch64_classify_address (struct aarch64_address_info *info, - rtx x, machine_mode mode, - RTX_CODE outer_code, bool strict_p) + rtx x, machine_mode mode, bool strict_p, + aarch64_addr_query_type type = ADDR_QUERY_M) { enum rtx_code code = GET_CODE (x); rtx op0, op1; /* On BE, we use load/store pair for all large int mode load/stores. TI/TFmode may also use a load/store pair. */ - bool load_store_pair_p = (outer_code == PARALLEL + bool load_store_pair_p = (type == ADDR_QUERY_LDP_STP || mode == TImode || mode == TFmode || (BYTES_BIG_ENDIAN @@ -4683,7 +4683,7 @@ aarch64_address_valid_for_prefetch_p (rtx x, bool strict_p) struct aarch64_address_info addr; /* PRFM accepts the same addresses as DImode... */ - bool res = aarch64_classify_address (&addr, x, DImode, MEM, strict_p); + bool res = aarch64_classify_address (&addr, x, DImode, strict_p); if (!res) return false; @@ -4719,19 +4719,18 @@ aarch64_legitimate_address_hook_p (machine_mode mode, rtx x, bool strict_p) { struct aarch64_address_info addr; - return aarch64_classify_address (&addr, x, mode, MEM, strict_p); + return aarch64_classify_address (&addr, x, mode, strict_p); } -/* Return TRUE if X is a legitimate address for accessing memory in - mode MODE. OUTER_CODE will be PARALLEL if this is a load/store - pair operation. */ +/* Return TRUE if X is a legitimate address of type TYPE for accessing + memory in mode MODE. STRICT_P is true if REG_OK_STRICT is in effect. */ bool -aarch64_legitimate_address_p (machine_mode mode, rtx x, - RTX_CODE outer_code, bool strict_p) +aarch64_legitimate_address_p (machine_mode mode, rtx x, bool strict_p, + aarch64_addr_query_type type) { struct aarch64_address_info addr; - return aarch64_classify_address (&addr, x, mode, outer_code, strict_p); + return aarch64_classify_address (&addr, x, mode, strict_p, type); } /* Split an out-of-range address displacement into a base and offset. @@ -5630,14 +5629,15 @@ aarch64_print_operand (FILE *f, rtx x, int code) 'op' is the context required by aarch64_classify_address. It can either be MEM for a normal memory access or PARALLEL for LDP/STP. */ static bool -aarch64_print_address_internal (FILE *f, machine_mode mode, rtx x, RTX_CODE op) +aarch64_print_address_internal (FILE *f, machine_mode mode, rtx x, + aarch64_addr_query_type type) { struct aarch64_address_info addr; /* Check all addresses are Pmode - including ILP32. */ gcc_assert (GET_MODE (x) == Pmode); - if (aarch64_classify_address (&addr, x, mode, op, true)) + if (aarch64_classify_address (&addr, x, mode, true, type)) switch (addr.type) { case ADDRESS_REG_IMM: @@ -5725,14 +5725,14 @@ aarch64_print_address_internal (FILE *f, machine_mode mode, rtx x, RTX_CODE op) static bool aarch64_print_ldpstp_address (FILE *f, machine_mode mode, rtx x) { - return aarch64_print_address_internal (f, mode, x, PARALLEL); + return aarch64_print_address_internal (f, mode, x, ADDR_QUERY_LDP_STP); } /* Print address 'x' of a memory access with mode 'mode'. */ static void aarch64_print_operand_address (FILE *f, machine_mode mode, rtx x) { - if (!aarch64_print_address_internal (f, mode, x, MEM)) + if (!aarch64_print_address_internal (f, mode, x, ADDR_QUERY_M)) output_addr_const (f, x); } @@ -6561,7 +6561,7 @@ aarch64_address_cost (rtx x, int cost = 0; info.shift = 0; - if (!aarch64_classify_address (&info, x, mode, c, false)) + if (!aarch64_classify_address (&info, x, mode, false)) { if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF) { diff --git a/gcc/config/aarch64/constraints.md b/gcc/config/aarch64/constraints.md index af4143e..70ea3cd 100644 --- a/gcc/config/aarch64/constraints.md +++ b/gcc/config/aarch64/constraints.md @@ -161,15 +161,15 @@ A memory address which uses a base register with an offset small enough for a load/store pair operation in DI mode." (and (match_code "mem") - (match_test "aarch64_legitimate_address_p (DImode, XEXP (op, 0), - PARALLEL, false)"))) + (match_test "aarch64_legitimate_address_p (DImode, XEXP (op, 0), false, + ADDR_QUERY_LDP_STP)"))) (define_memory_constraint "Ump" "@internal A memory address suitable for a load/store pair operation." (and (match_code "mem") (match_test "aarch64_legitimate_address_p (GET_MODE (op), XEXP (op, 0), - PARALLEL, 1)"))) + true, ADDR_QUERY_LDP_STP)"))) ;; Used for storing two 64-bit values in an AdvSIMD register using an STP ;; as a 128-bit vec_concat. @@ -177,8 +177,8 @@ "@internal A memory address suitable for a load/store pair operation." (and (match_code "mem") - (match_test "aarch64_legitimate_address_p (DFmode, XEXP (op, 0), - PARALLEL, 1)"))) + (match_test "aarch64_legitimate_address_p (DFmode, XEXP (op, 0), 1, + ADDR_QUERY_LDP_STP)"))) (define_memory_constraint "Utv" "@internal @@ -191,8 +191,8 @@ "@internal An address valid for loading or storing a 128-bit AdvSIMD register" (and (match_code "mem") - (match_test "aarch64_legitimate_address_p (V2DImode, XEXP (op, 0), - MEM, 1)"))) + (match_test "aarch64_legitimate_address_p (V2DImode, + XEXP (op, 0), 1)"))) (define_constraint "Ufc" "A floating point constant which can be used with an\ diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md index 2eaf0a7..d5593d1 100644 --- a/gcc/config/aarch64/predicates.md +++ b/gcc/config/aarch64/predicates.md @@ -186,15 +186,15 @@ (define_predicate "aarch64_mem_pair_operand" (and (match_code "mem") - (match_test "aarch64_legitimate_address_p (mode, XEXP (op, 0), PARALLEL, - 0)"))) + (match_test "aarch64_legitimate_address_p (mode, XEXP (op, 0), false, + ADDR_QUERY_LDP_STP)"))) ;; Used for storing two 64-bit values in an AdvSIMD register using an STP ;; as a 128-bit vec_concat. (define_predicate "aarch64_mem_pair_lanes_operand" (and (match_code "mem") - (match_test "aarch64_legitimate_address_p (DFmode, XEXP (op, 0), - PARALLEL, 1)"))) + (match_test "aarch64_legitimate_address_p (DFmode, XEXP (op, 0), 1, + ADDR_QUERY_LDP_STP)"))) (define_predicate "aarch64_prefetch_operand" (match_test "aarch64_address_valid_for_prefetch_p (op, false)")) |