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]
Other format: [Raw text]

[PATCH]: Fix compare and shift problems for 68HC12


Hi!

This patch fixes problems on 68HC12:

- 32-bit shift patterns ("*_const") fail to be reloaded with
  -O -fomit-frame-pointer because the Z register is disabled
  with -fomit-frame-pointer on 68HC12.  We must use the "*lshrsi3"
  pattern that temporarily save the Y register.

- comparing 2 regs is made by pushing one reg on the stack; comparison is then
  made with a pop; this creates side effects on operands and they are not
  detected correctly by final_scan_insn (because there are no side effect notes
  on them).  The compare must be implemented without splitting the insn (poping
  is not seen at all by final_scan_insn); also fixed notice_update_cc so that
  such side effects are found.

Committed on 3_4 and mainline.

Stephane

2004-03-07 Stephane Carrez <stcarrez@nerim.fr>

	* config/m68hc11/m68hc11.md ("*lshrsi3_const"): Disable for 68HC12.
	("*lshrsi3"): Also accept an immediate for 68HC12.
	("*ashrsi3_const"): Likewise.
	("*ashrsi3"): Likewise.
	("*ashlsi3_const"): Likewise.
	("*ashlsi3"): Likewise.
	("cmphi_1_hc12"): Compare two hard register by pushing them and
	comparing with a pop; don't use a split for that.
	("cmphi split"): Disable compare split for 68HC12.

	* config/m68hc11/m68hc11.c (m68hc11_notice_update_cc): Invalidate
	the status operands if they have side effects.

Index: config/m68hc11/m68hc11.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/m68hc11/m68hc11.md,v
retrieving revision 1.54.10.4
diff -u -p -r1.54.10.4 m68hc11.md
--- config/m68hc11/m68hc11.md	2 Mar 2004 22:12:39 -0000	1.54.10.4
+++ config/m68hc11/m68hc11.md	7 Mar 2004 20:56:59 -0000
@@ -308,7 +308,7 @@
   [(set (cc0)
 	(compare (match_operand:HI 0 "hard_reg_operand" "")
 		 (match_operand:HI 1 "hard_reg_operand" "")))]
-  "TARGET_M6812
+  "0 && TARGET_M6812
    && reload_completed && !(Z_REG_P (operands[0]) || Z_REG_P (operands[1]))"
   [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM))) (match_dup 1))
    (set (cc0)
@@ -344,8 +344,10 @@
       cc_status.flags |= CC_REVERSED;
       return \"cp%1\\t%0\";
     }
+  else if (SP_REG_P (operands[1]))
+    return \"sts\\t2,-sp\n\\tcp%0\\t2,sp+\";
   else if (H_REG_P (operands[1]))
-    return \"#\";
+    return \"psh%1\n\\tcp%0\\t2,sp+\";
   else
     return \"cp%0\\t%1\";
 }")
