sparc.c (mems_ok_for_ldd_peep): Rename from addrs_ok_for_ldd_peep_withmem...
authorDan Nicolaescu <dann@ics.uci.edu>
Sun, 16 Dec 2001 02:26:58 +0000 (02:26 +0000)
committerRichard Henderson <rth@gcc.gnu.org>
Sun, 16 Dec 2001 02:26:58 +0000 (18:26 -0800)
        * config/sparc/sparc.c (mems_ok_for_ldd_peep): Rename from
        addrs_ok_for_ldd_peep_withmem; take MEMs as parameters, not
        addrs; eliminate restriction of only using fp and sp as base
        registers.
        * config/sparc/sparc-protos.h: Update.
        * config/sparc/sparc.md (movdi): Use TARGET_V9 not TARGET_ARCH64.
        (*cmp_cc_set, *cmp_ccx_set64, *movdi_zero): New insns derived
        from old define_peepholes.
        Convert all the ldd/std peepholes to peephole2.

From-SVN: r48059

gcc/ChangeLog
gcc/config/sparc/sparc-protos.h
gcc/config/sparc/sparc.c
gcc/config/sparc/sparc.md

index 7eba009..9cd09b9 100644 (file)
@@ -1,3 +1,15 @@
+2001-12-15  Dan Nicolaescu  <dann@ics.uci.edu>
+
+        * config/sparc/sparc.c (mems_ok_for_ldd_peep): Rename from
+       addrs_ok_for_ldd_peep_withmem; take MEMs as parameters, not
+        addrs; eliminate restriction of only using fp and sp as base
+        registers. 
+        * config/sparc/sparc-protos.h: Update.
+        * config/sparc/sparc.md (movdi): Use TARGET_V9 not TARGET_ARCH64.
+        (*cmp_cc_set, *cmp_ccx_set64, *movdi_zero): New insns derived
+        from old define_peepholes.
+        Convert all the ldd/std peepholes to peephole2.
+
 2001-12-15  Ulrich Weigand  <uweigand@de.ibm.com>
 
        * s390.md (prologue, epilogue, *return_si, *return_di): New.
index fe65829..7e0e1fc 100644 (file)
@@ -92,7 +92,7 @@ extern char *output_v9branch PARAMS ((rtx, int, int, int, int, int, rtx));
 extern void emit_v9_brxx_insn PARAMS ((enum rtx_code, rtx, rtx));
 extern void output_double_int PARAMS ((FILE *, rtx));
 extern void print_operand PARAMS ((FILE *, rtx, int));
-extern int addrs_ok_for_ldd_peep PARAMS ((rtx, rtx));
+extern int mems_ok_for_ldd_peep PARAMS ((rtx, rtx));
 extern int arith_double_4096_operand PARAMS ((rtx, enum machine_mode));
 extern int arith_4096_operand PARAMS ((rtx, enum machine_mode));
 extern int zero_operand PARAMS ((rtx, enum machine_mode));
index 2807add..48906d4 100644 (file)
@@ -5646,27 +5646,28 @@ registers_ok_for_ldd_peep (reg1, reg2)
   return (REGNO (reg1) == REGNO (reg2) - 1);
 }
 
-/* Return 1 if addr1 and addr2 are suitable for use in an ldd or 
-   std insn.
-
-   This can only happen when addr1 and addr2 are consecutive memory
-   locations (addr1 + 4 == addr2).  addr1 must also be aligned on a 
-   64 bit boundary (addr1 % 8 == 0).  
-
-   We know %sp and %fp are kept aligned on a 64 bit boundary.  Other
-   registers are assumed to *never* be properly aligned and are 
-   rejected.
-
-   Knowing %sp and %fp are kept aligned on a 64 bit boundary, we 
-   need only check that the offset for addr1 % 8 == 0.  */
+/* Return 1 if the addresses in mem1 and mem2 are suitable for use in
+   an ldd or std insn. 
+      
+   This can only happen when addr1 and addr2, the addresses in mem1
+   and mem2, are consecutive memory locations (addr1 + 4 == addr2).
+   addr1 must also be aligned on a 64-bit boundary.  */
 
 int
-addrs_ok_for_ldd_peep (addr1, addr2)
-      rtx addr1, addr2;
+mems_ok_for_ldd_peep (mem1, mem2)
+      rtx mem1, mem2;
 {
+  rtx addr1, addr2;
   unsigned int reg1;
   int offset1;
 
+  addr1 = XEXP (mem1, 0);
+  addr2 = XEXP (mem2, 0);
+
+  /* mem1 should be aligned on a 64-bit boundary */
+  if (MEM_ALIGN (mem1) < 64)
+    return 0;
+  
   /* Extract a register number and offset (if used) from the first addr.  */
   if (GET_CODE (addr1) == PLUS)
     {
@@ -5699,11 +5700,6 @@ addrs_ok_for_ldd_peep (addr1, addr2)
       || GET_CODE (XEXP (addr2, 1)) != CONST_INT)
     return 0;
 
-  /* Only %fp and %sp are allowed.  Additionally both addresses must
-     use the same register.  */
-  if (reg1 != FRAME_POINTER_REGNUM && reg1 != STACK_POINTER_REGNUM)
-    return 0;
-
   if (reg1 != REGNO (XEXP (addr2, 0)))
     return 0;
 
index fc3f10b..dde4156 100644 (file)
         The const zero case is more complex, on v9
         we can always perform it.  */
       if (register_operand (operands[1], DImode)
-         || (TARGET_ARCH64
+         || (TARGET_V9
               && (operands[1] == const0_rtx)))
         goto movdi_is_ok;
 
   ;
 }")
 
+(define_insn "*movdi_zero"
+  [(set (match_operand:DI 0 "memory_operand" "")
+       (const_int 0))]
+  "TARGET_V9"
+  "stx\\t%%g0, %0"
+  [(set_attr "type" "store")])
+
 ;; Be careful, fmovd does not exist when !arch64.
 ;; We match MEM moves directly when we have correct even
 ;; numbered registers, but fall into splits otherwise.
   "TARGET_ARCH64"
   "xnorcc\\t%%g0, %1, %0"
   [(set_attr "type" "compare")])
+
+(define_insn "*cmp_cc_set"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+       (match_operand:SI 1 "register_operand" "r"))
+   (set (reg:CC 100)
+       (compare:CC (match_dup 1)
+                   (const_int 0)))]
+  ""
+  "orcc\\t%1, 0, %0"
+  [(set_attr "type" "compare")])
+
+(define_insn "*cmp_ccx_set64"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (match_operand:DI 1 "register_operand" "r"))
+   (set (reg:CCX 100)
+       (compare:CCX (match_dup 1)
+                    (const_int 0)))]
+  "TARGET_ARCH64"
+  "orcc\\t%1, 0, %0"
+   [(set_attr "type" "compare")])
 \f
 ;; Floating point arithmetic instructions.
 
 ;; The conditions in which we do this are very restricted and are 
 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
 
-(define_peephole
+(define_peephole2
   [(set (match_operand:SI 0 "memory_operand" "")
       (const_int 0))
    (set (match_operand:SI 1 "memory_operand" "")
   "TARGET_V9
    && ! MEM_VOLATILE_P (operands[0])
    && ! MEM_VOLATILE_P (operands[1])
-   && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[1], 0))"
-  "stx\\t%%g0, %0")
+   && mems_ok_for_ldd_peep (operands[0], operands[1])"
+  [(set (match_dup 0)
+       (const_int 0))]
+  "operands[0] = change_address (operands[0], DImode, NULL);")
 
-(define_peephole
+(define_peephole2
   [(set (match_operand:SI 0 "memory_operand" "")
       (const_int 0))
    (set (match_operand:SI 1 "memory_operand" "")
   "TARGET_V9
    && ! MEM_VOLATILE_P (operands[0])
    && ! MEM_VOLATILE_P (operands[1])
-   && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[0], 0))"
-  "stx\\t%%g0, %1")
+   && mems_ok_for_ldd_peep (operands[1], operands[0])"
+  [(set (match_dup 1)
+       (const_int 0))]
+  "operands[1] = change_address (operands[1], DImode, NULL);")
 
