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(mainline)


Hi!

Committed the following patch on mainline which corresponds to
the mainline version for:

http://gcc.gnu.org/ml/gcc-patches/2005-05/msg00655.html

Stephane

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

	* config/m68hc11/predicates.md (reg_or_some_mem_operand): Do not allow
	the 68HC12 address indirect addressing mode as it is not supported by
	bset and bclr.
	* config/m68hc11/m68hc11-protos.h (m68hc11_valid_addressing_p): Declare.
	(m68hc11_add_mode): Declare.
	* config/m68hc11/m68hc11.c (m68hc11_valid_addressing_p): Rename from
	register_indirect_p and export it.
	(m68hc11_z_replacement): Use emit_insn_after when adding the save Z
	instruction so that it is part of the good BB.
	(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.h (ADDR_STRICT, ADDR_INCDEC, ADDR_INDEXED,
	ADDR_OFFSET, ADDR_INDIRECT, ADDR__CONST): Moved from m68hc11.c.
	* 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.
? config/m68hc11/t-m68hc11-gas.fix
Index: config/m68hc11/m68hc11-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/m68hc11/m68hc11-protos.h,v
retrieving revision 1.34
diff -u -p -r1.34 m68hc11-protos.h
--- config/m68hc11/m68hc11-protos.h	2 Apr 2005 19:31:21 -0000	1.34
+++ config/m68hc11/m68hc11-protos.h	8 May 2005 19:39:34 -0000
@@ -98,6 +98,7 @@ extern int memory_indexed_operand (rtx, 
 extern void m68hc11_split_logical (enum machine_mode, int, rtx*);
 
 extern int m68hc11_register_indirect_p (rtx, enum machine_mode);
+extern int m68hc11_valid_addressing_p (rtx, enum machine_mode, int);
 
 extern int symbolic_memory_operand (rtx, enum machine_mode);
 
@@ -123,6 +124,7 @@ extern int m68hc11_page0_symbol_p (rtx x
 
 extern HOST_WIDE_INT m68hc11_min_offset;
 extern HOST_WIDE_INT m68hc11_max_offset;
+extern int m68hc11_addr_mode;
 
 #endif /* HAVE_MACHINE_MODES */
 #endif /* RTX_CODE */
Index: config/m68hc11/m68hc11.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/m68hc11/m68hc11.c,v
retrieving revision 1.115
diff -u -p -r1.115 m68hc11.c
--- config/m68hc11/m68hc11.c	8 May 2005 10:23:39 -0000	1.115
+++ config/m68hc11/m68hc11.c	8 May 2005 19:39:35 -0000
@@ -65,7 +65,6 @@ static rtx simplify_logical (enum machin
 static void m68hc11_emit_logical (enum machine_mode, int, rtx *);
 static void m68hc11_reorg (void);
 static int go_if_legitimate_address_internal (rtx, enum machine_mode, int);
-static int register_indirect_p (rtx, enum machine_mode, int);
 static rtx m68hc11_expand_compare (enum rtx_code, rtx, rtx);
 static int must_parenthesize (rtx);
 static int m68hc11_address_cost (rtx);
@@ -140,13 +139,6 @@ unsigned char m68hc11_reg_valid_for_inde
    This is 1 for 68HC11 and 0 for 68HC12.  */
 int m68hc11_sp_correction;
 
-#define ADDR_STRICT       0x01  /* Accept only registers in class A_REGS  */
-#define ADDR_INCDEC       0x02  /* Post/Pre inc/dec */
-#define ADDR_INDEXED      0x04  /* D-reg index */
-#define ADDR_OFFSET       0x08
-#define ADDR_INDIRECT     0x10  /* Accept (mem (mem ...)) for [n,X] */
-#define ADDR_CONST        0x20  /* Accept const and symbol_ref  */
-
 int m68hc11_addr_mode;
 int m68hc11_mov_addr_mode;
 
@@ -560,8 +552,8 @@ preferred_reload_class (rtx operand, enu
 /* Return 1 if the operand is a valid indexed addressing mode.
    For 68hc11:  n,r    with n in [0..255] and r in A_REGS class
    For 68hc12:  n,r    no constraint on the constant, r in A_REGS class.  */
-static int
-register_indirect_p (rtx operand, enum machine_mode mode, int addr_mode)
+int
+m68hc11_valid_addressing_p (rtx operand, enum machine_mode mode, int addr_mode)
 {
   rtx base, offset;
 
@@ -569,8 +561,8 @@ register_indirect_p (rtx operand, enum m
     {
     case MEM:
       if ((addr_mode & ADDR_INDIRECT) && GET_MODE_SIZE (mode) <= 2)
-        return register_indirect_p (XEXP (operand, 0), mode,
-                                    addr_mode & (ADDR_STRICT | ADDR_OFFSET));
+        return m68hc11_valid_addressing_p (XEXP (operand, 0), mode,
+                                   addr_mode & (ADDR_STRICT | ADDR_OFFSET));
       return 0;
 
     case POST_INC:
@@ -578,8 +570,8 @@ register_indirect_p (rtx operand, enum m
     case POST_DEC:
     case PRE_DEC:
       if (addr_mode & ADDR_INCDEC)
-	return register_indirect_p (XEXP (operand, 0), mode,
-                                    addr_mode & ADDR_STRICT);
+	return m68hc11_valid_addressing_p (XEXP (operand, 0), mode,
+                                   addr_mode & ADDR_STRICT);
       return 0;
 
     case PLUS:
@@ -675,7 +667,7 @@ m68hc11_small_indexed_indirect_p (rtx op
     return 1;
 
   addr_mode = m68hc11_mov_addr_mode | (reload_completed ? ADDR_STRICT : 0);
-  if (!register_indirect_p (operand, mode, addr_mode))
+  if (!m68hc11_valid_addressing_p (operand, mode, addr_mode))
     return 0;
 
   if (TARGET_M6812 && GET_CODE (operand) == PLUS
@@ -730,7 +722,7 @@ m68hc11_register_indirect_p (rtx operand
 
   operand = XEXP (operand, 0);
   addr_mode = m68hc11_addr_mode | (reload_completed ? ADDR_STRICT : 0);
-  return register_indirect_p (operand, mode, addr_mode);
+  return m68hc11_valid_addressing_p (operand, mode, addr_mode);
 }
 
 static int
@@ -749,7 +741,7 @@ go_if_legitimate_address_internal (rtx o
       return 1;
     }
   addr_mode = m68hc11_addr_mode | (strict ? ADDR_STRICT : 0);
-  if (register_indirect_p (operand, mode, addr_mode))
+  if (m68hc11_valid_addressing_p (operand, mode, addr_mode))
     {
       return 1;
     }
@@ -995,7 +987,7 @@ m68hc11_indirect_p (rtx operand, enum ma
 
       operand = XEXP (operand, 0);
       addr_mode = m68hc11_addr_mode | (reload_completed ? ADDR_STRICT : 0);
-      return register_indirect_p (operand, mode, addr_mode);
+      return m68hc11_valid_addressing_p (operand, mode, addr_mode);
     }
   return 0;
 }
@@ -3110,10 +3102,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:
@@ -3128,10 +3123,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:
@@ -3162,11 +3157,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))
@@ -3183,6 +3219,7 @@ m68hc11_gen_movhi (rtx insn, rtx *operan
 		  ops[0] = to;
 		  ops[1] = operands[2];
 		  m68hc11_gen_movhi (insn, ops);
+                  return;
 		}
 	      else
 		{
@@ -3190,19 +3227,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;
     }
@@ -3530,8 +3559,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
Index: config/m68hc11/m68hc11.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/m68hc11/m68hc11.h,v
retrieving revision 1.92
diff -u -p -r1.92 m68hc11.h
--- config/m68hc11/m68hc11.h	2 Apr 2005 20:44:38 -0000	1.92
+++ config/m68hc11/m68hc11.h	8 May 2005 19:39:36 -0000
@@ -1037,6 +1037,13 @@ typedef struct m68hc11_args
 
 /* Addressing modes, and classification of registers for them.  */
 
+#define ADDR_STRICT       0x01  /* Accept only registers in class A_REGS  */
+#define ADDR_INCDEC       0x02  /* Post/Pre inc/dec */
+#define ADDR_INDEXED      0x04  /* D-reg index */
+#define ADDR_OFFSET       0x08
+#define ADDR_INDIRECT     0x10  /* Accept (mem (mem ...)) for [n,X] */
+#define ADDR_CONST        0x20  /* Accept const and symbol_ref  */
+
 /* The 68HC12 has all the post/pre increment/decrement modes.  */
 #define HAVE_POST_INCREMENT (TARGET_M6812 && TARGET_AUTO_INC_DEC)
 #define HAVE_PRE_INCREMENT  (TARGET_M6812 && TARGET_AUTO_INC_DEC)
Index: config/m68hc11/m68hc11.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/m68hc11/m68hc11.md,v
retrieving revision 1.69
diff -u -p -r1.69 m68hc11.md
--- config/m68hc11/m68hc11.md	8 May 2005 17:52:22 -0000	1.69
+++ config/m68hc11/m68hc11.md	8 May 2005 19:39:37 -0000
@@ -689,8 +689,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"))]
   ""
   "#"
@@ -886,18 +886,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"
   "*
 {
@@ -905,6 +896,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"))]
@@ -1237,7 +1237,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"))]
   ""
   "#")
 
@@ -2382,7 +2382,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")))]
   ""
   "*
 {
@@ -2716,7 +2716,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")))]
   ""
   "*
@@ -2731,7 +2731,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"))))]
   ""
   "*
@@ -2751,7 +2751,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")))]
   ""
   "*
@@ -3326,8 +3326,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")))]
   ""
   "*
 {
@@ -3544,8 +3544,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")))]
   ""
   "*
 {
@@ -3636,8 +3636,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")))]
   ""
   "*
 {
@@ -6914,14 +6914,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)));")
Index: config/m68hc11/predicates.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/m68hc11/predicates.md,v
retrieving revision 1.1
diff -u -p -r1.1 predicates.md
--- config/m68hc11/predicates.md	2 Apr 2005 19:31:23 -0000	1.1
+++ config/m68hc11/predicates.md	8 May 2005 19:39:37 -0000
@@ -173,6 +173,7 @@
   if (GET_CODE (op) == MEM)
     {
       rtx op0 = XEXP (op, 0);
+      int addr_mode;
 
       if (symbolic_memory_operand (op0, mode))
 	return 1;
@@ -180,10 +181,20 @@
       if (IS_STACK_PUSH (op))
 	return 1;
 
-      if (m68hc11_register_indirect_p (op, mode))
-	return 1;
-
-      return 0;
+      if (GET_CODE (op) == REG && reload_in_progress
+          && REGNO (op) >= FIRST_PSEUDO_REGISTER
+          && reg_equiv_memory_loc[REGNO (op)])
+         {
+            op = reg_equiv_memory_loc[REGNO (op)];
+            op = eliminate_regs (op, 0, NULL_RTX);
+         }
+      if (GET_CODE (op) != MEM)
+         return 0;
+
+      op0 = XEXP (op, 0);
+      addr_mode = m68hc11_addr_mode | (reload_completed ? ADDR_STRICT : 0);
+      addr_mode &= ~ADDR_INDIRECT;
+      return m68hc11_valid_addressing_p (op0, mode, addr_mode);
     }
 
   return register_operand (op, mode);

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]