This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[AArch64 costs 15/18] Cost more Floating point RTX.
- From: James Greenhalgh <james dot greenhalgh at arm dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: richard dot earnshaw at arm dot com, marcus dot shawcroft at arm dot com, philipp dot tomsich at theobroma-systems dot com
- Date: Thu, 27 Mar 2014 17:33:39 +0000
- Subject: [AArch64 costs 15/18] Cost more Floating point RTX.
- Authentication-results: sourceware.org; auth=none
- References: <1395941622-22926-1-git-send-email-james dot greenhalgh at arm dot com>
Hi,
This one adds FMA, FLOAT_EXTEND, FLOAT_TRUNCATE, ABS.
and SMAX/SMIN.
Tested in series on aarch64-none-elf.
OK for stage 1?
Thanks,
James
---
2014-03-27 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.
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index bdfcc55..3caff3a 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -5588,6 +5588,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;
}