aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJames Greenhalgh <james.greenhalgh@arm.com>2014-05-16 08:59:07 +0000
committerJames Greenhalgh <jgreenhalgh@gcc.gnu.org>2014-05-16 08:59:07 +0000
commit268c3b4758fd7fc54f8cc8220f0a6193ed862a42 (patch)
treeab3cdc8e42487dfb04ea965a4b20d8364c6497d1 /gcc
parent2961177e7d5bd857c4809e6b4a6c655f0bb963cc (diff)
downloadgcc-268c3b4758fd7fc54f8cc8220f0a6193ed862a42.zip
gcc-268c3b4758fd7fc54f8cc8220f0a6193ed862a42.tar.gz
gcc-268c3b4758fd7fc54f8cc8220f0a6193ed862a42.tar.bz2
[AArch64 costs 9/18] Better cost logical operations
gcc/ * config/aarch64/aarch64.c (aarch64_rtx_costs): Improve cost for logical operations. Co-Authored-By: Philipp Tomsich <philipp.tomsich@theobroma-systems.com> From-SVN: r210501
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/aarch64/aarch64.c65
2 files changed, 66 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a084ca98..e648140 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): Improve cost for
+ logical operations.
+
+2014-05-16 James Greenhalgh <james.greenhalgh@arm.com>
+ Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
+
* config/aarch64/aarch64.c (aarch64_rtx_costs): Use address
costs when costing loads and stores to memory.
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index d0a5e49..6b20d4a 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -5206,25 +5206,80 @@ cost_minus:
op0 = XEXP (x, 0);
op1 = XEXP (x, 1);
+ if (code == AND
+ && GET_CODE (op0) == MULT
+ && CONST_INT_P (XEXP (op0, 1))
+ && CONST_INT_P (op1)
+ && aarch64_uxt_size (exact_log2 (INTVAL (XEXP (op0, 1))),
+ INTVAL (op1)) != 0)
+ {
+ /* This is a UBFM/SBFM. */
+ *cost += rtx_cost (XEXP (op0, 0), ZERO_EXTRACT, 0, speed);
+ if (speed)
+ *cost += extra_cost->alu.bfx;
+ return true;
+ }
+
if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
{
+ /* We possibly get the immediate for free, this is not
+ modelled. */
if (CONST_INT_P (op1)
&& aarch64_bitmask_imm (INTVAL (op1), GET_MODE (x)))
{
- *cost += rtx_cost (op0, AND, 0, speed);
+ *cost += rtx_cost (op0, (enum rtx_code) code, 0, speed);
+
+ if (speed)
+ *cost += extra_cost->alu.logical;
+
+ return true;
}
else
{
+ rtx new_op0 = op0;
+
+ /* Handle ORN, EON, or BIC. */
if (GET_CODE (op0) == NOT)
op0 = XEXP (op0, 0);
- op0 = aarch64_strip_shift (op0);
- *cost += (rtx_cost (op0, AND, 0, speed)
- + rtx_cost (op1, AND, 1, speed));
+
+ new_op0 = aarch64_strip_shift (op0);
+
+ /* If we had a shift on op0 then this is a logical-shift-
+ by-register/immediate operation. Otherwise, this is just
+ a logical operation. */
+ if (speed)
+ {
+ if (new_op0 != op0)
+ {
+ /* Shift by immediate. */
+ if (CONST_INT_P (XEXP (op0, 1)))
+ *cost += extra_cost->alu.log_shift;
+ else
+ *cost += extra_cost->alu.log_shift_reg;
+ }
+ else
+ *cost += extra_cost->alu.logical;
+ }
+
+ /* In both cases we want to cost both operands. */
+ *cost += rtx_cost (new_op0, (enum rtx_code) code, 0, speed)
+ + rtx_cost (op1, (enum rtx_code) code, 1, speed);
+
+ return true;
}
- return true;
}
return false;
+ case NOT:
+ /* MVN. */
+ if (speed)
+ *cost += extra_cost->alu.logical;
+
+ /* The logical instruction could have the shifted register form,
+ but the cost is the same if the shift is processed as a separate
+ instruction, so we don't bother with it here. */
+ return false;
+
case ZERO_EXTEND:
if ((GET_MODE (x) == DImode
&& GET_MODE (XEXP (x, 0)) == SImode)