incdec_operand and eqne_operator.
* config/h8300/h8300.c (incdec_operand): New.
(eqne_operator): Likewise.
* config/h8300/h8300.h (CONST_OK_FOR_M): Likewise.
(CONST_OK_FOR_O): Likewise.
(CONST_OK_FOR_LETTER_P): Use CONST_OK_FOR_M and
CONST_OK_FOR_O.
* config/h8300/h8300.md (UNSPEC_INCDEC): New.
(addhi3_incdec): New.
(addsi3_incdec): Likewise.
(two peepholes): Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@60375
138bc75d-0d04-0410-961f-
82ee72b054a4
2002-12-20 Kazu Hirata <kazu@cs.umass.edu>
+ * config/h8300/h8300-protos.h: Add prototypes for
+ incdec_operand and eqne_operator.
+ * config/h8300/h8300.c (incdec_operand): New.
+ (eqne_operator): Likewise.
+ * config/h8300/h8300.h (CONST_OK_FOR_M): Likewise.
+ (CONST_OK_FOR_O): Likewise.
+ (CONST_OK_FOR_LETTER_P): Use CONST_OK_FOR_M and
+ CONST_OK_FOR_O.
+ * config/h8300/h8300.md (UNSPEC_INCDEC): New.
+ (addhi3_incdec): New.
+ (addsi3_incdec): Likewise.
+ (two peepholes): Likewise.
+
+2002-12-20 Kazu Hirata <kazu@cs.umass.edu>
+
* config/h8300/h8300.c (dosize): Remove warnings.
(print_operand): Likewise.
extern int jump_address_operand PARAMS ((rtx, enum machine_mode));
extern int bit_operand PARAMS ((rtx, enum machine_mode));
extern int bit_memory_operand PARAMS ((rtx, enum machine_mode));
+extern int incdec_operand PARAMS ((rtx, enum machine_mode));
extern int bit_operator PARAMS ((rtx, enum machine_mode));
extern int nshift_operator PARAMS ((rtx, enum machine_mode));
+extern int eqne_operator PARAMS ((rtx, enum machine_mode));
extern int h8300_eightbit_constant_address_p PARAMS ((rtx));
extern int h8300_tiny_constant_address_p PARAMS ((rtx));
}
}
+/* Return nonzero if X is a constant suitable for inc/dec. */
+
+int
+incdec_operand (x, mode)
+ rtx x;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+ return (GET_CODE (x) == CONST_INT
+ && (CONST_OK_FOR_M (INTVAL (x))
+ || CONST_OK_FOR_O (INTVAL (x))));
+}
+
+/* Return nonzero if X is either EQ or NE. */
+
+int
+eqne_operator (x, mode)
+ rtx x;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+ enum rtx_code code = GET_CODE (x);
+
+ return (code == EQ || code == NE);
+}
+
/* Recognize valid operators for bit instructions. */
int
(TARGET_H8300H || TARGET_H8300S \
? (VALUE) == 1 || (VALUE) == 2 || (VALUE) == 4 \
: (VALUE) == 1 || (VALUE) == 2)
+#define CONST_OK_FOR_M(VALUE) \
+ ((VALUE) == 1 || (VALUE) == 2)
#define CONST_OK_FOR_N(VALUE) \
(TARGET_H8300H || TARGET_H8300S \
? (VALUE) == -1 || (VALUE) == -2 || (VALUE) == -4 \
: (VALUE) == -1 || (VALUE) == -2)
+#define CONST_OK_FOR_O(VALUE) \
+ ((VALUE) == -1 || (VALUE) == -2)
#define CONST_OK_FOR_LETTER_P(VALUE, C) \
((C) == 'I' ? CONST_OK_FOR_I (VALUE) : \
(C) == 'J' ? CONST_OK_FOR_J (VALUE) : \
(C) == 'L' ? CONST_OK_FOR_L (VALUE) : \
+ (C) == 'M' ? CONST_OK_FOR_M (VALUE) : \
(C) == 'N' ? CONST_OK_FOR_N (VALUE) : \
+ (C) == 'O' ? CONST_OK_FOR_O (VALUE) : \
0)
/* Similar, but for floating constants, and defining letters G and H.
;; ----------------------------------------------------------------------
(define_constants
+ [(UNSPEC_INCDEC 0)])
+
+(define_constants
[(SC_REG 3)
(FP_REG 6)
(SP_REG 7)
[(set_attr "length" "2,2,2,4,2")
(set_attr "cc" "none_0hit,none_0hit,clobber,set_zn,set_zn")])
+(define_insn "addhi3_incdec"
+ [(set (match_operand:HI 0 "register_operand" "=r,r")
+ (unspec:HI [(match_operand:HI 1 "register_operand" "0,0")
+ (match_operand:HI 2 "incdec_operand" "M,O")]
+ UNSPEC_INCDEC))]
+ "TARGET_H8300H || TARGET_H8300S"
+ "@
+ inc.w %2,%T0
+ dec.w %G2,%T0"
+ [(set_attr "length" "2,2")
+ (set_attr "cc" "set_zn,set_zn")])
+
(define_split
[(set (match_operand:HI 0 "register_operand" "")
(plus:HI (match_dup 0)
[(set_attr "length" "2,2,6,2")
(set_attr "cc" "none_0hit,none_0hit,set_zn,set_zn")])
+(define_insn "addsi3_incdec"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "0,0")
+ (match_operand:SI 2 "incdec_operand" "M,O")]
+ UNSPEC_INCDEC))]
+ "TARGET_H8300H || TARGET_H8300S"
+ "@
+ inc.l %2,%S0
+ dec.l %G2,%S0"
+ [(set_attr "length" "2,2")
+ (set_attr "cc" "set_zn,set_zn")])
+
(define_split
[(set (match_operand:SI 0 "register_operand" "")
(plus:SI (match_dup 0)
(plus:SI (match_dup 0)
(match_dup 1)))]
"")
+
+;; Turn
+;;
+;; subs #1,er4
+;; mov.w r4,r4
+;; bne .L2028
+;;
+;; into
+;;
+;; dec.w #1,r4
+;; bne .L2028
+
+(define_peephole2
+ [(set (match_operand:HI 0 "register_operand" "")
+ (plus:HI (match_dup 0)
+ (match_operand 1 "incdec_operand" "")))
+ (set (cc0)
+ (match_dup 0))
+ (set (pc)
+ (if_then_else (match_operator 3 "eqne_operator"
+ [(cc0) (const_int 0)])
+ (label_ref (match_operand 2 "" ""))
+ (pc)))]
+ "TARGET_H8300H || TARGET_H8300S"
+ [(set (match_operand:HI 0 "register_operand" "")
+ (unspec:HI [(match_dup 0)
+ (match_dup 1)]
+ UNSPEC_INCDEC))
+ (set (cc0)
+ (match_dup 0))
+ (set (pc)
+ (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
+ (label_ref (match_dup 2))
+ (pc)))]
+ "")
+
+;; The SImode version of the previous pattern.
+
+(define_peephole2
+ [(set (match_operand:SI 0 "register_operand" "")
+ (plus:SI (match_dup 0)
+ (match_operand 1 "incdec_operand" "")))
+ (set (cc0)
+ (match_dup 0))
+ (set (pc)
+ (if_then_else (match_operator 3 "eqne_operator"
+ [(cc0) (const_int 0)])
+ (label_ref (match_operand 2 "" ""))
+ (pc)))]
+ "TARGET_H8300H || TARGET_H8300S"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (unspec:SI [(match_dup 0)
+ (match_dup 1)]
+ UNSPEC_INCDEC))
+ (set (cc0)
+ (match_dup 0))
+ (set (pc)
+ (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
+ (label_ref (match_dup 2))
+ (pc)))]
+ "")