predicates.md (logical_and_operand): New predicate.

* config/sh/predicates.md (logical_and_operand): New predicate.
	* config/sh/constraints.md (Jmb, Jmw): New constraints.
	* config/sh/sh.md (andsi3): Move expander above insns.  Add handling
	of 0xFFFF constant.  Use logical_and_operand predicate and
	satisfies_constraint_Jmb, satisfies_constraint_Jmw.
	(*andsi3_compact): Make it an insn_and_split.  Use
	logical_and_operand predicate.  Add Jmb,Jmw alternatives.

From-SVN: r189241
This commit is contained in:
Oleg Endo 2012-07-03 22:26:23 +00:00
parent c128d2031e
commit 5e204a6e8b
4 changed files with 85 additions and 23 deletions

View File

@ -1,3 +1,13 @@
2012-07-03 Oleg Endo <olegendo@gcc.gnu.org>
* config/sh/predicates.md (logical_and_operand): New predicate.
* config/sh/constraints.md (Jmb, Jmw): New constraints.
* config/sh/sh.md (andsi3): Move expander above insns. Add handling
of 0xFFFF constant. Use logical_and_operand predicate and
satisfies_constraint_Jmb, satisfies_constraint_Jmw.
(*andsi3_compact): Make it an insn_and_split. Use
logical_and_operand predicate. Add Jmb,Jmw alternatives.
2012-07-03 Jason Merrill <jason@redhat.com>
PR c++/53826

View File

@ -31,6 +31,8 @@
;; IJKLMNOP: CONT_INT constants
;; Ixx: signed xx bit
;; J16: 0xffffffff00000000 | 0x00000000ffffffff
;; Jmb: 0x000000FF
;; Jmw: 0x0000FFFF
;; Kxx: unsigned xx bit
;; M: 1
;; N: 0
@ -135,6 +137,16 @@
(and (match_code "const_int")
(match_test "CONST_OK_FOR_J16 (ival)")))
(define_constraint "Jmb"
"Low byte mask constant 0x000000FF"
(and (match_code "const_int")
(match_test "ival == 0xFF")))
(define_constraint "Jmw"
"Low word mask constant 0x0000FFFF"
(and (match_code "const_int")
(match_test "ival == 0xFFFF")))
(define_constraint "K03"
"An unsigned 3-bit constant, as used in SH2A bclr, bset, etc."
(and (match_code "const_int")

View File

@ -574,6 +574,21 @@
return 0;
})
;; Like logical_operand but allows additional constant values which can be
;; done with zero extensions. Used for the second operand of and insns.
(define_predicate "logical_and_operand"
(match_code "subreg,reg,const_int")
{
if (logical_operand (op, mode))
return 1;
if (! TARGET_SHMEDIA
&& (satisfies_constraint_Jmb (op) || satisfies_constraint_Jmw (op)))
return 1;
return 0;
})
;; TODO: Add a comment here.
(define_predicate "logical_operator"

View File

@ -3113,12 +3113,55 @@ label:
;; Logical operations
;; -------------------------------------------------------------------------
(define_insn "*andsi3_compact"
[(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
(and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
(match_operand:SI 2 "logical_operand" "K08,r")))]
(define_expand "andsi3"
[(set (match_operand:SI 0 "arith_reg_operand" "")
(and:SI (match_operand:SI 1 "logical_reg_operand" "")
(match_operand:SI 2 "logical_and_operand" "")))]
""
{
/* If it is possible to turn the and insn into a zero extension
already, redundant zero extensions will be folded, which results
in better code.
Ideally the splitter of *andsi_compact would be enough, if reundant
zero extensions were detected after the combine pass, which does not
happen at the moment. */
if (TARGET_SH1)
{
if (satisfies_constraint_Jmb (operands[2]))
{
emit_insn (gen_zero_extendqisi2 (operands[0],
gen_lowpart (QImode, operands[1])));
DONE;
}
else if (satisfies_constraint_Jmw (operands[2]))
{
emit_insn (gen_zero_extendhisi2 (operands[0],
gen_lowpart (HImode, operands[1])));
DONE;
}
}
})
(define_insn_and_split "*andsi_compact"
[(set (match_operand:SI 0 "arith_reg_dest" "=r,r,z,r")
(and:SI (match_operand:SI 1 "arith_reg_operand" "%r,r,0,0")
(match_operand:SI 2 "logical_and_operand" "Jmb,Jmw,K08,r")))]
"TARGET_SH1"
"and %2,%0"
"@
extu.b %1,%0
extu.w %1,%0
and %2,%0
and %2,%0"
"&& 1"
[(set (match_dup 0) (zero_extend:SI (match_dup 1)))]
{
if (satisfies_constraint_Jmb (operands[2]))
operands[1] = gen_lowpart (QImode, operands[1]);
else if (satisfies_constraint_Jmw (operands[2]))
operands[1] = gen_lowpart (HImode, operands[1]);
else
FAIL;
}
[(set_attr "type" "arith")])
(define_insn "*andsi3_media"
@ -3139,24 +3182,6 @@ label:
"bclr\\t%W2,%0"
[(set_attr "type" "arith")])
;; If the constant is 255, then emit an extu.b instruction instead of an
;; and, since that will give better code.
(define_expand "andsi3"
[(set (match_operand:SI 0 "arith_reg_operand" "")
(and:SI (match_operand:SI 1 "logical_reg_operand" "")
(match_operand:SI 2 "logical_operand" "")))]
""
{
if (TARGET_SH1
&& CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 255)
{
emit_insn (gen_zero_extendqisi2 (operands[0],
gen_lowpart (QImode, operands[1])));
DONE;
}
})
(define_insn_and_split "anddi3"
[(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
(and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")