rs6000.c (registers_ok_for_quad_peep): Return false if we do not have fp register.
authorAndrew Pinski <pinskia@physics.uc.edu>
Wed, 28 Apr 2004 23:03:31 +0000 (23:03 +0000)
committerAndrew Pinski <pinskia@gcc.gnu.org>
Wed, 28 Apr 2004 23:03:31 +0000 (16:03 -0700)
2004-04-28  Andrew Pinski  <pinskia@physics.uc.edu>

        * config/rs6000/rs6000.c (registers_ok_for_quad_peep):
        Return false if we do not have fp register.
        (addrs_ok_for_quad_peep): Rename to ...
        (mems_ok_for_quad_peep): this.
        Add check for volatile memory.
        * config/rs6000/rs6000-protos.h (addrs_ok_for_quad_peep):
        Rename to ...
        (mems_ok_for_quad_peep): this.
        * config/rs6000/rs6000.md: Change peephole's for lfq/stq
        to peephole2's.
        (lfq_power2): New instruction.
        (stfq_power2): Likewise.

2004-04-28  Andrew Pinski  <pinskia@physics.uc.edu>

        * gcc.dg/rs6000-power2-1.c: New test.
        * gcc.dg/rs6000-power2-2.c: New test.

From-SVN: r81262

gcc/ChangeLog
gcc/config/rs6000/rs6000-protos.h
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/rs6000-power2-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/rs6000-power2-2.c [new file with mode: 0644]

index cc665a4d1d67c60471391d435a6afe55afc7e4c7..176ca3801baa96a27da64fd3374eda6126befa6c 100644 (file)
@@ -1,3 +1,18 @@
+2004-04-28  Andrew Pinski  <pinskia@physics.uc.edu>
+
+       * config/rs6000/rs6000.c (registers_ok_for_quad_peep):
+       Return false if we do not have fp register.
+       (addrs_ok_for_quad_peep): Rename to ...
+       (mems_ok_for_quad_peep): this.
+       Add check for volatile memory.
+       * config/rs6000/rs6000-protos.h (addrs_ok_for_quad_peep):
+       Rename to ...
+       (mems_ok_for_quad_peep): this.
+       * config/rs6000/rs6000.md: Change peephole's for lfq/stq
+       to peephole2's.
+       (lfq_power2): New instruction.
+       (stfq_power2): Likewise.
+
 2004-04-28  Jan Hubicka  <jh@suse.cz>
 
        PR c/15004
index 57e8886b391f5812e87498700ba2728ea4767c81..d368033d7906dd2af14e148e03f9be93e2d2a2ca 100644 (file)
@@ -102,7 +102,7 @@ extern int includes_rshift_p (rtx, rtx);
 extern int includes_rldic_lshift_p (rtx, rtx);
 extern int includes_rldicr_lshift_p (rtx, rtx);
 extern int registers_ok_for_quad_peep (rtx, rtx);
-extern int addrs_ok_for_quad_peep (rtx, rtx);
+extern int mems_ok_for_quad_peep (rtx, rtx);
 extern bool gpr_or_gpr_p (rtx, rtx);
 extern enum reg_class secondary_reload_class (enum reg_class,
                                              enum machine_mode, rtx);
index 715324ee25a95a7f56ed4f34a542d648b33ed949..7195805b18e4d4a4f734a3f61ca4c150c66ce860 100644 (file)
@@ -8594,10 +8594,7 @@ includes_rldicr_lshift_p (rtx shiftop, rtx andop)
 }
 
 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
-   for lfq and stfq insns.
-
-   Note reg1 and reg2 *must* be hard registers.  To be sure we will
-   abort if we are passed pseudo registers.  */
+   for lfq and stfq insns iff the registers are hard registers.   */
 
 int
 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
@@ -8605,6 +8602,11 @@ registers_ok_for_quad_peep (rtx reg1, rtx reg2)
   /* We might have been passed a SUBREG.  */
   if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG) 
     return 0;
+    
+  /* We might have been passed non floating point registers.  */
+  if (!FP_REGNO_P (REGNO (reg1))
+      || !FP_REGNO_P (REGNO (reg2)))
+    return 0;
 
   return (REGNO (reg1) == REGNO (reg2) - 1);
 }
@@ -8614,11 +8616,19 @@ registers_ok_for_quad_peep (rtx reg1, rtx reg2)
    (addr2 == addr1 + 8).  */
 
 int