@@ -4615,10 +4617,10 @@
    "")
 
 (define_insn "*ashlsi3_const1"
-  [(set (match_operand:SI 0 "non_push_operand" "=D,D,D,m,*u")
-	(ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,*u,m,*u")
+  [(set (match_operand:SI 0 "non_push_operand" "=D,D,D,m,*u,*u")
+	(ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,*u,m,*u,m")
 	           (const_int 1)))
-   (clobber (match_scratch:HI 2 "=X,X,X,&d,&d"))]
+   (clobber (match_scratch:HI 2 "=X,X,X,&d,&d,&d"))]
    ""
    "*
 {
@@ -4674,7 +4676,7 @@
 	(ashift:SI (match_dup 0)
 	           (match_operand:HI 1 "const_int_operand" "")))
    (clobber (match_scratch:HI 2 "=y"))]
-   ""
+   "TARGET_M6811 /* See *ashlsi3 note.  */"
    "*
 {
   CC_STATUS_INIT;
@@ -4684,7 +4686,7 @@
 (define_insn "*ashlsi3"
   [(set (match_operand:SI 0 "register_operand" "+D,D")
 	(ashift:SI (match_dup 0)
-	           (match_operand:HI 1 "general_operand" "y,m")))
+	           (match_operand:HI 1 "general_operand" "y,mi")))
    (clobber (match_scratch:HI 2 "=1,X"))]
    ""
    "*
@@ -4697,7 +4699,12 @@
      is not enough register in class A_REGS.
 
      Assuming that 'operands[1]' does not refer to the stack (which 
-     is true for 68hc11 only, we save temporary the value of Y.  */
+     is true for 68hc11 only, we save temporary the value of Y.
+
+     For 68HC12 we must also accept a constant because Z register is
+     disabled when compiling with -fomit-frame-pointer.  We can come up
+     with a reload problem and the *lshrsi3_const pattern was disabled
+     for that reason.  */
   if (!Y_REG_P (operands[2]))
     {
       rtx ops[1];
@@ -5084,7 +5091,7 @@
 	(ashiftrt:SI (match_dup 0)
 	             (match_operand:HI 1 "const_int_operand" "")))
    (clobber (match_scratch:HI 2 "=y"))]
-   ""
+   "TARGET_M6811 /* See *ashrsi3 note.  */"
    "*
 {
   CC_STATUS_INIT;
@@ -5094,7 +5101,7 @@
 (define_insn "*ashrsi3"
   [(set (match_operand:SI 0 "register_operand" "+D,D")
 	(ashiftrt:SI (match_dup 0)
-	             (match_operand:HI 1 "general_operand" "y,m")))
+	             (match_operand:HI 1 "general_operand" "y,mi")))
    (clobber (match_scratch:HI 2 "=1,X"))]
    ""
    "*
@@ -5106,7 +5113,12 @@
      is not enough register in class A_REGS.
 
      Assuming that 'operands[1]' does not refer to the stack (which 
-     is true for 68hc11 only, we save temporary the value of Y.  */
+     is true for 68hc11 only, we save temporary the value of Y.
+
+     For 68HC12 we must also accept a constant because Z register is
+     disabled when compiling with -fomit-frame-pointer.  We can come up
+     with a reload problem and the *lshrsi3_const pattern was disabled
+     for that reason.  */
   if (!Y_REG_P (operands[2]))
     {
       rtx ops[1];
@@ -5367,10 +5379,10 @@
     #")
 
 (define_insn "*lshrsi3_const1"
-  [(set (match_operand:SI 0 "non_push_operand" "=D,D,D,m,*u")
-	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,*u,m,*u")
+  [(set (match_operand:SI 0 "non_push_operand" "=D,D,D,m,*u,*u")
+	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,*u,m,*u,m")
 	             (const_int 1)))
-   (clobber (match_scratch:HI 2 "=X,X,X,&d,&d"))]
+   (clobber (match_scratch:HI 2 "=X,X,X,&d,&d,&d"))]
    ""
    "*
 {
@@ -5421,7 +5433,7 @@
 	(lshiftrt:SI (match_dup 0)
 	             (match_operand:HI 1 "const_int_operand" "")))
    (clobber (match_scratch:HI 2 "=y"))]
-   ""
+   "TARGET_M6811 /* See *lshrsi3 note.  */"
    "*
 {
   CC_STATUS_INIT;
@@ -5431,7 +5443,7 @@
 (define_insn "*lshrsi3"
   [(set (match_operand:SI 0 "register_operand" "+D,D")
 	(lshiftrt:SI (match_dup 0)
-	             (match_operand:HI 1 "general_operand" "y,m")))
+	             (match_operand:HI 1 "general_operand" "y,mi")))
    (clobber (match_scratch:HI 2 "=1,X"))]
    ""
    "*
@@ -5443,7 +5455,12 @@
      is not enough register in class A_REGS.
 
      Assuming that 'operands[1]' does not refer to the stack (which 
-     is true for 68hc11 only, we save temporary the value of Y.  */
+     is true for 68hc11 only, we save temporary the value of Y.
+
+     For 68HC12 we must also accept a constant because Z register is
+     disabled when compiling with -fomit-frame-pointer.  We can come up
+     with a reload problem and the *lshrsi3_const pattern was disabled
+     for that reason.  */
   if (!Y_REG_P (operands[2]))
     {
       rtx ops[1];
Index: config/m68hc11/m68hc11.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/m68hc11/m68hc11.c,v
retrieving revision 1.91.6.4
diff -u -p -r1.91.6.4 m68hc11.c
--- config/m68hc11/m68hc11.c	7 Mar 2004 09:52:13 -0000	1.91.6.4
+++ config/m68hc11/m68hc11.c	7 Mar 2004 20:57:01 -0000
@@ -4077,6 +4077,12 @@ m68hc11_notice_update_cc (rtx exp, rtx i
       && cc_status.value2
       && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2))
     cc_status.value2 = 0;
+
+  else if (cc_status.value1 && side_effects_p (cc_status.value1))
+    cc_status.value1 = 0;
+
+  else if (cc_status.value2 && side_effects_p (cc_status.value2))
+    cc_status.value2 = 0;
 }
 
 /* The current instruction does not affect the flags but changes

Attachment: pgp00000.pgp
Description: PGP signature


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