aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Lemke <jim@wasabisystems.com>2003-12-02 02:17:18 +0000
committerJames Lemke <jwlemke@gcc.gnu.org>2003-12-02 02:17:18 +0000
commite3b661203f3377b8387d3cff44aa73ddffc788cf (patch)
tree2221ae3f10793ee075b38c50bb26424774d8e364
parentd9e7c8e3c35b45d40660abe038d4379eb4f770a3 (diff)
downloadgcc-e3b661203f3377b8387d3cff44aa73ddffc788cf.zip
gcc-e3b661203f3377b8387d3cff44aa73ddffc788cf.tar.gz
gcc-e3b661203f3377b8387d3cff44aa73ddffc788cf.tar.bz2
arm.c (arm_rtx_costs): Improve for xscale multiply.
* config/arm/arm.c (arm_rtx_costs): Improve for xscale multiply. * testsuite/gcc.dg/arm-g2.c: New test. From-SVN: r74149
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/config/arm/arm.c34
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/arm-g2.c19
4 files changed, 55 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d11d4f0..7804fc0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,7 @@
+2003-12-01 James Lemke <jim@wasabisystems.com>
+
+ * config/arm/arm.c (arm_rtx_costs): Improve for xscale multiply.
+
2003-12-01 Roger Sayle <roger@eyesopen.com>
PR optimization/11634
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 5ec79df..cadbe65 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -3389,19 +3389,41 @@ arm_rtx_costs_1 (rtx x, enum rtx_code code, enum rtx_code outer)
{
unsigned HOST_WIDE_INT i = (INTVAL (XEXP (x, 1))
& (unsigned HOST_WIDE_INT) 0xffffffff);
- int add_cost = const_ok_for_arm (i) ? 4 : 8;
- int j;
+ int cost, const_ok = const_ok_for_arm (i);
+ int j, booth_unit_size;
+
+ if (arm_tune_xscale)
+ {
+ unsigned HOST_WIDE_INT masked_const;
+
+ /* The cost will be related to two insns.
+ First a load of the constant (MOV or LDR), then a multiply. */
+ cost = 2;
+ if (! const_ok)
+ cost += 1; /* LDR is probably more expensive because
+ of longer result latency. */
+ masked_const = i & 0xffff8000;
+ if (masked_const != 0 && masked_const != 0xffff8000)
+ {
+ masked_const = i & 0xf8000000;
+ if (masked_const == 0 || masked_const == 0xf8000000)
+ cost += 1;
+ else
+ cost += 2;
+ }
+ return cost;
+ }
/* Tune as appropriate. */
- int booth_unit_size = ((tune_flags & FL_FAST_MULT) ? 8 : 2);
-
+ cost = const_ok ? 4 : 8;
+ booth_unit_size = ((tune_flags & FL_FAST_MULT) ? 8 : 2);
for (j = 0; i && j < 32; j += booth_unit_size)
{
i >>= booth_unit_size;
- add_cost += 2;
+ cost += 2;
}
- return add_cost;
+ return cost;
}
return (((tune_flags & FL_FAST_MULT) ? 8 : 30)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d9bc74b..00fb340 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2003-12-01 James Lemke <jim@wasabisystems.com>
+
+ * gcc.dg/arm-g2.c: New test.
+
2003-12-01 Roger Sayle <roger@eyesopen.com>
PR optimization/11634
diff --git a/gcc/testsuite/gcc.dg/arm-g2.c b/gcc/testsuite/gcc.dg/arm-g2.c
new file mode 100644
index 0000000..0120ffb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/arm-g2.c
@@ -0,0 +1,19 @@
+/* Verify that hardware multiply is preferred on XScale. */
+/* { dg-do compile { target xscale*-*-* } } */
+/* { dg-options "-mcpu=xscale -O2" } */
+
+/* Brett Gaines' test case. */
+unsigned BCPL(unsigned) __attribute__ ((naked));
+unsigned BCPL(unsigned seed)
+{
+ /* Best code would be:
+ ldr r1, =2147001325
+ ldr r2, =715136305
+ mla r0, r1, r0, r2
+ mov pc, lr */
+
+ return seed * 2147001325U + 715136305U;
+}
+
+/* We want to suppress running for -mthumb but not for -mthumb-interwork. */
+/* { dg-final { global compiler_flags; if ![string match "*-mthumb *" $compiler_flags] { scan-assembler "mla\[ ].*" } } } */