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 HC12 invalid code generation for movw, bclr and bset


Hi!

This patch fixes an invalid code generation for 68HC12 with movw,
bset and bclr instructions.  The indirect addressing (MEM (MEM))
is not supported for these instructions.  Committed on 3_4 and 4_0.
(PR savannah/12297 and PR savannah/11813)

Stephane

2005-05-08  Stephane Carrez  <stcarrez@nerim.fr>

	* config/m68hc11/m68hc11.c (m68hc11_z_replacement): Use emit_insn_after
	when adding the save Z instruction so that it is part of the good BB.
	(reg_or_some_mem_operand): Do not allow the 68HC12 address indirect
	addressing mode as it is not supported by bset and bclr.
	(m68hc11_gen_movhi): Fix invalid generation of indexed indirect
	addressing with movw.
	(m68hc11_gen_movqi): Use pula and pulb instead of lda and ldb for
	68HC12.
	* config/m68hc11/m68hc11.md ("movhi_const0"): Use this pattern only
	for 68HC11.
	("*movhi_68hc12"): Handle movhi_const0.
	("*subhi3", "subqi3"): Use general_operand for operand 1.
	("*subhi3_zext"): Likewise.
Index: config/m68hc11/m68hc11.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/m68hc11/m68hc11.c,v
retrieving revision 1.91.6.7
diff -u -p -r1.91.6.7 m68hc11.c
--- config/m68hc11/m68hc11.c	8 May 2005 10:08:48 -0000	1.91.6.7
+++ config/m68hc11/m68hc11.c	8 May 2005 18:47:47 -0000
@@ -1027,6 +1027,7 @@ reg_or_some_mem_operand (rtx operand, en
   if (GET_CODE (operand) == MEM)
     {
       rtx op = XEXP (operand, 0);
+      int addr_mode;
 
       if (symbolic_memory_operand (op, mode))
 	return 1;
@@ -1034,10 +1035,20 @@ reg_or_some_mem_operand (rtx operand, en
       if (IS_STACK_PUSH (operand))
 	return 1;
 
-      if (m68hc11_register_indirect_p (operand, mode))
-	return 1;
+      if (GET_CODE (operand) == REG && reload_in_progress
+          && REGNO (operand) >= FIRST_PSEUDO_REGISTER
+          && reg_equiv_memory_loc[REGNO (operand)])
+         {
+            operand = reg_equiv_memory_loc[REGNO (operand)];
+            operand = eliminate_regs (operand, 0, NULL_RTX);
+         }
+      if (GET_CODE (operand) != MEM)
+         return 0;
 
-      return 0;
+      operand = XEXP (operand, 0);
+      addr_mode = m68hc11_addr_mode | (reload_completed ? ADDR_STRICT : 0);
+      addr_mode &= ~ADDR_INDIRECT;
+      return register_indirect_p (operand, mode, addr_mode);
     }
 
   return register_operand (operand, mode);
@@ -3221,10 +3232,13 @@ m68hc11_gen_movhi (rtx insn, rtx *operan
 
   if (TARGET_M6812)
     {
-      if (IS_STACK_PUSH (operands[0]) && H_REG_P (operands[1]))
+      rtx from = operands[1];
+      rtx to = operands[0];
+
+      if (IS_STACK_PUSH (to) && H_REG_P (from))
 	{
           cc_status = cc_prev_status;
-	  switch (REGNO (operands[1]))
+	  switch (REGNO (from))
 	    {
 	    case HARD_X_REGNUM:
 	    case HARD_Y_REGNUM:
@@ -3239,10 +3253,10 @@ m68hc11_gen_movhi (rtx insn, rtx *operan
 	    }
 	  return;
 	}
-      if (IS_STACK_POP (operands[1]) && H_REG_P (operands[0]))
+      if (IS_STACK_POP (from) && H_REG_P (to))
 	{
           cc_status = cc_prev_status;
-	  switch (REGNO (operands[0]))
+	  switch (REGNO (to))
 	    {
 	    case HARD_X_REGNUM:
 	    case HARD_Y_REGNUM:
@@ -3273,11 +3287,52 @@ m68hc11_gen_movhi (rtx insn, rtx *operan
 	  else
 	    output_asm_insn ("st%1\t%0", operands);
 	}
+
+      /* The 68hc12 does not support (MEM:HI (MEM:HI)) with the movw
+         instruction.  We have to use a scratch register as temporary location.
+         Trying to use a specific pattern or constrain failed.  */
+      else if (GET_CODE (to) == MEM && GET_CODE (XEXP (to, 0)) == MEM)
+        {
+          rtx ops[4];
+
+          ops[0] = to;
+          ops[2] = from;
+          ops[3] = 0;
+          if (dead_register_here (insn, d_reg))
+            ops[1] = d_reg;
+          else if (dead_register_here (insn, ix_reg))
+            ops[1] = ix_reg;
+          else if (dead_register_here (insn, iy_reg))
+            ops[1] = iy_reg;
+          else
+            {
+              ops[1] = d_reg;
+              ops[3] = d_reg;
+              output_asm_insn ("psh%3", ops);
+            }
+
+          ops[0] = to;
+          ops[2] = from;
+          output_asm_insn ("ld%1\t%2", ops);
+          output_asm_insn ("st%1\t%0", ops);
+          if (ops[3])
+            output_asm_insn ("pul%3", ops);
+        }
+
+      /* Use movw for non-null constants or when we are clearing
+         a volatile memory reference.  However, this is possible
+         only if the memory reference has a small offset or is an
+         absolute address.  */
+      else if (GET_CODE (from) == CONST_INT
+               && INTVAL (from) == 0
+               && (MEM_VOLATILE_P (to) == 0
+                   || m68hc11_small_indexed_indirect_p (to, HImode) == 0))
+        {
+          output_asm_insn ("clr\t%h0", operands);
+          output_asm_insn ("clr\t%b0", operands);
+        }
       else
 	{
-	  rtx from = operands[1];
-	  rtx to = operands[0];
-
 	  if ((m68hc11_register_indirect_p (from, GET_MODE (from))
 	       && !m68hc11_small_indexed_indirect_p (from, GET_MODE (from)))
 	      || (m68hc11_register_indirect_p (to, GET_MODE (to))
@@ -3294,6 +3349,7 @@ m68hc11_gen_movhi (rtx insn, rtx *operan
 		  ops[0] = to;
 		  ops[1] = operands[2];
 		  m68hc11_gen_movhi (insn, ops);
+                  return;
 		}
 	      else
 		{
@@ -3301,19 +3357,11 @@ m68hc11_gen_movhi (rtx insn, rtx *operan
                   fatal_insn ("move insn not handled", insn);
 		}
 	    }
-	  else
-	    {
-	      if (GET_CODE (from) == CONST_INT && INTVAL (from) == 0)
-		{
-		  output_asm_insn ("clr\t%h0", operands);
-		  output_asm_insn ("clr\t%b0", operands);
-		}
-	      else
-		{
-                  m68hc11_notice_keep_cc (operands[0]);
-		  output_asm_insn ("movw\t%1,%0", operands);
-		}
-	    }
+          else
+            {
+              m68hc11_notice_keep_cc (operands[0]);
+              output_asm_insn ("movw\t%1,%0", operands);
+            }
 	}
       return;
     }
@@ -3641,8 +3689,10 @@ m68hc11_gen_movqi (rtx insn, rtx *operan
 	}
       else if (H_REG_P (operands[0]))
 	{
-	  if (Q_REG_P (operands[0]))
-	    output_asm_insn ("lda%0\t%b1", operands);
+          if (IS_STACK_POP (operands[1]))
+            output_asm_insn ("pul%b0", operands);
+	  else if (Q_REG_P (operands[0]))
+            output_asm_insn ("lda%0\t%b1", operands);
 	  else if (D_REG_P (operands[0]))
 	    output_asm_insn ("ldab\t%b1", operands);
 	  else
@@ -5006,9 +5056,11 @@ m68hc11_z_replacement (rtx insn)
       if (info.save_before_last)
 	save_pos_insn = PREV_INSN (save_pos_insn);
 
-      emit_insn_before (gen_movhi (gen_rtx (REG, HImode, SOFT_Z_REGNUM),
-				   gen_rtx (REG, HImode, info.regno)),
-			save_pos_insn);
+      /* Use emit_insn_after () to ensure the new insn is part of
+         the good basic block.  */
+      emit_insn_after (gen_movhi (gen_rtx (REG, HImode, SOFT_Z_REGNUM),
+                                  gen_rtx (REG, HImode, info.regno)),
+                       PREV_INSN (save_pos_insn));
     }
 
   if (info.must_push_reg && info.last)
@@ -5047,8 +5099,8 @@ m68hc11_z_replacement (rtx insn)
       else
 	dst = gen_rtx (REG, HImode, SOFT_SAVED_XY_REGNUM);
 
-      emit_insn_before (gen_movhi (gen_rtx (REG, HImode, info.regno),
-				   dst), insn);
+      emit_insn_after (gen_movhi (gen_rtx (REG, HImode, info.regno),
+                                  dst), PREV_INSN (insn));
     }
 
 }
Index: config/m68hc11/m68hc11.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/m68hc11/m68hc11.md,v
retrieving revision 1.54.10.8
diff -u -p -r1.54.10.8 m68hc11.md
--- config/m68hc11/m68hc11.md	8 May 2005 17:42:44 -0000	1.54.10.8
+++ config/m68hc11/m68hc11.md	8 May 2005 19:20:53 -0000
@@ -687,8 +687,8 @@
    DONE;")
 
 (define_insn_and_split "movdf_internal"
-  [(set (match_operand:DF 0 "non_push_operand" "=mu,U,!u,U,m,m,!u")
-	(match_operand:DF 1 "general_operand" "G,iU,iU,!u,mi,!u,!mu"))
+  [(set (match_operand:DF 0 "non_push_operand" "=mu,U,m,!u,U,m,!u")
+	(match_operand:DF 1 "general_operand" "G,iU,mi,iU,!u,!u,!mu"))
    (clobber (match_scratch:HI 2 "=X,&d,&d,&d,&d,&d,&d"))]
   ""
   "#"
@@ -884,18 +884,9 @@
     }
 }")
 
-(define_insn "movhi_const0"
-  [(set (match_operand:HI 0 "splitable_operand" "=d,A,um")
-	(const_int 0))]
-  ""
-  "@
-   clra\\n\\tclrb
-   ld%0\\t#0
-   clr\\t%b0\\n\\tclr\\t%h0")
-
 (define_insn "*movhi_68hc12"
-  [(set (match_operand:HI 0 "nonimmediate_operand" "=U,dAw,dAw,U,U,m,!u")
-	(match_operand:HI 1 "general_operand" "U,dAwim,!u,dAwi,!u,dAw,riU"))]
+  [(set (match_operand:HI 0 "nonimmediate_operand" "=U,dAw,dAw,m,U,U,m,!u")
+	(match_operand:HI 1 "general_operand" "U,dAwim,!u,K,dAwi,!u,dAw,riU"))]
   "TARGET_M6812"
   "*
 {
@@ -903,6 +894,15 @@
   return \"\";
 }")
 
+(define_insn "movhi_const0"
+  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,A,um")
+	(const_int 0))]
+  "TARGET_M6811"
+  "@
+   clra\\n\\tclrb
+   ld%0\\t#0
+   clr\\t%b0\\n\\tclr\\t%h0")
+
 (define_insn "*movhi_m68hc11"
   [(set (match_operand:HI 0 "nonimmediate_operand" "=dAw,!u,m,m,dAw,!*u")
 	(match_operand:HI 1 "general_operand" "dAwim,dAw,dA,?Aw,!*u,dAw"))]
@@ -1235,7 +1235,7 @@
   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,m,!u,!u")
 	(zero_extend:DI 
 	    (match_operand:SI 1 "nonimmediate_operand" "m,Du,m,Du")))
-   (clobber (match_scratch:HI 2 "=d,d,&d,d"))]
+   (clobber (match_scratch:HI 2 "=d,d,d,d"))]
   ""
   "#")
 
@@ -2380,7 +2380,7 @@
   [(set (match_operand:HI 0 "hard_reg_operand" "=A,d")
 	(plus:HI (zero_extend:HI 
 		     (match_operand:QI 1 "nonimmediate_operand" "d,um*A"))
-		 (match_operand:HI 2 "hard_reg_operand" "0,0")))]
+		 (match_operand:HI 2 "general_operand" "0,0")))]
   ""
   "*
 {
@@ -2714,7 +2714,7 @@
 
 (define_insn "*subhi3"
   [(set (match_operand:HI 0 "register_operand" "=d,*A,d,*A")
-	(minus:HI (match_operand:HI 1 "register_operand" "0,0,0,0")
+	(minus:HI (match_operand:HI 1 "general_operand" "0,0,0,0")
 		  (match_operand:HI 2 "general_operand" "im*A*d,im*d*A,u,!u")))]
   ""
   "*
@@ -2729,7 +2729,7 @@
 
 (define_insn "*subhi3_zext"
   [(set (match_operand:HI 0 "hard_reg_operand" "=d,d")
-	(minus:HI (match_operand:HI 1 "hard_reg_operand" "0,0")
+	(minus:HI (match_operand:HI 1 "general_operand" "0,0")
            (zero_extend:HI (match_operand:QI 2 "general_operand" "mi*A,!u"))))]
   ""
   "*
@@ -2749,7 +2749,7 @@
 
 (define_insn "subqi3"
   [(set (match_operand:QI 0 "hard_reg_operand" "=dq,!*x*y")
-        (minus:QI (match_operand:QI 1 "hard_reg_operand" "0,0")
+        (minus:QI (match_operand:QI 1 "general_operand" "0,0")
                   (match_operand:QI 2 "general_operand" "uim*A*d,uim*A*d")))]
   ""
   "*
@@ -3324,8 +3324,8 @@
 
 (define_insn "*andqi3_gen"
   [(set (match_operand:QI 0 "register_operand" "=d,d,d,?*A,?*A,!*q")
-        (and:QI (match_operand:QI 1 "register_operand" "%0,0,0,0,0,0")
-             (match_operand:QI 2 "general_operand" "mi,!u,?*A,!um,?*A*d,!um*A")))]
+        (and:QI (match_operand:QI 1 "general_operand" "%0,0,0,0,0,0")
+             (match_operand:QI 2 "general_operand" "mi,!*u,?*A,!*um,?*A*d,!*um*A")))]
   ""
   "*
 {
@@ -3542,8 +3542,8 @@
 
 (define_insn "*iorqi3_gen"
   [(set (match_operand:QI 0 "register_operand" "=d,d,d,?*A,?*A,!*q")
-	(ior:QI (match_operand:QI 1 "register_operand" "%0,0,0,0,0,0")
-	     (match_operand:QI 2 "general_operand" "mi,!u,!*A,!um,?*A*d,!um*A")))]
+	(ior:QI (match_operand:QI 1 "general_operand" "%0,0,0,0,0,0")
+	     (match_operand:QI 2 "general_operand" "mi,!*u,!*A,!*um,?*A*d,!*um*A")))]
   ""
   "*
 {
@@ -3634,8 +3634,8 @@
 
 (define_insn "xorqi3"
   [(set (match_operand:QI 0 "register_operand" "=d,d,d,?*A,?*A,!*q")
-        (xor:QI (match_operand:QI 1 "register_operand" "%0,0,0,0,0,0")
-             (match_operand:QI 2 "general_operand" "im,!u,!*A,!ium,?*A*d,!ium*A")))]
+        (xor:QI (match_operand:QI 1 "general_operand" "%0,0,0,0,0,0")
+             (match_operand:QI 2 "general_operand" "im,!*u,!*A,!i*um,?*A*d,!i*um*A")))]
   ""
   "*
 {
@@ -6909,14 +6909,16 @@
 ;;
 ;; Replace "leas 2,sp" with a "pulx" or a "puly".
 ;; On 68HC12, this is one cycle slower but one byte smaller.
-;; pr target/6899: This peephole is not valid because a register CSE
-;; pass removes the pulx/puly.
+;; pr target/6899: This peephole was not valid because a register CSE
+;; pass removes the pulx/puly.  The 'use' clause ensure that the pulx is
+;; not removed.
 ;;
 (define_peephole2
   [(set (reg:HI SP_REGNUM) (plus:HI (reg:HI SP_REGNUM) (const_int 2)))
    (match_scratch:HI 0 "xy")]
-  "0 && TARGET_M6812 && optimize_size"
-  [(set (match_dup 0) (match_dup 1))]
+  "TARGET_M6812 && optimize_size"
+  [(set (match_dup 0) (match_dup 1))
+   (use (match_dup 0))]
   "operands[1] = gen_rtx (MEM, HImode,
 			  gen_rtx (POST_INC, HImode,
 				   gen_rtx_REG (HImode, HARD_SP_REGNUM)));")

Attachment: signature.asc
Description: OpenPGP digital signature


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