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]
Other format: [Raw text]

Re: [PATCH, committed] eq SCC splitter


>>>>> Richard Henderson writes:

> Also, why would you bother splitting out the one case of x == 0,
> when all of the other cases are ((x ^ y) == 0)?

	Appended is the followup patch that I am finishing up testing with
no regressions so far.  The comparison is implemented with both XOR and
MINUS (as in the original patterns) because the instructions accept a
slightly different range of useful immediate constants.

	Does this look like what you had in mind?

David

	* config/rs6000/rs6000.md (eq): Convert to define_insn_and_split.
	* config/rs6000/predicates.md (scc_eq_operand): New.

Index: rs6000.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.376
diff -c -p -r1.376 rs6000.md
*** rs6000.md	8 Jun 2005 14:46:09 -0000	1.376
--- rs6000.md	9 Jun 2005 13:57:13 -0000
***************
*** 11468,11620 ****
  ;; otherwise won't accept constants.  We do this because it is faster than
  ;; the cmp/mfcr sequence we would otherwise generate.
  
! (define_insn ""
!   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
! 	(eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
! 	       (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,L,I")))
!    (clobber (match_scratch:SI 3 "=r,X,r,r,r"))]
!   "TARGET_32BIT"
!   "@
!    xor %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0
!    #
!    {xoril|xori} %0,%1,%b2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0
!    {xoriu|xoris} %0,%1,%u2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0
!    {sfi|subfic} %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0"
!   [(set_attr "type" "three,two,three,three,three")
!    (set_attr "length" "12,8,12,12,12")])
! 
! (define_insn ""
!   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r")
! 	(eq:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r")
! 	       (match_operand:DI 2 "reg_or_cint_operand" "r,O,K,J,I")))
!    (clobber (match_scratch:DI 3 "=r,X,r,r,r"))]
!   "TARGET_64BIT"
!   "@
!    xor %0,%1,%2\;subfic %3,%0,0\;adde %0,%3,%0
!    #
!    xori %0,%1,%b2\;subfic %3,%0,0\;adde %0,%3,%0
!    xoris %0,%1,%u2\;subfic %3,%0,0\;adde %0,%3,%0
!    subfic %0,%1,%2\;subfic %3,%0,0\;adde %0,%3,%0"
!   [(set_attr "type" "three,two,three,three,three")
!    (set_attr "length" "12,8,12,12,12")])
! 
! (define_split
!   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
! 	(eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
! 	       (match_operand:GPR 2 "zero_constant" "")))
!    (clobber (match_scratch:GPR 3 ""))]
    ""
!   [(set (match_dup 0)
! 	(clz:GPR (match_dup 1)))
     (set (match_dup 0)
! 	(lshiftrt:GPR (match_dup 0) (match_dup 4)))]
    {
!     operands[4] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
!   })
! 
! (define_insn ""
!   [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,x,x,x,?y,?y,?y,?y,?y")
! 	(compare:CC
! 	 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r")
! 		(match_operand:SI 2 "reg_or_cint_operand" "r,O,K,L,I,r,O,K,L,I"))
! 	 (const_int 0)))
!    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r,r,r")
! 	(eq:SI (match_dup 1) (match_dup 2)))
!    (clobber (match_scratch:SI 3 "=r,X,r,r,r,r,X,r,r,r"))]
!   "TARGET_32BIT"
!   "@
!    xor %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
!    #
!    {xoril|xori} %0,%1,%b2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
!    {xoriu|xoris} %0,%1,%u2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
!    {sfi|subfic} %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
!    #
!    #
!    #
!    #
!    #"
!   [(set_attr "type" "compare")
!    (set_attr "length" "12,8,12,12,12,16,12,16,16,16")])
  
! (define_split
!   [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
! 	(compare:CC
! 	 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "")
! 		(match_operand:SI 2 "reg_or_cint_operand" ""))
! 	 (const_int 0)))
!    (set (match_operand:SI 0 "gpc_reg_operand" "")
! 	(eq:SI (match_dup 1) (match_dup 2)))
!    (clobber (match_scratch:SI 3 ""))]
!   "TARGET_32BIT && reload_completed"
!   [(parallel [(set (match_dup 0)
! 	(eq:SI (match_dup 1) (match_dup 2)))
!    (clobber (match_dup 3))])
!    (set (match_dup 4)
! 	(compare:CC (match_dup 0)
! 		    (const_int 0)))]
!   "")
! 
! (define_insn ""
!   [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,x,x,x,?y,?y,?y,?y,?y")
! 	(compare:CC
! 	 (eq:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r")
! 		(match_operand:DI 2 "reg_or_cint_operand" "r,O,K,J,I,r,O,K,J,I"))
! 	 (const_int 0)))
!    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r,r,r")
! 	(eq:DI (match_dup 1) (match_dup 2)))
!    (clobber (match_scratch:DI 3 "=r,X,r,r,r,r,X,r,r,r"))]
!   "TARGET_64BIT"
!   "@
!    xor %0,%1,%2\;subfic %3,%0,0\;adde. %0,%3,%0
!    #
!    xori %0,%1,%b2\;subfic %3,%0,0\;adde. %0,%3,%0
!    xoris %0,%1,%u2\;subfic %3,%0,0\;adde. %0,%3,%0
!    subfic %0,%1,%2\;subfic %3,%0,0\;adde. %0,%3,%0
!    #
!    #
!    #
!    #
!    #"
!   [(set_attr "type" "compare")
!    (set_attr "length" "12,8,12,12,12,16,12,16,16,16")])
! 
! (define_split
!   [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
! 	(compare:CC
! 	 (eq:DI (match_operand:DI 1 "gpc_reg_operand" "")
! 		(match_operand:DI 2 "reg_or_cint_operand" ""))
! 	 (const_int 0)))
!    (set (match_operand:DI 0 "gpc_reg_operand" "")
! 	(eq:DI (match_dup 1) (match_dup 2)))
!    (clobber (match_scratch:DI 3 ""))]
!   "TARGET_64BIT && reload_completed"
!   [(parallel [(set (match_dup 0)
! 	(eq:DI (match_dup 1) (match_dup 2)))
!    (clobber (match_dup 3))])
!    (set (match_dup 4)
! 	(compare:CC (match_dup 0)
! 		    (const_int 0)))]
!   "")
  
