This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] Fix push on h8300.
- To: gcc-patches at gcc dot gnu dot org
- Subject: [patch] Fix push on h8300.
- From: Kazu Hirata <kazu at hxi dot com>
Hi,
Attached is a patch to fix how push insns are generated on h8300.
Some time after I integrated push patterns into mov patterns, the
second flow phase started combining a stack pointer rewinding and a
push. Specifically,
adds #4,er7 <- stack rewinding from previous function call
mov.l er0,@-er7 <- stack push (HImode) for next function call
The flow2 phase turns the above insns into
mov.w er0,@er7
This is incorrect. "mov.w er0,@(2,er7)" would be correct. This is
because "(pre_modify (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))"
in the original push insn is combined and then canceled with the
previous stack pointer increment by 4.
The patch fixes the problem by utilizing newly created push patterns
(pushqi1 and pushhi1), which use parallel to represent a push,
eliminating the execution failure of 921124-1.c. Since push insns
that push regs shorter than Pmode are now out of mov patters,
unnecessary things are removed.
pushhi1_h8300 is just a expander for convenience because the standard
mov pattern can be used on TARGET_H8300.
I tried PROMOTE_MODE, PROMOTE_FUNCTION_ARGS, and PROMOTE_FOR_CAL_ONLY,
but that generated so many sign- and zero-extensions. This is why I
went for "parallel" solution.
Regression tested on h8300 port.
OK to apply?
Thanks,
Kazu Hirata
2001-07-30 Kazu Hirata <kazu@hxi.com>
* h8300-protos.h (general_operand_dst_push): Remove.
* h8300.c (general_operand_dst_push): Likewise.
* h8300.h (OK_FOR_T): Likewise.
(EXTRA_CONSTRAINTS): Do not use OK_FOR_T.
* h8300.md (pushqi_h8300): New.
(pushqi_h8300hs): Likewise.
(pushqi): Likewise.
(pushhi_h8300): Likewise.
(pushhi_h8300hs): Likewise.
(pushhi): Likewise.
Index: h8300-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/h8300/h8300-protos.h,v
retrieving revision 1.10
diff -u -r1.10 h8300-protos.h
--- h8300-protos.h 2001/07/23 21:46:37 1.10
+++ h8300-protos.h 2001/07/29 23:29:19
@@ -45,7 +45,6 @@
extern int general_operand_src PARAMS ((rtx, enum machine_mode));
extern int general_operand_dst PARAMS ((rtx, enum machine_mode));
-extern int general_operand_dst_push PARAMS ((rtx, enum machine_mode mode));
extern int o_operand PARAMS ((rtx, enum machine_mode));
extern int p_operand PARAMS ((rtx, enum machine_mode));
extern int call_insn_operand PARAMS ((rtx, enum machine_mode));
Index: h8300.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/h8300/h8300.c,v
retrieving revision 1.62
diff -u -r1.62 h8300.c
--- h8300.c 2001/07/23 21:46:37 1.62
+++ h8300.c 2001/07/29 23:29:20
@@ -537,7 +537,7 @@
}
/* Return true if OP is a valid destination operand for an integer move
- instruction, excluding those involving pre_modify. */
+ instruction. */
int
general_operand_dst (op, mode)
@@ -547,20 +547,6 @@
if (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == PRE_DEC)
return 1;
return general_operand (op, mode);
-}
-
-/* Return true if OP is a valid destination operand for an integer move
- instruction, including those involving pre_modify. */
-
-int
-general_operand_dst_push (op, mode)
- rtx op;
- enum machine_mode mode;
-{
- if (push_operand (op, mode))
- return 1;
-
- return general_operand_dst (op, mode);
}
/* Return true if OP is a const valid for a bit clear instruction. */
Index: h8300.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/h8300/h8300.h,v
retrieving revision 1.49
diff -u -r1.49 h8300.h
--- h8300.h 2001/07/29 03:12:34 1.49
+++ h8300.h 2001/07/29 23:29:20
@@ -840,16 +840,6 @@
(GET_CODE (X) == CONST_INT && TARGET_H8300H \
&& 0xffff00 <= INTVAL (X) && INTVAL (X) <= 0xffffff)
-/* 'T' if valid for a push destination using pre_modify. */
-#define OK_FOR_T(OP) \
- (GET_CODE (OP) == MEM \
- && GET_CODE (XEXP (OP, 0)) == PRE_MODIFY \
- && GET_CODE (XEXP (XEXP (OP, 0), 1)) == PLUS \
- && XEXP (XEXP (XEXP (OP, 0), 1), 0) == XEXP (XEXP (OP, 0), 0) \
- && GET_CODE (XEXP (XEXP (XEXP (OP, 0), 1), 1)) == CONST_INT \
- && INTVAL (XEXP (XEXP (XEXP (OP, 0), 1), 1)) == - (int) STACK_BOUNDARY / 8 \
- && XEXP (XEXP (OP, 0), 0) == stack_pointer_rtx)
-
/* 'U' if valid for a bset destination;
i.e. a register, register indirect, or the eightbit memory region
(a SYMBOL_REF with an SYMBOL_REF_FLAG set).
@@ -872,8 +862,7 @@
&& GET_CODE (XEXP (OP, 0)) == CONST_INT))
#define EXTRA_CONSTRAINT(OP, C) \
- ((C) == 'T' ? OK_FOR_T (OP) : \
- (C) == 'U' ? OK_FOR_U (OP) : \
+ ((C) == 'U' ? OK_FOR_U (OP) : \
0)
/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
Index: h8300.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/h8300/h8300.md,v
retrieving revision 1.31
diff -u -r1.31 h8300.md
--- h8300.md 2001/07/23 21:46:38 1.31
+++ h8300.md 2001/07/29 23:29:21
@@ -106,9 +106,41 @@
;; movqi
+(define_insn "pushqi1_h8300"
+ [(parallel [(set (reg:HI 7)
+ (plus:HI (reg:HI 7) (const_int -2)))
+ (set (mem:QI (plus:HI (reg:HI 7) (const_int -1)))
+ (match_operand:QI 0 "register_operand" "r"))])]
+ "TARGET_H8300"
+ "mov.w %T0,@-r7"
+ [(set_attr "length" "2")
+ (set_attr "cc" "clobber")])
+
+(define_insn "pushqi1_h8300hs"
+ [(parallel [(set (reg:SI 7)
+ (plus:SI (reg:SI 7) (const_int -4)))
+ (set (mem:QI (plus:SI (reg:SI 7) (const_int -3)))
+ (match_operand:QI 0 "register_operand" "r"))])]
+ "TARGET_H8300H || TARGET_H8300S"
+ "mov.l %S0,@-er7"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+(define_expand "pushqi1"
+ [(use (match_operand:QI 0 "register_operand" "r"))]
+ ""
+ "
+{
+ if (TARGET_H8300)
+ emit_insn (gen_pushqi1_h8300 (operands[0]));
+ else
+ emit_insn (gen_pushqi1_h8300hs (operands[0]));
+ DONE;
+}")
+
(define_insn ""
- [(set (match_operand:QI 0 "general_operand_dst_push" "=r,r ,<,T,r,r,m")
- (match_operand:QI 1 "general_operand_src" " I,r>,r,r,n,m,r"))]
+ [(set (match_operand:QI 0 "general_operand_dst" "=r,r ,<,r,r,m")
+ (match_operand:QI 1 "general_operand_src" " I,r>,r,n,m,r"))]
"TARGET_H8300
&& (register_operand (operands[0],QImode)
|| register_operand (operands[1], QImode))"
@@ -116,16 +148,15 @@
sub.b %X0,%X0
mov.b %R1,%X0
mov.b %X1,%R0
- mov.w %T1,@-r7
mov.b %R1,%X0
mov.b %R1,%X0
mov.b %X1,%R0"
- [(set_attr "length" "2,2,2,2,2,4,4")
- (set_attr "cc" "set_zn,set_znv,set_znv,clobber,set_znv,set_znv,set_znv")])
+ [(set_attr "length" "2,2,2,2,4,4")
+ (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
(define_insn ""
- [(set (match_operand:QI 0 "general_operand_dst_push" "=r,r ,<,r,T,r,m")
- (match_operand:QI 1 "general_operand_src" " I,r>,r,n,r,m,r"))]
+ [(set (match_operand:QI 0 "general_operand_dst" "=r,r ,<,r,r,m")
+ (match_operand:QI 1 "general_operand_src" " I,r>,r,n,m,r"))]
"(TARGET_H8300H || TARGET_H8300S)
&& (register_operand (operands[0],QImode)
|| register_operand (operands[1], QImode))"
@@ -134,14 +165,13 @@
mov.b %R1,%X0
mov.b %X1,%R0
mov.b %R1,%X0
- mov.l %S1,@-er7
mov.b %R1,%X0
mov.b %X1,%R0"
- [(set_attr "length" "2,2,2,2,4,8,8")
- (set_attr "cc" "set_zn,set_znv,set_znv,clobber,set_znv,set_znv,set_znv")])
+ [(set_attr "length" "2,2,2,2,8,8")
+ (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
(define_expand "movqi"
- [(set (match_operand:QI 0 "general_operand_dst_push" "")
+ [(set (match_operand:QI 0 "general_operand_dst" "")
(match_operand:QI 1 "general_operand_src" ""))]
""
"
@@ -170,3 +200,33 @@
;; movhi
+(define_expand "pushhi1_h8300"
+ [(set (mem:QI (pre_dec:HI (reg:HI 7)))
+ (match_operand:QI 0 "register_operand" "r"))]
+ "TARGET_H8300"
+ "")
+
+(define_insn "pushhi1_h8300hs"
+ [(parallel [(set (reg:SI 7)
+ (plus:SI (reg:SI 7) (const_int -4)))
+ (set (mem:HI (plus:SI (reg:SI 7) (const_int -2)))
+ (match_operand:HI 0 "register_operand" "r"))])]
+ "TARGET_H8300H || TARGET_H8300S"
+ "mov.l %S0,@-er7"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+(define_expand "pushhi1"
+ [(use (match_operand:QI 0 "register_operand" "r"))]
+ ""
+ "
+{
+ if (TARGET_H8300)
+ emit_insn (gen_pushhi1_h8300 (operands[0]));
+ else
+ emit_insn (gen_pushhi1_h8300hs (operands[0]));
+ DONE;
+}")
+
(define_insn ""
[(set (match_operand:HI 0 "general_operand_dst" "=r,r,<,r,r,m")
(match_operand:HI 1 "general_operand_src" "I,r>,r,i,m,r"))]
@@ -187,8 +247,8 @@
(set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
(define_insn ""
- [(set (match_operand:HI 0 "general_operand_dst_push" "=r,r,<,T,r,r,m")
- (match_operand:HI 1 "general_operand_src" "I,r>,r,r,i,m,r"))]
+ [(set (match_operand:HI 0 "general_operand_dst" "=r,r,<,r,r,m")
+ (match_operand:HI 1 "general_operand_src" "I,r>,r,i,m,r"))]
"(TARGET_H8300H || TARGET_H8300S)
&& (register_operand (operands[0],HImode)
|| register_operand (operands[1], HImode))"
@@ -196,15 +256,14 @@
sub.w %T0,%T0
mov.w %T1,%T0
mov.w %T1,%T0
- mov.l %S1,@-er7
mov.w %T1,%T0
mov.w %T1,%T0
mov.w %T1,%T0"
- [(set_attr "length" "2,2,2,4,4,8,8")
- (set_attr "cc" "set_zn,set_znv,set_znv,clobber,set_znv,set_znv,set_znv")])
+ [(set_attr "length" "2,2,2,4,8,8")
+ (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
(define_expand "movhi"
- [(set (match_operand:HI 0 "general_operand_dst_push" "")
+ [(set (match_operand:HI 0 "general_operand_dst" "")
(match_operand:HI 1 "general_operand_src" ""))]
""
"