aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJames Greenhalgh <james.greenhalgh@arm.com>2014-05-16 09:20:22 +0000
committerJames Greenhalgh <jgreenhalgh@gcc.gnu.org>2014-05-16 09:20:22 +0000
commitb292109f9ec580c1b81e4b39388cb0d315318d7e (patch)
treecc3479e30db23ca0610f386740d8d93b7f4e13df /gcc
parenta8eecd00ec2693734716d20592e5253ab135929a (diff)
downloadgcc-b292109f9ec580c1b81e4b39388cb0d315318d7e.zip
gcc-b292109f9ec580c1b81e4b39388cb0d315318d7e.tar.gz
gcc-b292109f9ec580c1b81e4b39388cb0d315318d7e.tar.bz2
[AArch64 costs 15/18] Cost more Floating point RTX.
gcc/ * config/aarch64/aarch64.c (aarch64_rtx_costs): Cost FMA, FLOAT_EXTEND, FLOAT_TRUNCATE, ABS, SMAX, and SMIN. Co-Authored-By: Philipp Tomsich <philipp.tomsich@theobroma-systems.com> From-SVN: r210507
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/aarch64/aarch64.c83
2 files changed, 89 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 86a70cd..a4e6b18 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,6 +1,12 @@
2014-05-16 James Greenhalgh <james.greenhalgh@arm.com>
Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
+ * config/aarch64/aarch64.c (aarch64_rtx_costs): Cost FMA,
+ FLOAT_EXTEND, FLOAT_TRUNCATE, ABS, SMAX, and SMIN.
+
+2014-05-16 James Greenhalgh <james.greenhalgh@arm.com>
+ Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
+
* config/aarch64/aarch64.c (aarch64_rtx_costs): Cost comparison
operators.
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 8d863ed..503f914 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -5641,6 +5641,89 @@ cost_plus:
return false; /* All arguments must be in registers. */
+ case FMA:
+ op0 = XEXP (x, 0);
+ op1 = XEXP (x, 1);
+ op2 = XEXP (x, 2);
+
+ if (speed)
+ *cost += extra_cost->fp[mode == DFmode].fma;
+
+ /* FMSUB, FNMADD, and FNMSUB are free. */
+ if (GET_CODE (op0) == NEG)
+ op0 = XEXP (op0, 0);
+
+ if (GET_CODE (op2) == NEG)
+ op2 = XEXP (op2, 0);
+
+ /* aarch64_fnma4_elt_to_64v2df has the NEG as operand 1,
+ and the by-element operand as operand 0. */
+ if (GET_CODE (op1) == NEG)
+ op1 = XEXP (op1, 0);
+
+ /* Catch vector-by-element operations. The by-element operand can
+ either be (vec_duplicate (vec_select (x))) or just
+ (vec_select (x)), depending on whether we are multiplying by
+ a vector or a scalar.
+
+ Canonicalization is not very good in these cases, FMA4 will put the
+ by-element operand as operand 0, FNMA4 will have it as operand 1. */
+ if (GET_CODE (op0) == VEC_DUPLICATE)
+ op0 = XEXP (op0, 0);
+ else if (GET_CODE (op1) == VEC_DUPLICATE)
+ op1 = XEXP (op1, 0);
+
+ if (GET_CODE (op0) == VEC_SELECT)
+ op0 = XEXP (op0, 0);
+ else if (GET_CODE (op1) == VEC_SELECT)
+ op1 = XEXP (op1, 0);
+
+ /* If the remaining parameters are not registers,
+ get the cost to put them into registers. */
+ *cost += rtx_cost (op0, FMA, 0, speed);
+ *cost += rtx_cost (op1, FMA, 1, speed);
+ *cost += rtx_cost (op2, FMA, 2, speed);
+ return true;
+
+ case FLOAT_EXTEND:
+ if (speed)
+ *cost += extra_cost->fp[mode == DFmode].widen;
+ return false;
+
+ case FLOAT_TRUNCATE:
+ if (speed)
+ *cost += extra_cost->fp[mode == DFmode].narrow;
+ return false;
+
+ case ABS:
+ if (GET_MODE_CLASS (mode) == MODE_FLOAT)
+ {
+ /* FABS and FNEG are analogous. */
+ if (speed)
+ *cost += extra_cost->fp[mode == DFmode].neg;
+ }
+ else
+ {
+ /* Integer ABS will either be split to
+ two arithmetic instructions, or will be an ABS
+ (scalar), which we don't model. */
+ *cost = COSTS_N_INSNS (2);
+ if (speed)
+ *cost += 2 * extra_cost->alu.arith;
+ }
+ return false;
+
+ case SMAX:
+ case SMIN:
+ if (speed)
+ {
+ /* FMAXNM/FMINNM/FMAX/FMIN.
+ TODO: This may not be accurate for all implementations, but
+ we do not model this in the cost tables. */
+ *cost += extra_cost->fp[mode == DFmode].addsub;
+ }
+ return false;
+
default:
break;
}