OSDN Git Service

* config/m68hc11/predicates.md (reg_or_some_mem_operand): Do not allow
authorciceron <ciceron@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 8 May 2005 19:53:42 +0000 (19:53 +0000)
committerciceron <ciceron@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 8 May 2005 19:53:42 +0000 (19:53 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@99405 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/m68hc11/m68hc11-protos.h
gcc/config/m68hc11/m68hc11.c
gcc/config/m68hc11/m68hc11.h
gcc/config/m68hc11/m68hc11.md
gcc/config/m68hc11/predicates.md

index ff70fab..3cb7bf4 100644 (file)
@@ -1,5 +1,28 @@
 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.
+
+2005-05-08  Stephane Carrez  <stcarrez@nerim.fr>
+
        PR target/19051
        * config/m68hc11/m68hc11.md ("mulqi3"): Use general_operand for operand
        1 and fix constraints.
index 4a123e8..aad6f4a 100644 (file)
@@ -98,6 +98,7 @@ extern int memory_indexed_operand (rtx, enum machine_mode);
 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 93fe2c3..17d0dd4 100644 (file)
@@ -65,7 +65,6 @@ static rtx simplify_logical (enum machine_mode, int, rtx, rtx *);
 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_index[FIRST_PSEUDO_REGISTER];
    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, enum reg_class class)
 /* 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 machine_mode mode, int addr_mode)
     {
     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 machine_mode mode, int addr_mode)
     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 operand, enum machine_mode mode)
     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, enum machine_mode mode)
 
   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 operand, enum machine_mode mode,
       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 machine_mode mode)
 
       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 *operands)
 
   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 *operands)
            }
          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 *operands)
          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 *operands)
                  ops[0] = to;
                  ops[1] = operands[2];
                  m68hc11_gen_movhi (insn, ops);
+                  return;
                }
              else
                {
@@ -3190,19 +3227,11 @@ m68hc11_gen_movhi (rtx insn, rtx *operands)
                   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 *operands)
        }
       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 b513dcd..02b0856 100644 (file)
@@ -1037,6 +1037,13 @@ typedef struct m68hc11_args
 \f
 /* 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 8459100..c03191c 100644 (file)
    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"))]
   ""
   "#"
     }
 }")
 
-(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"
   "*
 {
   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"))]
   [(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"))]
   ""
   "#")
 
   [(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")))]
   ""
   "*
 {
 
 (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")))]
   ""
   "*
 
 (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"))))]
   ""
   "*
 
 (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")))]
   ""
   "*
 
 (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")))]
   ""
   "*
 {
 
 (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")))]
   ""
   "*
 {
 
 (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")))]
   ""
   "*
 {
 ;;
 ;; 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 67d1f98..904c5b1 100644 (file)
   if (GET_CODE (op) == MEM)
     {
       rtx op0 = XEXP (op, 0);
+      int addr_mode;
 
       if (symbolic_memory_operand (op0, mode))
        return 1;
       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);