! (define_split
!   [(set (match_operand:CC 4 "cc_reg_operand" "")
  	(compare:CC
! 	 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
! 		 (match_operand:GPR 2 "zero_constant" ""))
  	 (const_int 0)))
!    (set (match_operand:GPR 0 "gpc_reg_operand" "")
  	(eq:GPR (match_dup 1) (match_dup 2)))
!    (clobber (match_scratch:GPR 3 ""))]
    ""
!   [(set (match_dup 0)
! 	(clz:GPR (match_dup 1)))
!    (parallel [(set (match_dup 4)
! 		   (compare:CC (lshiftrt:GPR (match_dup 0) (match_dup 5))
  			       (const_int 0)))
  	      (set (match_dup 0)
! 		   (lshiftrt:GPR (match_dup 0) (match_dup 5)))])]
    {
!     operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
    })
  
  ;; We have insns of the form shown by the first define_insn below.  If
--- 11468,11542 ----
  ;; otherwise won't accept constants.  We do this because it is faster than
  ;; the cmp/mfcr sequence we would otherwise generate.
  
! (define_insn_and_split "*eq<mode>"
!   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
! 	(eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
! 		(match_operand:GPR 2 "scc_eq_operand" "ri")))
!    (clobber (match_scratch:GPR 3 "=r"))
!    (clobber (match_scratch:GPR 4 "=r"))]
    ""
!   "#"
!   "reload_completed"
!   [(set (match_dup 3)
! 	(clz:GPR (match_dup 4)))
     (set (match_dup 0)
! 	(lshiftrt:GPR (match_dup 3) (match_dup 5)))]
    {
!     if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)
!       {
! 	if (logical_operand (operands[2], <MODE>mode))
! 	  emit_insn (gen_rtx_SET (VOIDmode, operands[4],
! 				  gen_rtx_XOR (<MODE>mode,
! 					       operands[1], operands[2])));
! 	else
! 	  emit_insn (gen_rtx_SET (VOIDmode, operands[4],
! 				  gen_rtx_PLUS (<MODE>mode, operands[1],
! 						negate_rtx (<MODE>mode,
! 							    operands[2]))));
!       }
!     else
!       operands[4] = operands[1];
  
!     operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
!   })
  
! (define_insn_and_split "*eq<mode>_compare"
!   [(set (match_operand:CC 5 "cc_reg_operand" "=y")
  	(compare:CC
! 	 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "=r")
! 		 (match_operand:GPR 2 "scc_eq_operand" "ri"))
  	 (const_int 0)))
!    (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
  	(eq:GPR (match_dup 1) (match_dup 2)))
!    (clobber (match_scratch:GPR 3 "=r"))
!    (clobber (match_scratch:GPR 4 "=r"))]
    ""
!   "#"
!   "reload_completed"
!   [(set (match_dup 3)
! 	(clz:GPR (match_dup 4)))
!    (parallel [(set (match_dup 5)
! 		   (compare:CC (lshiftrt:GPR (match_dup 3) (match_dup 6))
  			       (const_int 0)))
  	      (set (match_dup 0)
! 		   (lshiftrt:GPR (match_dup 3) (match_dup 6)))])]
    {
!     if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)
!       {
! 	if (logical_operand (operands[2], <MODE>mode))
! 	  emit_insn (gen_rtx_SET (VOIDmode, operands[4],
! 				  gen_rtx_XOR (<MODE>mode,
! 					       operands[1], operands[2])));
! 	else
! 	  emit_insn (gen_rtx_SET (VOIDmode, operands[4],
! 				  gen_rtx_PLUS (<MODE>mode, operands[1],
! 						negate_rtx (<MODE>mode,
! 							    operands[2]))));
!       }
!     else
!       operands[4] = operands[1];
! 
!     operands[6] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
    })
  
  ;; We have insns of the form shown by the first define_insn below.  If
Index: predicates.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/predicates.md,v
retrieving revision 1.15
diff -c -p -r1.15 predicates.md
*** predicates.md	18 May 2005 20:35:53 -0000	1.15
--- predicates.md	9 Jun 2005 13:57:13 -0000
***************
*** 551,556 ****
--- 551,561 ----
  	 (match_operand 0 "gpc_reg_operand")
  	 (match_operand 0 "logical_operand"))))
  
+ ;; Return 1 if the operand is either a logical operand or a short cint operand.
+ (define_predicate "scc_eq_operand"
+   (ior (match_operand 0 "logical_operand")
+        (match_operand 0 "short_cint_operand")))
+ 
  ;; Return 1 if the operand is a general non-special register or memory operand.
  (define_predicate "reg_or_mem_operand"
    (if_then_else (match_code "mem")


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