#define CONSTANT_ADDRESS_P(X) CONSTANT_P (X)
/* Extra constraints. */
+#define OK_FOR_R(OP) \
+ (GET_CODE (OP) == MEM \
+ && GET_MODE (OP) == QImode \
+ && REG_P (XEXP (OP, 0)))
/* Q is used for sp + <something> in the {zero,sign}_extendpsisi2 patterns. */
#define EXTRA_CONSTRAINT(OP, C) \
- ((C) == 'S' ? GET_CODE (OP) == SYMBOL_REF : \
+ ((C) == 'R' ? OK_FOR_R (OP) : \
+ (C) == 'S' ? GET_CODE (OP) == SYMBOL_REF : \
(C) == 'Q' ? GET_CODE (OP) == PLUS : 0)
/* Maximum number of registers that can appear in a valid memory address. */
;; BIT INSTRUCTIONS
;; -----------------------------------------------------------------
-;; When clearing a set of bits in memory, we load the inverted bitmask into
-;; a register, then use bclr.
+;; These clears a constant set of bits in memory or in a register.
+;; We must support register destinations to make reload happy.
(define_insn ""
- [(set (match_operand:QI 0 "indirect_memory_operand" "")
+ [(set (match_operand:QI 0 "general_operand" "R,d")
(subreg:QI
(and:HI (subreg:HI (match_dup 0) 0)
(match_operand 1 "const_int_operand" "")) 0))
- (clobber (match_scratch:HI 2 "=&d"))]
+ (clobber (match_scratch:HI 2 "=&d,X"))]
""
- "mov %N1,%2\;bclr %2,%0"
+ "@
+ mov %N1,%2\;bclr %2,%0
+ and %1,%0"
[(set_attr "cc" "clobber")])
-;; These clear a non-constant set of bits in memory.
+;; This clears a variable set of bits in memory or in a register.
(define_insn ""
- [(set (match_operand:QI 0 "indirect_memory_operand" "")
+ [(set (match_operand:QI 0 "general_operand" "R,d")
(subreg:QI
(and:HI (subreg:HI (match_dup 0) 0)
- (not:HI (match_operand:HI 1 "general_operand" "d"))) 0))]
+ (not:HI (match_operand:HI 1 "general_operand" "d,d"))) 0))
+ (clobber (match_scratch:HI 2 "=X,&d"))]
""
- "bclr %1,%0"
+ "@
+ bclr %1,%0
+ mov %1,%2\;not %2\;and %2,%0"
[(set_attr "cc" "clobber")])
(define_insn ""
- [(set (match_operand:QI 0 "indirect_memory_operand" "")
+ [(set (match_operand:QI 0 "general_operand" "R,d")
(subreg:QI
- (and:HI (not:HI (match_operand:HI 1 "general_operand" "d"))
- (subreg:HI (match_dup 0) 0)) 0))]
+ (and:HI (not:HI (match_operand:HI 1 "general_operand" "d,d"))
+ (subreg:HI (match_dup 0) 0)) 0))
+ (clobber (match_scratch:HI 2 "=X,&d"))]
""
- "bclr %1,%0"
+ "@
+ bclr %1,%0
+ mov %1,%2\;not %2\;and %2,%0"
[(set_attr "cc" "clobber")])
;; These set bits in memory.
(define_insn ""
- [(set (match_operand:QI 0 "indirect_memory_operand" "")
+ [(set (match_operand:QI 0 "general_operand" "R,d")
(subreg:QI
(ior:HI (subreg:HI (match_dup 0) 0)
- (match_operand:HI 1 "general_operand" "d")) 0))]
+ (match_operand:HI 1 "general_operand" "d,d")) 0))]
""
- "bset %1,%0"
+ "@
+ bset %1,%0
+ or %1,%0"
[(set_attr "cc" "clobber")])
(define_insn ""
- [(set (match_operand:QI 0 "indirect_memory_operand" "")
+ [(set (match_operand:QI 0 "general_operand" "R,d")
(subreg:QI
- (ior:HI (match_operand:HI 1 "general_operand" "d")
+ (ior:HI (match_operand:HI 1 "general_operand" "d,d")
(subreg:HI (match_dup 0) 0)) 0))]
""
- "bset %1,%0"
+ "@
+ bset %1,%0
+ or %1,%0"
[(set_attr "cc" "clobber")])
;; Not any shorter/faster than using cmp, but it might save a