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>
* tree-ssa-dom.c (dom_opt_dom_walker::optimize_stmt): Call
......@@ -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);
......
......@@ -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)
{
......
......@@ -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\
......
......@@ -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)"))
......
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