+struct addr_mode_cost_table
+{
+ const int integer[AMO_MAX];
+ const int fp[AMO_MAX];
+ const int vector[AMO_MAX];
+};
+
/* Dump function ARM_PRINT_TUNE_INFO should be updated whenever this
structure is modified. */
struct tune_params
{
const struct cpu_cost_table *insn_extra_cost;
+ const struct addr_mode_cost_table *addr_mode_costs;
bool (*sched_adjust_cost) (rtx_insn *, int, rtx_insn *, int *);
int (*branch_cost) (bool, bool);
/* Vectorizer costs. */
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index b8dbed6..0d31f5f 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -1751,9 +1751,32 @@ const struct cpu_cost_table v7m_extra_costs =
}
};
+const struct addr_mode_cost_table generic_addr_mode_costs =
+{
+ /* int. */
+ {
+ 0, /* AMO_DEFAULT. */
+ 0, /* AMO_NO_WB. */
+ 0 /* AMO_WB. */
+ },
+ /* float. */
+ {
+ 0, /* AMO_DEFAULT. */
+ 0, /* AMO_NO_WB. */
+ 0 /* AMO_WB. */
+ },
+ /* vector. */
+ {
+ 0, /* AMO_DEFAULT. */
+ 0, /* AMO_NO_WB. */
+ 0 /* AMO_WB. */
+ }
+};
+
const struct tune_params arm_slowmul_tune =
{
&generic_extra_costs, /* Insn extra costs. */
+ &generic_addr_mode_costs, /* Addressing mode costs. */
NULL, /* Sched adj cost. */
arm_default_branch_cost,
&arm_default_vec_cost,
@@ -1777,6 +1800,7 @@ const struct tune_params arm_slowmul_tune =
const struct tune_params arm_fastmul_tune =
{
&generic_extra_costs, /* Insn extra costs. */
+ &generic_addr_mode_costs, /* Addressing mode costs. */
NULL, /* Sched adj cost. */
arm_default_branch_cost,
&arm_default_vec_cost,
@@ -1803,6 +1827,7 @@ const struct tune_params arm_fastmul_tune =
const struct tune_params arm_strongarm_tune =
{
&generic_extra_costs, /* Insn extra costs. */
+ &generic_addr_mode_costs, /* Addressing mode costs. */
NULL, /* Sched adj cost. */
arm_default_branch_cost,
&arm_default_vec_cost,
@@ -1826,6 +1851,7 @@ const struct tune_params arm_strongarm_tune =
const struct tune_params arm_xscale_tune =
{
&generic_extra_costs, /* Insn extra costs. */
+ &generic_addr_mode_costs, /* Addressing mode costs. */
xscale_sched_adjust_cost,
arm_default_branch_cost,
&arm_default_vec_cost,
@@ -1849,6 +1875,7 @@ const struct tune_params arm_xscale_tune =
const struct tune_params arm_9e_tune =
{
&generic_extra_costs, /* Insn extra costs. */
+ &generic_addr_mode_costs, /* Addressing mode costs. */
NULL, /* Sched adj cost. */
arm_default_branch_cost,
&arm_default_vec_cost,
@@ -1872,6 +1899,7 @@ const struct tune_params arm_9e_tune =
const struct tune_params arm_marvell_pj4_tune =
{
&generic_extra_costs, /* Insn extra costs. */
+ &generic_addr_mode_costs, /* Addressing mode costs. */
NULL, /* Sched adj cost. */
arm_default_branch_cost,
&arm_default_vec_cost,
@@ -1895,6 +1923,7 @@ const struct tune_params arm_marvell_pj4_tune =
const struct tune_params arm_v6t2_tune =
{
&generic_extra_costs, /* Insn extra costs. */
+ &generic_addr_mode_costs, /* Addressing mode costs. */
NULL, /* Sched adj cost. */
arm_default_branch_cost,
&arm_default_vec_cost,
@@ -1920,6 +1949,7 @@ const struct tune_params arm_v6t2_tune =
const struct tune_params arm_cortex_tune =
{
&generic_extra_costs,
+ &generic_addr_mode_costs, /* Addressing mode costs. */
NULL, /* Sched adj cost. */
arm_default_branch_cost,
&arm_default_vec_cost,
@@ -1943,6 +1973,7 @@ const struct tune_params arm_cortex_tune =
const struct tune_params arm_cortex_a8_tune =
{
&cortexa8_extra_costs,
+ &generic_addr_mode_costs, /* Addressing mode costs. */
NULL, /* Sched adj cost. */
arm_default_branch_cost,
&arm_default_vec_cost,
@@ -1966,6 +1997,7 @@ const struct tune_params arm_cortex_a8_tune =
const struct tune_params arm_cortex_a7_tune =
{
&cortexa7_extra_costs,
+ &generic_addr_mode_costs, /* Addressing mode costs. */
NULL, /* Sched adj cost. */
arm_default_branch_cost,
&arm_default_vec_cost,
@@ -1989,6 +2021,7 @@ const struct tune_params arm_cortex_a7_tune =
const struct tune_params arm_cortex_a15_tune =
{
&cortexa15_extra_costs,
+ &generic_addr_mode_costs, /* Addressing mode costs. */
NULL, /* Sched adj cost. */
arm_default_branch_cost,
&arm_default_vec_cost,
@@ -2012,6 +2045,7 @@ const struct tune_params arm_cortex_a15_tune =
const struct tune_params arm_cortex_a35_tune =
{
&cortexa53_extra_costs,
+ &generic_addr_mode_costs, /* Addressing mode costs. */
NULL, /* Sched adj cost. */
arm_default_branch_cost,
&arm_default_vec_cost,
@@ -2035,6 +2069,7 @@ const struct tune_params arm_cortex_a35_tune =
const struct tune_params arm_cortex_a53_tune =
{
&cortexa53_extra_costs,
+ &generic_addr_mode_costs, /* Addressing mode costs. */
NULL, /* Sched adj cost. */
arm_default_branch_cost,
&arm_default_vec_cost,
@@ -2058,6 +2093,7 @@ const struct tune_params arm_cortex_a53_tune =
const struct tune_params arm_cortex_a57_tune =
{
&cortexa57_extra_costs,
+ &generic_addr_mode_costs, /* addressing mode costs */
NULL, /* Sched adj cost. */
arm_default_branch_cost,
&arm_default_vec_cost,
@@ -2081,6 +2117,7 @@ const struct tune_params arm_cortex_a57_tune =
const struct tune_params arm_exynosm1_tune =
{
&exynosm1_extra_costs,
+ &generic_addr_mode_costs, /* Addressing mode
costs. */
NULL, /* Sched adj
cost. */
arm_default_branch_cost,
&arm_default_vec_cost,
@@ -2104,6 +2141,7 @@ const struct tune_params arm_exynosm1_tune =
const struct tune_params arm_xgene1_tune =
{
&xgene1_extra_costs,
+ &generic_addr_mode_costs, /* Addressing mode costs. */
NULL, /* Sched adj cost. */
arm_default_branch_cost,
&arm_default_vec_cost,
@@ -2130,6 +2168,7 @@ const struct tune_params arm_xgene1_tune =
const struct tune_params arm_cortex_a5_tune =
{
&cortexa5_extra_costs,
+ &generic_addr_mode_costs, /* Addressing mode costs. */
NULL, /* Sched adj cost. */
arm_cortex_a5_branch_cost,
&arm_default_vec_cost,
@@ -2153,6 +2192,7 @@ const struct tune_params arm_cortex_a5_tune =
const struct tune_params arm_cortex_a9_tune =
{
&cortexa9_extra_costs,
+ &generic_addr_mode_costs, /* Addressing mode costs. */
cortex_a9_sched_adjust_cost,
arm_default_branch_cost,
&arm_default_vec_cost,
@@ -2176,6 +2216,7 @@ const struct tune_params arm_cortex_a9_tune =
const struct tune_params arm_cortex_a12_tune =
{
&cortexa12_extra_costs,
+ &generic_addr_mode_costs, /* Addressing mode costs. */
NULL, /* Sched adj cost. */
arm_default_branch_cost,
&arm_default_vec_cost, /* Vectorizer costs. */
@@ -2199,6 +2240,7 @@ const struct tune_params arm_cortex_a12_tune =
const struct tune_params arm_cortex_a73_tune =
{
&cortexa57_extra_costs,
+ &generic_addr_mode_costs, /* Addressing mode
costs. */
NULL, /* Sched adj
cost. */
arm_default_branch_cost,
&arm_default_vec_cost, /* Vectorizer costs. */
@@ -2229,6 +2271,7 @@ const struct tune_params arm_cortex_a73_tune =
const struct tune_params arm_v7m_tune =
{
&v7m_extra_costs,
+ &generic_addr_mode_costs, /* Addressing mode costs. */
NULL, /* Sched adj cost. */
arm_cortex_m_branch_cost,
&arm_default_vec_cost,
@@ -2254,6 +2297,7 @@ const struct tune_params arm_v7m_tune =
const struct tune_params arm_cortex_m7_tune =
{
&v7m_extra_costs,
+ &generic_addr_mode_costs, /* Addressing mode costs. */
NULL, /* Sched adj cost. */
arm_cortex_m7_branch_cost,
&arm_default_vec_cost,
@@ -2280,6 +2324,7 @@ const struct tune_params arm_cortex_m7_tune =
const struct tune_params arm_v6m_tune =
{
&generic_extra_costs, /* Insn extra costs. */
+ &generic_addr_mode_costs, /* Addressing mode costs. */
NULL, /* Sched adj cost. */
arm_default_branch_cost,
&arm_default_vec_cost, /* Vectorizer costs. */
@@ -2303,6 +2348,7 @@ const struct tune_params arm_v6m_tune =
const struct tune_params arm_fa726te_tune =
{
&generic_extra_costs, /* Insn extra costs. */
+ &generic_addr_mode_costs, /* Addressing mode
costs. */
fa726te_sched_adjust_cost,
arm_default_branch_cost,
&arm_default_vec_cost,
@@ -9249,7 +9295,42 @@ arm_mem_costs (rtx x, const struct
cpu_cost_table *extra_cost,
/* Calculate cost of the addressing mode. */
if (speed_p)
{
- /* TODO: Add table-driven costs for addressing modes. (See
patch 2) */
+ arm_addr_mode_op op_type;
+ switch (GET_CODE (XEXP (x, 0)))
+ {
+ default:
+ case REG:
+ op_type = AMO_DEFAULT;
+ break;
+ case MINUS:
+ /* MINUS does not appear in RTL, but the architecture
supports it,
+ so handle this case defensively. */
+ /* fall through */
+ case PLUS:
+ op_type = AMO_NO_WB;
+ break;
+ case PRE_INC:
+ case PRE_DEC:
+ case POST_INC:
+ case POST_DEC:
+ case PRE_MODIFY:
+ case POST_MODIFY:
+ op_type = AMO_WB;
+ break;
+ }
+
+ if (VECTOR_MODE_P (mode))
+ {
+ *cost += current_tune->addr_mode_costs->vector[op_type];
+ }
+ else if (FLOAT_MODE_P (mode))
+ {
+ *cost += current_tune->addr_mode_costs->fp[op_type];
+ }
+ else
+ {
+ *cost += current_tune->addr_mode_costs->integer[op_type];
+ }