aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/config/sh/constraints.md12
-rw-r--r--gcc/config/sh/predicates.md15
-rw-r--r--gcc/config/sh/sh.md71
4 files changed, 85 insertions, 23 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9fcf3ca..f161d63 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/sh/constraints.md b/gcc/config/sh/constraints.md
index 6c9bc5e..8642ea8 100644
--- a/gcc/config/sh/constraints.md
+++ b/gcc/config/sh/constraints.md
@@ -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")
diff --git a/gcc/config/sh/predicates.md b/gcc/config/sh/predicates.md
index d58f657..3e7efd3 100644
--- a/gcc/config/sh/predicates.md
+++ b/gcc/config/sh/predicates.md
@@ -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"
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index 4e2425f..1dda194 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -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")