Commit a97d8b98 by Richard Sandiford Committed by Richard Sandiford

[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
parent 75b7462e
2017-12-21 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
* 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.
2017-12-20 Richard Biener <rguenther@suse.de> 2017-12-20 Richard Biener <rguenther@suse.de>
* tree-ssa-dom.c (dom_opt_dom_walker::optimize_stmt): Call * tree-ssa-dom.c (dom_opt_dom_walker::optimize_stmt): Call
...@@ -111,6 +111,19 @@ enum aarch64_symbol_type ...@@ -111,6 +111,19 @@ enum aarch64_symbol_type
SYMBOL_FORCE_TO_MEM 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 /* A set of tuning parameters contains references to size and time
cost models and vectors for address cost calculations, register cost models and vectors for address cost calculations, register
move costs and memory move costs. */ move costs and memory move costs. */
...@@ -440,7 +453,8 @@ bool aarch64_float_const_representable_p (rtx); ...@@ -440,7 +453,8 @@ bool aarch64_float_const_representable_p (rtx);
#if defined (RTX_CODE) #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); machine_mode aarch64_select_cc_mode (RTX_CODE, rtx, rtx);
rtx aarch64_gen_compare_reg (RTX_CODE, rtx, rtx); rtx aarch64_gen_compare_reg (RTX_CODE, rtx, rtx);
rtx aarch64_load_tp (rtx); rtx aarch64_load_tp (rtx);
......
...@@ -4437,21 +4437,21 @@ virt_or_elim_regno_p (unsigned regno) ...@@ -4437,21 +4437,21 @@ virt_or_elim_regno_p (unsigned regno)
|| regno == ARG_POINTER_REGNUM); || regno == ARG_POINTER_REGNUM);
} }
/* Return true if X is a valid address for machine mode MODE. If it is, /* Return true if X is a valid address of type TYPE for machine mode MODE.
fill in INFO appropriately. STRICT_P is true if REG_OK_STRICT is in If it is, fill in INFO appropriately. STRICT_P is true if
effect. OUTER_CODE is PARALLEL for a load/store pair. */ REG_OK_STRICT is in effect. */
static bool static bool
aarch64_classify_address (struct aarch64_address_info *info, aarch64_classify_address (struct aarch64_address_info *info,
rtx x, machine_mode mode, rtx x, machine_mode mode, bool strict_p,
RTX_CODE outer_code, bool strict_p) aarch64_addr_query_type type = ADDR_QUERY_M)
{ {
enum rtx_code code = GET_CODE (x); enum rtx_code code = GET_CODE (x);
rtx op0, op1; rtx op0, op1;
/* On BE, we use load/store pair for all large int mode load/stores. /* On BE, we use load/store pair for all large int mode load/stores.
TI/TFmode may also use a load/store pair. */ 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 == TImode
|| mode == TFmode || mode == TFmode
|| (BYTES_BIG_ENDIAN || (BYTES_BIG_ENDIAN
...@@ -4683,7 +4683,7 @@ aarch64_address_valid_for_prefetch_p (rtx x, bool strict_p) ...@@ -4683,7 +4683,7 @@ aarch64_address_valid_for_prefetch_p (rtx x, bool strict_p)
struct aarch64_address_info addr; struct aarch64_address_info addr;
/* PRFM accepts the same addresses as DImode... */ /* 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) if (!res)
return false; return false;
...@@ -4719,19 +4719,18 @@ aarch64_legitimate_address_hook_p (machine_mode mode, rtx x, bool strict_p) ...@@ -4719,19 +4719,18 @@ aarch64_legitimate_address_hook_p (machine_mode mode, rtx x, bool strict_p)
{ {
struct aarch64_address_info addr; 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 /* Return TRUE if X is a legitimate address of type TYPE for accessing
mode MODE. OUTER_CODE will be PARALLEL if this is a load/store memory in mode MODE. STRICT_P is true if REG_OK_STRICT is in effect. */
pair operation. */
bool bool
aarch64_legitimate_address_p (machine_mode mode, rtx x, aarch64_legitimate_address_p (machine_mode mode, rtx x, bool strict_p,
RTX_CODE outer_code, bool strict_p) aarch64_addr_query_type type)
{ {
struct aarch64_address_info addr; 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. /* 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) ...@@ -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 'op' is the context required by aarch64_classify_address. It can either be
MEM for a normal memory access or PARALLEL for LDP/STP. */ MEM for a normal memory access or PARALLEL for LDP/STP. */
static bool 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; struct aarch64_address_info addr;
/* Check all addresses are Pmode - including ILP32. */ /* Check all addresses are Pmode - including ILP32. */
gcc_assert (GET_MODE (x) == Pmode); 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) switch (addr.type)
{ {
case ADDRESS_REG_IMM: case ADDRESS_REG_IMM:
...@@ -5725,14 +5725,14 @@ aarch64_print_address_internal (FILE *f, machine_mode mode, rtx x, RTX_CODE op) ...@@ -5725,14 +5725,14 @@ aarch64_print_address_internal (FILE *f, machine_mode mode, rtx x, RTX_CODE op)
static bool static bool
aarch64_print_ldpstp_address (FILE *f, machine_mode mode, rtx x) 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'. */ /* Print address 'x' of a memory access with mode 'mode'. */
static void static void
aarch64_print_operand_address (FILE *f, machine_mode mode, rtx x) 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); output_addr_const (f, x);
} }
...@@ -6561,7 +6561,7 @@ aarch64_address_cost (rtx x, ...@@ -6561,7 +6561,7 @@ aarch64_address_cost (rtx x,
int cost = 0; int cost = 0;
info.shift = 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) if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF)
{ {
......
...@@ -161,15 +161,15 @@ ...@@ -161,15 +161,15 @@
A memory address which uses a base register with an offset small enough for A memory address which uses a base register with an offset small enough for
a load/store pair operation in DI mode." a load/store pair operation in DI mode."
(and (match_code "mem") (and (match_code "mem")
(match_test "aarch64_legitimate_address_p (DImode, XEXP (op, 0), (match_test "aarch64_legitimate_address_p (DImode, XEXP (op, 0), false,
PARALLEL, false)"))) ADDR_QUERY_LDP_STP)")))
(define_memory_constraint "Ump" (define_memory_constraint "Ump"
"@internal "@internal
A memory address suitable for a load/store pair operation." A memory address suitable for a load/store pair operation."
(and (match_code "mem") (and (match_code "mem")
(match_test "aarch64_legitimate_address_p (GET_MODE (op), XEXP (op, 0), (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 ;; Used for storing two 64-bit values in an AdvSIMD register using an STP
;; as a 128-bit vec_concat. ;; as a 128-bit vec_concat.
...@@ -177,8 +177,8 @@ ...@@ -177,8 +177,8 @@
"@internal "@internal
A memory address suitable for a load/store pair operation." A memory address suitable for a load/store pair operation."
(and (match_code "mem") (and (match_code "mem")
(match_test "aarch64_legitimate_address_p (DFmode, XEXP (op, 0), (match_test "aarch64_legitimate_address_p (DFmode, XEXP (op, 0), 1,
PARALLEL, 1)"))) ADDR_QUERY_LDP_STP)")))
(define_memory_constraint "Utv" (define_memory_constraint "Utv"
"@internal "@internal
...@@ -191,8 +191,8 @@ ...@@ -191,8 +191,8 @@
"@internal "@internal
An address valid for loading or storing a 128-bit AdvSIMD register" An address valid for loading or storing a 128-bit AdvSIMD register"
(and (match_code "mem") (and (match_code "mem")
(match_test "aarch64_legitimate_address_p (V2DImode, XEXP (op, 0), (match_test "aarch64_legitimate_address_p (V2DImode,
MEM, 1)"))) XEXP (op, 0), 1)")))
(define_constraint "Ufc" (define_constraint "Ufc"
"A floating point constant which can be used with an\ "A floating point constant which can be used with an\
......
...@@ -186,15 +186,15 @@ ...@@ -186,15 +186,15 @@
(define_predicate "aarch64_mem_pair_operand" (define_predicate "aarch64_mem_pair_operand"
(and (match_code "mem") (and (match_code "mem")
(match_test "aarch64_legitimate_address_p (mode, XEXP (op, 0), PARALLEL, (match_test "aarch64_legitimate_address_p (mode, XEXP (op, 0), false,
0)"))) ADDR_QUERY_LDP_STP)")))
;; Used for storing two 64-bit values in an AdvSIMD register using an STP ;; Used for storing two 64-bit values in an AdvSIMD register using an STP
;; as a 128-bit vec_concat. ;; as a 128-bit vec_concat.
(define_predicate "aarch64_mem_pair_lanes_operand" (define_predicate "aarch64_mem_pair_lanes_operand"
(and (match_code "mem") (and (match_code "mem")
(match_test "aarch64_legitimate_address_p (DFmode, XEXP (op, 0), (match_test "aarch64_legitimate_address_p (DFmode, XEXP (op, 0), 1,
PARALLEL, 1)"))) ADDR_QUERY_LDP_STP)")))
(define_predicate "aarch64_prefetch_operand" (define_predicate "aarch64_prefetch_operand"
(match_test "aarch64_address_valid_for_prefetch_p (op, false)")) (match_test "aarch64_address_valid_for_prefetch_p (op, false)"))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment