This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

SPARC: convert text peepholes to RTL peepholes



The subject says it all. 


Straight forward for the ldd/std peepholes, just generate the correct
rtl. 
The compare and move and the store zero peepholes needed new
define_insns to emit those instructions. 

In movdi I made the code match the comments.

The call/return peepholes are used to fill the delay slot, and there's
not much we can do about it...

Thanks to Richard Henderson for his quick and precise answers to all
the questions I had while working on this. 

Here's the patch, bootstraped on sparc-sun-solaris2.8 a few days ago.

2001-09-11  Dan Nicolaescu  <dann@ics.uci.edu>

	* 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.	
	* config/sparc/sparc.c (addrs_ok_for_ldd_peep): Allow the use of
	any register based on the alignment info.
	
Index: sparc.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sparc/sparc.md,v
retrieving revision 1.132
diff -c -3 -p -c -r1.132 sparc.md
*** sparc.md	2001/09/04 13:10:26	1.132
--- sparc.md	2001/09/11 08:26:26
***************
*** 2383,2389 ****
  	 The const zero case is more complex, on v9
  	 we can always perform it.  */
        if (register_operand (operands[1], DImode)
! 	  || (TARGET_ARCH64
                && (operands[1] == const0_rtx)))
          goto movdi_is_ok;
  
--- 2383,2389 ----
  	 The const zero case is more complex, on v9
  	 we can always perform it.  */
        if (register_operand (operands[1], DImode)
! 	  || (TARGET_V9
                && (operands[1] == const0_rtx)))
          goto movdi_is_ok;
  
***************
*** 2431,2437 ****
    /* This makes sure we will not get rematched due to splittage. */
    if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
      ;
!   else if (TARGET_ARCH64
  	   && CONSTANT_P (operands[1])
             && GET_CODE (operands[1]) != HIGH
             && GET_CODE (operands[1]) != LO_SUM)
--- 2431,2437 ----
    /* This makes sure we will not get rematched due to splittage. */
    if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
      ;
!   else if (TARGET_V9
  	   && CONSTANT_P (operands[1])
             && GET_CODE (operands[1]) != HIGH
             && GET_CODE (operands[1]) != LO_SUM)
***************
*** 2444,2449 ****
--- 2444,2456 ----
    ;
  }")
  
+ (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.
***************
*** 7266,7271 ****
--- 7273,7305 ----
    "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_operand:SI 2 "register_operand" "r")
+ 		    (const_int 0)))]
+   "(rtx_equal_p (operands[2], operands[0])
+     || rtx_equal_p (operands[2], operands[1]))
+     && ! SPARC_FP_REG_P (REGNO (operands[0]))
+     && ! SPARC_FP_REG_P (REGNO (operands[1]))"
+   "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_operand:DI 2 "register_operand" "r")
+ 		    (const_int 0)))]
+   "TARGET_ARCH64
+    && (rtx_equal_p (operands[2], operands[0])
+        || rtx_equal_p (operands[2], operands[1]))
+    && ! SPARC_FP_REG_P (REGNO (operands[0]))
+    && ! SPARC_FP_REG_P (REGNO (operands[1]))"
+   "orcc\\t%1, 0, %0"
+    [(set_attr "type" "compare")])
  
  ;; Floating point arithmetic instructions.
  
***************
*** 8949,8955 ****
  ;; 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
    [(set (match_operand:SI 0 "memory_operand" "")
        (const_int 0))
     (set (match_operand:SI 1 "memory_operand" "")
--- 8983,8989 ----
  ;; The conditions in which we do this are very restricted and are 
  ;; explained in the code for {registers,memory}_ok_for_ldd functions.
  
! (define_peephole2
    [(set (match_operand:SI 0 "memory_operand" "")
        (const_int 0))
     (set (match_operand:SI 1 "memory_operand" "")
***************
*** 8958,8966 ****
     && ! 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")
  
! (define_peephole
    [(set (match_operand:SI 0 "memory_operand" "")
        (const_int 0))
     (set (match_operand:SI 1 "memory_operand" "")
--- 8992,9002 ----
     && ! MEM_VOLATILE_P (operands[0])
     && ! MEM_VOLATILE_P (operands[1])
     && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[1], 0))"
!   [(set (match_dup 0)
!        (const_int 0))]
!   "operands[0] = change_address (operands[0], DImode, NULL);")
  
! (define_peephole2
    [(set (match_operand:SI 0 "memory_operand" "")
        (const_int 0))
     (set (match_operand:SI 1 "memory_operand" "")
***************
*** 8969,9092 ****
     && ! 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")
  
! (define_peephole
!   [(set (match_operand:SI 0 "register_operand" "=rf")
          (match_operand:SI 1 "memory_operand" ""))
!    (set (match_operand:SI 2 "register_operand" "=rf")
          (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")
  
! (define_peephole
    [(set (match_operand:SI 0 "memory_operand" "")
!         (match_operand:SI 1 "register_operand" "rf"))
     (set (match_operand:SI 2 "memory_operand" "")
!         (match_operand:SI 3 "register_operand" "rf"))]
    "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")
          (match_operand:SF 1 "memory_operand" ""))
!    (set (match_operand:SF 2 "register_operand" "=fr")
          (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")
  
! (define_peephole
    [(set (match_operand:SF 0 "memory_operand" "")
!         (match_operand:SF 1 "register_operand" "fr"))
     (set (match_operand:SF 2 "memory_operand" "")
!         (match_operand:SF 3 "register_operand" "fr"))]
    "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:SI 0 "register_operand" "=rf")
          (match_operand:SI 1 "memory_operand" ""))
!    (set (match_operand:SI 2 "register_operand" "=rf")
          (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")
  
! (define_peephole
    [(set (match_operand:SI 0 "memory_operand" "")
!         (match_operand:SI 1 "register_operand" "rf"))
     (set (match_operand:SI 2 "memory_operand" "")
!         (match_operand:SI 3 "register_operand" "rf"))]
    "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")
   
! (define_peephole
!   [(set (match_operand:SF 0 "register_operand" "=fr")
          (match_operand:SF 1 "memory_operand" ""))
!    (set (match_operand:SF 2 "register_operand" "=fr")
          (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")
  
! (define_peephole
    [(set (match_operand:SF 0 "memory_operand" "")
!         (match_operand:SF 1 "register_operand" "fr"))
     (set (match_operand:SF 2 "memory_operand" "")
!         (match_operand:SF 3 "register_operand" "fr"))]
    "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")
   
  ;; 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"))
     (set (reg:CC 100)
! 	(compare:CC (match_operand:SI 2 "register_operand" "r")
  		    (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")
  
! (define_peephole
!   [(set (match_operand:DI 0 "register_operand" "=r")
! 	(match_operand:DI 1 "register_operand" "r"))
     (set (reg:CCX 100)
! 	(compare:CCX (match_operand:DI 2 "register_operand" "r")
  		    (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")
  
  ;; Return peepholes.  First the "normal" ones.
  ;; These are necessary to catch insns ending up in the epilogue delay list.
--- 9005,9161 ----
     && ! MEM_VOLATILE_P (operands[0])
     && ! MEM_VOLATILE_P (operands[1])
     && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[0], 0))"
!   [(set (match_dup 1)
!        (const_int 0))]
!   "operands[1] = change_address (operands[1], DImode, NULL);")
  
! (define_peephole2
!   [(set (match_operand:SI 0 "register_operand" "")
          (match_operand:SI 1 "memory_operand" ""))
!    (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))" 
!   [(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_peephole2
    [(set (match_operand:SI 0 "memory_operand" "")
!         (match_operand:SI 1 "register_operand" ""))
     (set (match_operand:SI 2 "memory_operand" "")
!         (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))"
!   [(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" "")
          (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))"
!   [(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_peephole2
    [(set (match_operand:SF 0 "memory_operand" "")
!         (match_operand:SF 1 "register_operand" ""))
     (set (match_operand:SF 2 "memory_operand" "")
!         (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))"
!   [(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_peephole2
!   [(set (match_operand:SI 0 "register_operand" "")
          (match_operand:SI 1 "memory_operand" ""))
!    (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))"
!   [(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_peephole2
    [(set (match_operand:SI 0 "memory_operand" "")
!         (match_operand:SI 1 "register_operand" ""))
     (set (match_operand:SI 2 "memory_operand" "")
!         (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))" 
!   [(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_peephole2
!   [(set (match_operand:SF 0 "register_operand" "")
          (match_operand:SF 1 "memory_operand" ""))
!    (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))"
!   [(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_peephole2
    [(set (match_operand:SF 0 "memory_operand" "")
!         (match_operand:SF 1 "register_operand" ""))
     (set (match_operand:SF 2 "memory_operand" "")
!         (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))"
!   [(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_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" "")
  		    (const_int 0)))]
    "(rtx_equal_p (operands[2], operands[0])
      || rtx_equal_p (operands[2], operands[1]))
!     && ! 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_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" "")
  		    (const_int 0)))]
    "TARGET_ARCH64
     && (rtx_equal_p (operands[2], operands[0])
         || rtx_equal_p (operands[2], operands[1]))
!    && ! 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.

Index: sparc.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sparc/sparc.c,v
retrieving revision 1.153
diff -c -3 -p -c -r1.153 sparc.c
*** sparc.c	2001/09/04 10:43:46	1.153
--- sparc.c	2001/09/11 08:29:01
*************** int
*** 5676,5682 ****
  addrs_ok_for_ldd_peep (addr1, addr2)
        rtx addr1, addr2;
  {
!   unsigned int reg1;
    int offset1;
  
    /* Extract a register number and offset (if used) from the first addr.  */
--- 5676,5682 ----
  addrs_ok_for_ldd_peep (addr1, addr2)
        rtx addr1, addr2;
  {
!   rtx reg1_rtx;
    int offset1;
  
    /* Extract a register number and offset (if used) from the first addr.  */
*************** addrs_ok_for_ldd_peep (addr1, addr2)
*** 5687,5693 ****
  	return 0;
        else
  	{
!           reg1 = REGNO (XEXP (addr1, 0));
  	  /* The offset must be constant!  */
  	  if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
              return 0;
--- 5687,5693 ----
  	return 0;
        else
  	{
!           reg1_rtx = XEXP (addr1, 0);
  	  /* The offset must be constant!  */
  	  if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
              return 0;
*************** addrs_ok_for_ldd_peep (addr1, addr2)
*** 5698,5704 ****
      return 0;
    else
      {
!       reg1 = REGNO (addr1);
        /* This was a simple (mem (reg)) expression.  Offset is 0.  */
        offset1 = 0;
      }
--- 5698,5704 ----
      return 0;
    else
      {
!       reg1_rtx = addr1;
        /* This was a simple (mem (reg)) expression.  Offset is 0.  */
        offset1 = 0;
      }
*************** addrs_ok_for_ldd_peep (addr1, addr2)
*** 5711,5722 ****
        || 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;
  
    /* The first offset must be evenly divisible by 8 to ensure the 
--- 5711,5722 ----
        || GET_CODE (XEXP (addr2, 1)) != CONST_INT)
      return 0;
  
!   /* The addresses have to be 64 bit aligned.  Additionally both
!      addresses must use the same register.  */
!   if (REGNO_POINTER_ALIGN (ORIGINAL_REGNO (reg1_rtx)) < 8)
      return 0;
  
!   if (REGNO (reg1_rtx) != REGNO (XEXP (addr2, 0)))
      return 0;
  
    /* The first offset must be evenly divisible by 8 to ensure the 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]