@@ -4170,6 +4170,58 @@ mips_set_reg_reg_cost (machine_mode mode)
}
}
+/* Implement TARGET_INSN_COSTS. */
+
+static int
+mips_insn_cost (rtx_insn *x, bool speed)
+{
+ int cost;
+ int count;
+ int attr_count;
+ int ratio;
+
+ rtx set = single_set (x);
+ if (!set
+ || (recog_memoized (x) < 0
+ && GET_CODE (PATTERN (x)) != ASM_INPUT
+ && asm_noperands (PATTERN (x)) < 0))
+ {
+ if (set)
+ cost = set_rtx_cost (set, speed);
+ else
+ cost = pattern_cost (PATTERN (x), speed);
+ /* If the cost is zero, then it's likely a complex insn.
+ We don't want the cost of these to be less than
+ something we know about. */
+ return cost ? cost : COSTS_N_INSNS (2);
+ }
+
+ if (!speed)
+ return get_attr_length (x);
+
+ cost = rtx_cost_and_count (SET_SRC (set), GET_MODE (SET_DEST (set)),
+ SET, 1, true, &count);
+ cost = cost ? cost : COSTS_N_INSNS (2);
+ count = count ? count : cost / COSTS_N_INSNS (1);
+ attr_count = get_attr_insn_count (x);
+ ratio = get_attr_perf_ratio (x);
+
+ /* The estimating of rtx_cost_and_count seems good.
+ If we have ratio, we trust it more. If we don't have ratio,
+ we trust rtx_cost more: so x2. */
+ if (ratio == 0 && count < attr_count * 2)
+ return cost;
+
+ /* Over estimate the count of instructions. It normally means that
+ we can combine some INSNs, but rtx_cost have no idea about it. */
+ if (ratio > 0)
+ return get_attr_insn_count (x) * COSTS_N_INSNS (1) * ratio;
+ else if (cost > count && count > 0)
+ return get_attr_insn_count (x) * cost / count;
+ else
+ return get_attr_insn_count (x) * COSTS_N_INSNS (1);
+}
+
/* Implement TARGET_RTX_COSTS. */
static bool
@@ -4195,6 +4247,7 @@ mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
{
gcc_assert (CONSTANT_P (x));
*total = 0;
+ *count = 0;
return true;
}
@@ -4214,6 +4267,7 @@ mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
&& UINTVAL (x) == 0xffffffff)
{
*total = 0;
+ *count = 0;
return true;
}
@@ -4223,6 +4277,7 @@ mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
if (cost >= 0)
{
*total = cost;
+ *count = cost / COSTS_N_INSNS (1);
return true;
}
}
@@ -4236,6 +4291,7 @@ mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
if (speed || mips_immediate_operand_p (outer_code, INTVAL (x)))
{
*total = 0;
+ *count = 0;
return true;
}
}
@@ -4248,6 +4304,7 @@ mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
if (force_to_mem_operand (x, VOIDmode))
{
*total = COSTS_N_INSNS (1);
+ *count = 1;
return true;
}
cost = mips_const_insns (x);
@@ -4281,10 +4338,12 @@ mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
&& (outer_code == SET || GET_MODE (x) == VOIDmode))
cost = 1;
*total = COSTS_N_INSNS (cost);
+ *count = cost;
return true;
}
/* The value will need to be fetched from the constant pool. */
*total = CONSTANT_POOL_COST;
+ *count = CONSTANT_POOL_COST / COSTS_N_INSNS (1);
return true;
case MEM:
@@ -4295,6 +4354,7 @@ mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
if (cost > 0)
{
*total = COSTS_N_INSNS (cost + 1);
+ *count = cost;
return true;
}
/* Check for a scaled indexed address. */
@@ -4302,6 +4362,7 @@ mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
|| mips_lx_address_p (addr, mode))
{
*total = COSTS_N_INSNS (2);
+ *count = 1;
return true;
}
/* Otherwise use the default handling. */
@@ -4309,10 +4370,12 @@ mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
case FFS:
*total = COSTS_N_INSNS (6);
+ *count = 1;
return false;
case NOT:
- *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) > UNITS_PER_WORD ? 2 : 1);
+ *count = (GET_MODE_SIZE (mode) > UNITS_PER_WORD ? 2 : 1);
+ *total = COSTS_N_INSNS (*count);
return false;
case AND:
@@ -4325,6 +4388,7 @@ mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
{
*total = (mips_zero_extend_cost (mode, XEXP (x, 0))
+ set_src_cost (XEXP (x, 0), mode, speed));
+ *count = *total / COSTS_N_INSNS (1);
return true;
}
if (ISA_HAS_CINS && CONST_INT_P (XEXP (x, 1)))
@@ -4336,6 +4400,7 @@ mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
{
*total = COSTS_N_INSNS (1);
*total += set_src_cost (XEXP (op, 0), mode, speed);
+ *count = *total / COSTS_N_INSNS (1);
return true;
}
}
@@ -4349,6 +4414,7 @@ mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
*total = (COSTS_N_INSNS (cost)
+ set_src_cost (XEXP (XEXP (x, 0), 0), mode, speed)
+ set_src_cost (XEXP (XEXP (x, 1), 0), mode, speed));
+ *count = *total / COSTS_N_INSNS (1);
return true;
}
@@ -4359,6 +4425,7 @@ mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
/* Double-word operations use two single-word operations. */
*total = mips_binary_cost (x, COSTS_N_INSNS (1), COSTS_N_INSNS (2),
speed);
+ *count = *total / COSTS_N_INSNS (1);
return true;
case ASHIFT:
@@ -4372,6 +4439,7 @@ mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
else
*total = mips_binary_cost (x, COSTS_N_INSNS (1), COSTS_N_INSNS (12),
speed);
+ *count = *total / COSTS_N_INSNS (1);
return true;
case ABS:
@@ -4379,12 +4447,14 @@ mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
*total = mips_cost->fp_add;
else
*total = COSTS_N_INSNS (4);
+ *count = 1;
return false;
case LO_SUM:
/* Low-part immediates need an extended MIPS16 instruction. */
*total = (COSTS_N_INSNS (TARGET_MIPS16 ? 2 : 1)
+ set_src_cost (XEXP (x, 0), mode, speed));
+ *count = *total / COSTS_N_INSNS (1);
return true;
case LT:
@@ -4409,10 +4479,12 @@ mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
if (FLOAT_MODE_P (mode))
{
*total = mips_cost->fp_add;
+ *count = 1;
return false;
}
*total = mips_binary_cost (x, COSTS_N_INSNS (1), COSTS_N_INSNS (4),
speed);
+ *count = *total / COSTS_N_INSNS (1);
return true;
case MINUS:
@@ -4429,6 +4501,7 @@ mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
+ set_src_cost (XEXP (XEXP (op0, 0), 0), mode, speed)
+ set_src_cost (XEXP (op0, 1), mode, speed)
+ set_src_cost (op1, mode, speed));
+ *count = 2;
return true;
}
if (GET_CODE (op1) == MULT)
@@ -4437,6 +4510,7 @@ mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
+ set_src_cost (op0, mode, speed)
+ set_src_cost (XEXP (op1, 0), mode, speed)
+ set_src_cost (XEXP (op1, 1), mode, speed));
+ *count = 2;
return true;
}
}
@@ -4448,9 +4522,15 @@ mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
/* If this is part of a MADD or MSUB, treat the PLUS as
being free. */
if (ISA_HAS_UNFUSED_MADD4 && GET_CODE (XEXP (x, 0)) == MULT)
- *total = 0;
+ {
+ *total = 0;
+ *count = 0;
+ }
else
- *total = mips_cost->fp_add;
+ {
+ *total = mips_cost->fp_add;
+ *count = 1;
+ }
return false;
}
@@ -4466,6 +4546,7 @@ mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
*total = (COSTS_N_INSNS (1)
+ set_src_cost (XEXP (XEXP (x, 0), 0), mode, speed)
+ set_src_cost (XEXP (x, 1), mode, speed));
+ *count = *total / COSTS_N_INSNS (1);
return true;
}
}
@@ -4476,6 +4557,7 @@ mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
*total = mips_binary_cost (x, COSTS_N_INSNS (1),
COSTS_N_INSNS (TARGET_MIPS16 ? 5 : 4),
speed);
+ *count = *total / COSTS_N_INSNS (1);
return true;
case NEG:
@@ -4491,31 +4573,46 @@ mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
+ set_src_cost (XEXP (XEXP (op, 0), 0), mode, speed)
+ set_src_cost (XEXP (XEXP (op, 0), 1), mode, speed)
+ set_src_cost (XEXP (op, 1), mode, speed));
+ *count = 2;
return true;
}
}
if (float_mode_p)
- *total = mips_cost->fp_add;
+ {
+ *total = mips_cost->fp_add;
+ *count = 1;
+ }
else
- *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) > UNITS_PER_WORD ? 4 : 1);
+ {
+ *count = (GET_MODE_SIZE (mode) > UNITS_PER_WORD ? 4 : 1);
+ *total = COSTS_N_INSNS (*count);
+ }
return false;
case FMA:
*total = mips_fp_mult_cost (mode);
+ *count = 1;
return false;
case MULT:
+ *count = 1;
if (float_mode_p)
*total = mips_fp_mult_cost (mode);
else if (mode == DImode && !TARGET_64BIT)
- /* Synthesized from 2 mulsi3s, 1 mulsidi3 and two additions,
- where the mulsidi3 always includes an MFHI and an MFLO. */
- *total = (speed
- ? mips_cost->int_mult_si * 3 + 6
- : COSTS_N_INSNS (ISA_HAS_MUL3 ? 7 : 9));
+ {
+ /* Synthesized from 2 mulsi3s, 1 mulsidi3 and two additions,
+ where the mulsidi3 always includes an MFHI and an MFLO. */
+ *total = (speed
+ ? mips_cost->int_mult_si * 3 + 6
+ : COSTS_N_INSNS (ISA_HAS_MUL3 ? 7 : 9));
+ *count = (speed ? 4 : (ISA_HAS_MUL3 ? 2 : 3));
+ }
else if (!speed)
- *total = COSTS_N_INSNS ((ISA_HAS_MUL3 || ISA_HAS_R6MUL) ? 1 : 2) + 1;
+ {
+ *count = ((ISA_HAS_MUL3 || ISA_HAS_R6MUL) ? 1 : 2);
+ *total = COSTS_N_INSNS (*count) + 1;
+ }
else if (mode == DImode)
*total = mips_cost->int_mult_di;
else
@@ -4536,6 +4633,7 @@ mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
else
*total = (mips_fp_div_cost (mode)
+ set_src_cost (XEXP (x, 1), mode, speed));
+ *count = 2;
return true;
}
/* Fall through. */
@@ -4545,12 +4643,14 @@ mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
if (float_mode_p)
{
*total = mips_fp_div_cost (mode);
+ *count = 2;
return false;
}
/* Fall through. */
case UDIV:
case UMOD:
+ *count = 1;
if (!speed)
{
/* It is our responsibility to make division by a power of 2
@@ -4565,6 +4665,7 @@ mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
{
*total = COSTS_N_INSNS (2);
*total += set_src_cost (XEXP (x, 0), mode, speed);
+ *count = *total / COSTS_N_INSNS (1);
return true;
}
*total = COSTS_N_INSNS (mips_idiv_insns (mode));
@@ -4577,6 +4678,7 @@ mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
case SIGN_EXTEND:
*total = mips_sign_extend_cost (mode, XEXP (x, 0));
+ *count = *total / COSTS_N_INSNS (1);
return false;
case ZERO_EXTEND:
@@ -4588,9 +4690,11 @@ mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
&& GET_CODE (XEXP (XEXP (x, 0), 0)) == PLUS)
{
*total = set_src_cost (XEXP (XEXP (x, 0), 0), VOIDmode, speed);
+ *count = *total / COSTS_N_INSNS (1);
return true;
}
*total = mips_zero_extend_cost (mode, XEXP (x, 0));
+ *count = *total / COSTS_N_INSNS (1);
return false;
case TRUNCATE:
/* Costings for highpart multiplies. Matching patterns of the form:
@@ -4635,7 +4739,7 @@ mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
*total += rtx_cost (XEXP (op, 0), VOIDmode, GET_CODE (op),
0, speed);
}
-
+ *count = 3;
return true;
}
return false;
@@ -4646,6 +4750,7 @@ mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
case FLOAT_EXTEND:
case FLOAT_TRUNCATE:
*total = mips_cost->fp_add;
+ *count = 1;
return false;
case SET:
@@ -4653,6 +4758,7 @@ mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
&& reg_or_0_operand (SET_SRC (x), VOIDmode))
{
*total = mips_set_reg_reg_cost (GET_MODE (SET_DEST (x)));
+ *count = *total / COSTS_N_INSNS (1);
return true;
}
return false;
@@ -23072,6 +23178,8 @@ mips_bit_clear_p (enum machine_mode mode, unsigned HOST_WIDE_INT m)
#define TARGET_RTX_COSTS mips_rtx_costs
#undef TARGET_ADDRESS_COST
#define TARGET_ADDRESS_COST mips_address_cost
+#undef TARGET_INSN_COST
+#define TARGET_INSN_COST mips_insn_cost
#undef TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P
#define TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P mips_no_speculation_in_delay_slots_p