This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[patch] Fix push on h8300.


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" ""))]
   ""
   "


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]