aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorKazu Hirata <kazu@cs.umass.edu>2002-12-20 20:53:52 +0000
committerKazu Hirata <kazu@gcc.gnu.org>2002-12-20 20:53:52 +0000
commitf9d2de4d0dc6eb961d12eb1888e387dfbdf33ae4 (patch)
tree169d6ebd254a2a3318a7ea9b59640a9ce9401741 /gcc
parentb47900aa0b511c57af99f2a7c88063e108b46dbc (diff)
downloadgcc-f9d2de4d0dc6eb961d12eb1888e387dfbdf33ae4.zip
gcc-f9d2de4d0dc6eb961d12eb1888e387dfbdf33ae4.tar.gz
gcc-f9d2de4d0dc6eb961d12eb1888e387dfbdf33ae4.tar.bz2
h8300-protos.h: Add prototypes for incdec_operand and eqne_operator.
* 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. From-SVN: r60375
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/config/h8300/h8300-protos.h2
-rw-r--r--gcc/config/h8300/h8300.c24
-rw-r--r--gcc/config/h8300/h8300.h6
-rw-r--r--gcc/config/h8300/h8300.md88
5 files changed, 135 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1fd0beb..d7e51d7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,20 @@
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.
diff --git a/gcc/config/h8300/h8300-protos.h b/gcc/config/h8300/h8300-protos.h
index aac5622..f56d837 100644
--- a/gcc/config/h8300/h8300-protos.h
+++ b/gcc/config/h8300/h8300-protos.h
@@ -59,8 +59,10 @@ extern int small_call_insn_operand PARAMS ((rtx, enum machine_mode));
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));
diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c
index 2d372dd..739728c 100644
--- a/gcc/config/h8300/h8300.c
+++ b/gcc/config/h8300/h8300.c
@@ -1806,6 +1806,30 @@ notice_update_cc (body, insn)
}
}
+/* 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
diff --git a/gcc/config/h8300/h8300.h b/gcc/config/h8300/h8300.h
index 49c47ef..aebc4f7 100644
--- a/gcc/config/h8300/h8300.h
+++ b/gcc/config/h8300/h8300.h
@@ -466,16 +466,22 @@ enum reg_class {
(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.
diff --git a/gcc/config/h8300/h8300.md b/gcc/config/h8300/h8300.md
index 14e2c6c..5bba952 100644
--- a/gcc/config/h8300/h8300.md
+++ b/gcc/config/h8300/h8300.md
@@ -51,6 +51,9 @@
;; ----------------------------------------------------------------------
(define_constants
+ [(UNSPEC_INCDEC 0)])
+
+(define_constants
[(SC_REG 3)
(FP_REG 6)
(SP_REG 7)
@@ -794,6 +797,18 @@
[(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)
@@ -834,6 +849,18 @@
[(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)
@@ -2784,3 +2811,64 @@
(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)))]
+ "")