* [patch] h8300: Use inc/dec.
@ 2002-12-20 12:55 Kazu Hirata
0 siblings, 0 replies; only message in thread
From: Kazu Hirata @ 2002-12-20 12:55 UTC (permalink / raw)
To: gcc-patches
Hi,
Attached is a patch to use inc/dec instead of adds/subs in certain
cases.
Currently, a decrement followed by a conditional branch based on
inequality test looks like
subs #1,er4
mov.w r4,r4
bne .L2028
The test instruction in the middle can be removed if the decrement is
done by dec because it sets cc0.
dec.w #1,r4
bne .L2028
This kind of optimization is valid only for (in)equality tests. The
patch implements the above transformation using a peephole and an
unspec insn representing inc/dec.
Tested on h8300 port. Committed.
Kazu Hirata
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.
Index: h8300-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/h8300/h8300-protos.h,v
retrieving revision 1.34
diff -u -r1.34 h8300-protos.h
--- h8300-protos.h 28 Nov 2002 14:08:34 -0000 1.34
+++ h8300-protos.h 20 Dec 2002 20:42:34 -0000
@@ -59,8 +59,10 @@
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));
Index: h8300.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/h8300/h8300.c,v
retrieving revision 1.178
diff -u -r1.178 h8300.c
--- h8300.c 20 Dec 2002 20:40:57 -0000 1.178
+++ h8300.c 20 Dec 2002 20:42:35 -0000
@@ -1806,6 +1806,30 @@
}
}
+/* 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
Index: h8300.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/h8300/h8300.h,v
retrieving revision 1.124
diff -u -r1.124 h8300.h
--- h8300.h 16 Dec 2002 18:21:14 -0000 1.124
+++ h8300.h 20 Dec 2002 20:42:36 -0000
@@ -466,16 +466,22 @@
(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.
Index: h8300.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/h8300/h8300.md,v
retrieving revision 1.125
diff -u -r1.125 h8300.md
--- h8300.md 20 Dec 2002 00:08:06 -0000 1.125
+++ h8300.md 20 Dec 2002 20:42:36 -0000
@@ -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)
@@ -2783,4 +2810,65 @@
(set (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)))]
"")
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2002-12-20 20:55 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-12-20 12:55 [patch] h8300: Use inc/dec Kazu Hirata
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).