This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH, committed] eq SCC splitter
- From: David Edelsohn <dje at watson dot ibm dot com>
- To: Richard Henderson <rth at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Thu, 09 Jun 2005 15:02:11 -0400
- Subject: Re: [PATCH, committed] eq SCC splitter
- References: <20050608184747.GE10978@redhat.com>
>>>>> 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")