===================================================================
@@ -3113,12 +3113,55 @@
;; 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 @@
"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")
===================================================================
@@ -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"
===================================================================
@@ -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")