OSDN Git Service

* config/arm/arm.c (arm_rtx_costs): Improve for xscale multiply.
authorjwlemke <jwlemke@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 2 Dec 2003 02:17:18 +0000 (02:17 +0000)
committerjwlemke <jwlemke@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 2 Dec 2003 02:17:18 +0000 (02:17 +0000)
* testsuite/gcc.dg/arm-g2.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@74149 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/arm/arm.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/arm-g2.c [new file with mode: 0644]

index d11d4f0..7804fc0 100644 (file)
@@ -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
index 5ec79df..cadbe65 100644 (file)
@@ -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)
index d9bc74b..00fb340 100644 (file)
@@ -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 (file)
index 0000000..0120ffb
--- /dev/null
@@ -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\[         ].*" } } } */