@@ -1117,6 +1117,7 @@ static tree rs6000_builtin_vectorized_libmass (tree, tree, tree);
static void rs6000_emit_set_long_const (rtx, HOST_WIDE_INT);
static int rs6000_memory_move_cost (machine_mode, reg_class_t, bool);
static bool rs6000_debug_rtx_costs (rtx, machine_mode, int, int, int *, bool);
+static int rs6000_address_cost (rtx, machine_mode, addr_space_t, bool);
static int rs6000_debug_address_cost (rtx, machine_mode, addr_space_t,
bool);
static int rs6000_debug_adjust_cost (rtx_insn *, rtx, rtx_insn *, int);
@@ -1523,7 +1524,7 @@ static const struct attribute_spec rs6000_attribute_table[] =
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS rs6000_rtx_costs
#undef TARGET_ADDRESS_COST
-#define TARGET_ADDRESS_COST hook_int_rtx_mode_as_bool_0
+#define TARGET_ADDRESS_COST rs6000_address_cost
#undef TARGET_DWARF_REGISTER_SPAN
#define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
@@ -30720,14 +30721,20 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code,
- (outer_code == SET ? 1 : 0));
return true;
- case CONST:
- case HIGH:
- case SYMBOL_REF:
case MEM:
/* When optimizing for size, MEM should be slightly more expensive
than generating address, e.g., (plus (reg) (const)).
L1 cache latency is about two instructions. */
*total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
+ *total += COSTS_N_INSNS (rs6000_address_cost (XEXP (x, 0), mode,
+ 0, speed));
+ return true;
+
+ case CONST:
+ case HIGH:
+ case LO_SUM:
+ case SYMBOL_REF:
+ *total = COSTS_N_INSNS (1);
return true;
case LABEL_REF:
@@ -31009,6 +31016,26 @@ rs6000_debug_rtx_costs (rtx x, machine_mode mode, int outer_code,
return ret;
}
+/* Say that before being split, -mcmodel=medium/large UNSPEC_TOCREL
+ addresses cost one more insn than other addresses. */
+
+static int
+rs6000_address_cost (rtx x,
+ machine_mode mode ATTRIBUTE_UNUSED,
+ addr_space_t as ATTRIBUTE_UNUSED,
+ bool speed ATTRIBUTE_UNUSED)
+{
+ if (TARGET_CMODEL == CMODEL_SMALL)
+ return 0;
+
+ if (GET_CODE (x) == PLUS)
+ x = XEXP (x, 0);
+ if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TOCREL)
+ return 1;
+
+ return 0;
+}
+
/* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
static int