summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/avr/avr.c47
2 files changed, 44 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f57ef041ab2..92f7c7f2e9b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2017-07-17 Georg-Johann Lay <avr@gjlay.de>
+
+ PR 80929
+ * config/avr/avr.c (avr_mul_highpart_cost): New static function.
+ (avr_rtx_costs_1) [TRUNCATE]: Use it to compute mul_highpart cost.
+ [LSHIFTRT, outer_code = TRUNCATE]: Same.
+
2017-07-17 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/81396
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index 49ebb6352a2..0abfa13df94 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -10709,6 +10709,33 @@ avr_memory_move_cost (machine_mode mode,
}
+/* Cost for mul highpart. X is a LSHIFTRT, i.e. the outer TRUNCATE is
+ already stripped off. */
+
+static int
+avr_mul_highpart_cost (rtx x, int)
+{
+ if (AVR_HAVE_MUL
+ && LSHIFTRT == GET_CODE (x)
+ && MULT == GET_CODE (XEXP (x, 0))
+ && CONST_INT_P (XEXP (x, 1)))
+ {
+ // This is the wider mode.
+ machine_mode mode = GET_MODE (x);
+
+ // The middle-end might still have PR81444, i.e. it is calling the cost
+ // functions with strange modes. Fix this now by also considering
+ // PSImode (should actually be SImode instead).
+ if (HImode == mode || PSImode == mode || SImode == mode)
+ {
+ return COSTS_N_INSNS (2);
+ }
+ }
+
+ return 10000;
+}
+
+
/* Mutually recursive subroutine of avr_rtx_cost for calculating the
cost of an RTX operand given its context. X is the rtx of the
operand, MODE is its mode, and OUTER is the rtx_code of this
@@ -10748,7 +10775,7 @@ avr_operand_rtx_cost (rtx x, machine_mode mode, enum rtx_code outer,
In either case, *TOTAL contains the cost result. */
static bool
-avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code ATTRIBUTE_UNUSED,
+avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code,
int opno ATTRIBUTE_UNUSED, int *total, bool speed)
{
enum rtx_code code = GET_CODE (x);
@@ -11402,6 +11429,12 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code ATTRIBUTE_UNUSED,
return true;
case LSHIFTRT:
+ if (outer_code == TRUNCATE)
+ {
+ *total = avr_mul_highpart_cost (x, speed);
+ return true;
+ }
+
switch (mode)
{
case QImode:
@@ -11579,16 +11612,10 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code ATTRIBUTE_UNUSED,
return true;
case TRUNCATE:
- if (AVR_HAVE_MUL
- && LSHIFTRT == GET_CODE (XEXP (x, 0))
- && MULT == GET_CODE (XEXP (XEXP (x, 0), 0))
- && CONST_INT_P (XEXP (XEXP (x, 0), 1)))
+ if (LSHIFTRT == GET_CODE (XEXP (x, 0)))
{
- if (QImode == mode || HImode == mode)
- {
- *total = COSTS_N_INSNS (2);
- return true;
- }
+ *total = avr_mul_highpart_cost (XEXP (x, 0), speed);
+ return true;
}
break;