-addrs_ok_for_quad_peep (rtx addr1, rtx addr2)
+mems_ok_for_quad_peep (rtx mem1, rtx mem2)
 {
+  rtx addr1, addr2;
   unsigned int reg1;
   int offset1;
 
+  /* The mems cannot be volatile.  */
+  if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
+    return 0;
+  
+  addr1 = XEXP (mem1, 0);
+  addr2 = XEXP (mem2, 0);
+
   /* Extract an offset (if used) from the first addr.  */
   if (GET_CODE (addr1) == PLUS)
     {
index c1dabf888b3991d2e8190c61f53172dc313f3681..d93b80a8456282e0c5b2653305077fbb677b8179 100644 (file)
 
 ;; Peephole to convert two consecutive FP loads or stores into lfq/stfq.
 
-(define_peephole
-  [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
+(define_insn "*lfq_power2"
+  [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
+       (match_operand:TF 1 "memory_operand" ""))]
+  "TARGET_POWER2
+   && TARGET_HARD_FLOAT && TARGET_FPRS"
+   "lfq%U1%X1 %0,%1")
+
+(define_peephole2
+  [(set (match_operand:DF 0 "gpc_reg_operand" "")
        (match_operand:DF 1 "memory_operand" ""))
-   (set (match_operand:DF 2 "gpc_reg_operand" "=f")
+   (set (match_operand:DF 2 "gpc_reg_operand" "")
        (match_operand:DF 3 "memory_operand" ""))]
   "TARGET_POWER2
    && TARGET_HARD_FLOAT && TARGET_FPRS
    && registers_ok_for_quad_peep (operands[0], operands[2])
-   && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
-   && addrs_ok_for_quad_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
-  "lfq%U1%X1 %0,%1")
+   && mems_ok_for_quad_peep (operands[1], operands[3])"
+  [(set (match_dup 0)
+        (match_dup 1))]
+  "operands[1] = widen_memory_access (operands[1], TFmode, 0);
+   operands[0] = gen_rtx_REG (TFmode, REGNO (operands[0]));")
 
-(define_peephole
+(define_insn "*stfq_power2"
+  [(set (match_operand:TF 0 "memory_operand" "")
+       (match_operand:TF 1 "gpc_reg_operand" "f"))]
+  "TARGET_POWER2
+   && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "stfq%U0%X0 %1,%0")
+
+
+(define_peephole2
   [(set (match_operand:DF 0 "memory_operand" "")
-       (match_operand:DF 1 "gpc_reg_operand" "f"))
+       (match_operand:DF 1 "gpc_reg_operand" ""))
    (set (match_operand:DF 2 "memory_operand" "")
-       (match_operand:DF 3 "gpc_reg_operand" "f"))]
+       (match_operand:DF 3 "gpc_reg_operand" ""))]
   "TARGET_POWER2
    && TARGET_HARD_FLOAT && TARGET_FPRS
    && registers_ok_for_quad_peep (operands[1], operands[3])
-   && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
-   && addrs_ok_for_quad_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
-  "stfq%U0%X0 %1,%0")
+   && mems_ok_for_quad_peep (operands[0], operands[2])"
+  [(set (match_dup 0)
+       (match_dup 1))]
+  "operands[0] = widen_memory_access (operands[0], TFmode, 0);
+   operands[1] = gen_rtx_REG (TFmode, REGNO (operands[1]));")
 \f
 ;; TLS support.
 
index 1de727de43ebb356128cee72f3628e37dcf88a98..87f7a59535b7d7ee524f8a17e06eb12ceea6924a 100644 (file)
@@ -1,3 +1,8 @@
+2004-04-28  Andrew Pinski  <pinskia@physics.uc.edu>
+
+       * gcc.dg/rs6000-power2-1.c: New test.
+       * gcc.dg/rs6000-power2-2.c: New test.
+
 2004-04-28  Jan Hubicka  <jh@suse.cz>
 
        * gcc.dg/unused-6.c: New test.
diff --git a/gcc/testsuite/gcc.dg/rs6000-power2-1.c b/gcc/testsuite/gcc.dg/rs6000-power2-1.c
new file mode 100644 (file)
index 0000000..7f22b98
--- /dev/null
@@ -0,0 +1,21 @@
+/* { dg-do assemble { target powerpc-*-* rs6000-*-* }  } */
+/* { dg-options "-O -mpower2 -fno-schedule-insns -w" } */
+/* This used to ICE as the peephole was not checking to see
+   if the register is a floating point one (I think this cannot
+   happen in real life except in this example).  */
+
+register double t1 __asm__("r14");
+register double t2 __asm__("r15");
+register double t3 __asm__("r16"), t4 __asm__("r17");
+void t(double *a, double *b)
+{
+        t1 = a[-1];
+        t2 = a[0];
+        t3 = a[1];
+        t4 = a[2];
+        b[-1] = t1;
+        b[0] = t2;
+        b[1] = t3;
+        b[2] = t4;
+}
+
diff --git a/gcc/testsuite/gcc.dg/rs6000-power2-2.c b/gcc/testsuite/gcc.dg/rs6000-power2-2.c
new file mode 100644 (file)
index 0000000..dda4852
--- /dev/null
@@ -0,0 +1,22 @@
+/* { dg-do assemble { target powerpc-*-* rs6000-*-* }  } */
+/* { dg-options "-O -mpower2 -fno-schedule-insns" } */
+/* { dg-final { scan-assembler-not "lfd" } } */
+/* { dg-final { scan-assembler-not "sfd" } } */
+/* { dg-final { scan-assembler "lfq" } } */
+/* { dg-final { scan-assembler "sfq" } } */
+
+register double t1 __asm__("f0");
+register double t2 __asm__("f1");
+register double t3 __asm__("f2"), t4 __asm__("f3");
+void t(double *a, double *b)
+{
+        t1 = a[-1];
+        t2 = a[0];
+        t3 = a[1];
+        t4 = a[2];
+        b[-1] = t1;
+        b[0] = t2;
+        b[1] = t3;
+        b[2] = t4;
+}
+