-(define_peephole
-  [(set (match_operand:SI 0 "register_operand" "=rf")
+(define_peephole2
+  [(set (match_operand:SI 0 "register_operand" "")
         (match_operand:SI 1 "memory_operand" ""))
-   (set (match_operand:SI 2 "register_operand" "=rf")
+   (set (match_operand:SI 2 "register_operand" "")
         (match_operand:SI 3 "memory_operand" ""))]
   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
    && ! MEM_VOLATILE_P (operands[1])
    && ! MEM_VOLATILE_P (operands[3])
-   && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))" 
-  "ldd\\t%1, %0")
+   && mems_ok_for_ldd_peep (operands[1], operands[3])" 
+  [(set (match_dup 0)
+       (match_dup 1))]
+  "operands[1] = change_address (operands[1], DImode, NULL);
+   operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
 
-(define_peephole
+(define_peephole2
   [(set (match_operand:SI 0 "memory_operand" "")
-        (match_operand:SI 1 "register_operand" "rf"))
+        (match_operand:SI 1 "register_operand" ""))
    (set (match_operand:SI 2 "memory_operand" "")
-        (match_operand:SI 3 "register_operand" "rf"))]
+        (match_operand:SI 3 "register_operand" ""))]
   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
    && ! MEM_VOLATILE_P (operands[0])
    && ! MEM_VOLATILE_P (operands[2])
-   && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
-  "std\\t%1, %0")
-(define_peephole
-  [(set (match_operand:SF 0 "register_operand" "=fr")
+   && mems_ok_for_ldd_peep (operands[0], operands[2])"
+  [(set (match_dup 0)
+       (match_dup 1))]
+  "operands[0] = change_address (operands[0], DImode, NULL);
+   operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
+
+(define_peephole2
+  [(set (match_operand:SF 0 "register_operand" "")
         (match_operand:SF 1 "memory_operand" ""))
-   (set (match_operand:SF 2 "register_operand" "=fr")
+   (set (match_operand:SF 2 "register_operand" "")
         (match_operand:SF 3 "memory_operand" ""))]
   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
    && ! MEM_VOLATILE_P (operands[1])
    && ! MEM_VOLATILE_P (operands[3])
-   && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
-  "ldd\\t%1, %0")
+   && mems_ok_for_ldd_peep (operands[1], operands[3])"
+  [(set (match_dup 0)
+       (match_dup 1))]
+  "operands[1] = change_address (operands[1], DFmode, NULL);
+   operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
 
-(define_peephole
+(define_peephole2
   [(set (match_operand:SF 0 "memory_operand" "")
-        (match_operand:SF 1 "register_operand" "fr"))
+        (match_operand:SF 1 "register_operand" ""))
    (set (match_operand:SF 2 "memory_operand" "")
-        (match_operand:SF 3 "register_operand" "fr"))]
+        (match_operand:SF 3 "register_operand" ""))]
   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
   && ! MEM_VOLATILE_P (operands[0])
   && ! MEM_VOLATILE_P (operands[2])
-  && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
-  "std\\t%1, %0")
+  && mems_ok_for_ldd_peep (operands[0], operands[2])"
+  [(set (match_dup 0)
+       (match_dup 1))]
+  "operands[0] = change_address (operands[0], DFmode, NULL);
+   operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
 
-(define_peephole
-  [(set (match_operand:SI 0 "register_operand" "=rf")
+(define_peephole2
+  [(set (match_operand:SI 0 "register_operand" "")
         (match_operand:SI 1 "memory_operand" ""))
-   (set (match_operand:SI 2 "register_operand" "=rf")
+   (set (match_operand:SI 2 "register_operand" "")
         (match_operand:SI 3 "memory_operand" ""))]
   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
   && ! MEM_VOLATILE_P (operands[3])
   && ! MEM_VOLATILE_P (operands[1])
-  && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
-  "ldd\\t%3, %2")
+  && mems_ok_for_ldd_peep (operands[3], operands[1])"
+  [(set (match_dup 2)
+       (match_dup 3))]
+   "operands[3] = change_address (operands[3], DImode, NULL);
+    operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
 
-(define_peephole
+(define_peephole2
   [(set (match_operand:SI 0 "memory_operand" "")
-        (match_operand:SI 1 "register_operand" "rf"))
+        (match_operand:SI 1 "register_operand" ""))
    (set (match_operand:SI 2 "memory_operand" "")
-        (match_operand:SI 3 "register_operand" "rf"))]
+        (match_operand:SI 3 "register_operand" ""))]
   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
   && ! MEM_VOLATILE_P (operands[2])
   && ! MEM_VOLATILE_P (operands[0])
-  && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))" 
-  "std\\t%3, %2")
+  && mems_ok_for_ldd_peep (operands[2], operands[0])" 
+  [(set (match_dup 2)
+       (match_dup 3))]
+  "operands[2] = change_address (operands[2], DImode, NULL);
+   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
+   ")
  
-(define_peephole
-  [(set (match_operand:SF 0 "register_operand" "=fr")
+(define_peephole2
+  [(set (match_operand:SF 0 "register_operand" "")
         (match_operand:SF 1 "memory_operand" ""))
-   (set (match_operand:SF 2 "register_operand" "=fr")
+   (set (match_operand:SF 2 "register_operand" "")
         (match_operand:SF 3 "memory_operand" ""))]
   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
   && ! MEM_VOLATILE_P (operands[3])
   && ! MEM_VOLATILE_P (operands[1])
-  && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
-  "ldd\\t%3, %2")
+  && mems_ok_for_ldd_peep (operands[3], operands[1])"
+  [(set (match_dup 2)
+       (match_dup 3))]
+  "operands[3] = change_address (operands[3], DFmode, NULL);
+   operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
 
-(define_peephole
+(define_peephole2
   [(set (match_operand:SF 0 "memory_operand" "")
-        (match_operand:SF 1 "register_operand" "fr"))
+        (match_operand:SF 1 "register_operand" ""))
    (set (match_operand:SF 2 "memory_operand" "")
-        (match_operand:SF 3 "register_operand" "fr"))]
+        (match_operand:SF 3 "register_operand" ""))]
   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
   && ! MEM_VOLATILE_P (operands[2])
   && ! MEM_VOLATILE_P (operands[0])
-  && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
-  "std\\t%3, %2")
+  && mems_ok_for_ldd_peep (operands[2], operands[0])"
+  [(set (match_dup 2)
+       (match_dup 3))]
+  "operands[2] = change_address (operands[2], DFmode, NULL);
+   operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
  
 ;; Optimize the case of following a reg-reg move with a test
 ;; of reg just moved.  Don't allow floating point regs for operand 0 or 1.
 ;; This can result from a float to fix conversion.
 
-(define_peephole
-  [(set (match_operand:SI 0 "register_operand" "=r")
-       (match_operand:SI 1 "register_operand" "r"))
+(define_peephole2
+  [(set (match_operand:SI 0 "register_operand" "")
+       (match_operand:SI 1 "register_operand" ""))
    (set (reg:CC 100)
-       (compare:CC (match_operand:SI 2 "register_operand" "r")
+       (compare:CC (match_operand:SI 2 "register_operand" "")
                    (const_int 0)))]
   "(rtx_equal_p (operands[2], operands[0])
     || rtx_equal_p (operands[2], operands[1]))
-   && ! FP_REG_P (operands[0])
-   && ! FP_REG_P (operands[1])"
-  "orcc\\t%1, 0, %0")
+    && ! SPARC_FP_REG_P (REGNO (operands[0]))
+    && ! SPARC_FP_REG_P (REGNO (operands[1]))"
+  [(parallel [(set (match_dup 0) (match_dup 1))
+             (set (reg:CC 100)
+                  (compare:CC (match_dup 1) (const_int 0)))])]
+  "")
 
-(define_peephole
-  [(set (match_operand:DI 0 "register_operand" "=r")
-       (match_operand:DI 1 "register_operand" "r"))
+(define_peephole2
+  [(set (match_operand:DI 0 "register_operand" "")
+       (match_operand:DI 1 "register_operand" ""))
    (set (reg:CCX 100)
-       (compare:CCX (match_operand:DI 2 "register_operand" "r")
+       (compare:CCX (match_operand:DI 2 "register_operand" "")
                    (const_int 0)))]
   "TARGET_ARCH64
    && (rtx_equal_p (operands[2], operands[0])
        || rtx_equal_p (operands[2], operands[1]))
-   && ! FP_REG_P (operands[0])
-   && ! FP_REG_P (operands[1])"
-  "orcc\\t%1, 0, %0")
+   && ! SPARC_FP_REG_P (REGNO (operands[0]))
+   && ! SPARC_FP_REG_P (REGNO (operands[1]))"
+  [(parallel [(set (match_dup 0) (match_dup 1))
+             (set (reg:CCX 100)
+                  (compare:CC (match_dup 1) (const_int 0)))])]
+  "")
 
 ;; Return peepholes.  First the "normal" ones.
 ;; These are necessary to catch insns ending up in the epilogue delay list.