OSDN Git Service

* config/m32c/m32c-pragma.c (m32c_register_pragmas): Register the
authordj <dj@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 22 Oct 2010 21:41:42 +0000 (21:41 +0000)
committerdj <dj@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 22 Oct 2010 21:41:42 +0000 (21:41 +0000)
__far address space.
* config/m32c/m32c.h (ADDR_SPACE_FAR): New.  Add support for
"__far" address space for R8C and M16C processor variants.
* config/m32c/m32c.c (m32c_addr_space_legitimate_address_p): New.
(far_addr_space_p): New.
(encode_pattern_1): Add sign and zero extend support.
(m32c_hard_regno_nregs_1): Large pointers in A16 mode are SImode.
(m32c_extra_constraint_p2): Add SF constraint.
(m32c_legitimate_address_p): Support __far addresses.
(m32c_addr_space_pointer_mode): New.
(m32c_addr_space_address_mode): New.
(m32c_addr_space_legitimate_address_p): New.
(m32c_addr_space_legitimize_address): New.
(m32c_addr_space_subset_p): New.
(m32c_addr_space_convert): New.
(conversions): Add __far operand patterns.
(m32c_prepare_move): Force constants into registers for __far
moves.
(m32c_split_move): __far moves are always split.
* config/m32c/addsub.md (addsi3_1): Support SImode symbols.
* config/m32c/mov.md (mov<mode>_far_op1): New.
(mov<mode>_far_op2): New.
(movqi_op): Add __far (SF) support.
(movhi_op): Likewise.
(movsi_splittable): Split A1A0 also.

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

gcc/ChangeLog
gcc/config/m32c/addsub.md
gcc/config/m32c/m32c-pragma.c
gcc/config/m32c/m32c.c
gcc/config/m32c/m32c.h
gcc/config/m32c/mov.md

index 313ad11..2ddd304 100644 (file)
@@ -1,3 +1,32 @@
+2010-10-22  DJ Delorie  <dj@redhat.com>
+
+       * config/m32c/m32c-pragma.c (m32c_register_pragmas): Register the
+       __far address space.
+       * config/m32c/m32c.h (ADDR_SPACE_FAR): New.  Add support for
+       "__far" address space for R8C and M16C processor variants.
+       * config/m32c/m32c.c (m32c_addr_space_legitimate_address_p): New.
+       (far_addr_space_p): New.
+       (encode_pattern_1): Add sign and zero extend support.
+       (m32c_hard_regno_nregs_1): Large pointers in A16 mode are SImode.
+       (m32c_extra_constraint_p2): Add SF constraint.
+       (m32c_legitimate_address_p): Support __far addresses.
+       (m32c_addr_space_pointer_mode): New.
+       (m32c_addr_space_address_mode): New.
+       (m32c_addr_space_legitimate_address_p): New.
+       (m32c_addr_space_legitimize_address): New.
+       (m32c_addr_space_subset_p): New.
+       (m32c_addr_space_convert): New.
+       (conversions): Add __far operand patterns.
+       (m32c_prepare_move): Force constants into registers for __far
+       moves.
+       (m32c_split_move): __far moves are always split.
+       * config/m32c/addsub.md (addsi3_1): Support SImode symbols.
+       * config/m32c/mov.md (mov<mode>_far_op1): New.
+       (mov<mode>_far_op2): New.
+       (movqi_op): Add __far (SF) support.
+       (movhi_op): Likewise.
+       (movsi_splittable): Split A1A0 also.
+
 2010-10-22  Artjoms Sinkarovs <artyom.shinakroff@gmail.com>
        Andrew Pinski <pinskia@gmail.com>
 
index ea4c817..4463273 100644 (file)
     case 1:
       return \"add.w %X2,%h0\;adcf.w %H0\";
     case 2:
-      output_asm_insn (\"add.w %X2,%h0\",operands);
-      operands[2]= GEN_INT (INTVAL (operands[2]) >> 16);
-      return \"adc.w %X2,%H0\";
+      if (GET_CODE (operands[2]) == SYMBOL_REF)
+        {
+          output_asm_insn (\"add.w #%%lo(%d2),%h0\",operands);
+          return \"adc.w #%%hi(%d2),%H0\";
+        }
+      else
+        {
+          output_asm_insn (\"add.w %X2,%h0\",operands);
+          operands[2]= GEN_INT (INTVAL (operands[2]) >> 16);
+          return \"adc.w %X2,%H0\";
+        }
     case 3:
       return \"add.w %h2,%h0\;adc.w %H2,%H0\";
     case 4:
index b25c063..f8a66ad 100644 (file)
@@ -131,4 +131,13 @@ m32c_register_pragmas (void)
   c_register_pragma ("GCC", "memregs", m32c_pragma_memregs);
   c_register_pragma (NULL, "ADDRESS", m32c_pragma_address);
   c_register_pragma (NULL, "address", m32c_pragma_address);
+
+  /* R8C and M16C have 16-bit pointers in a 20-bit address zpace.
+     M32C has 24-bit pointers in a 24-bit address space, so does not
+     need far pointers, but we accept the qualifier anyway, as a
+     no-op.  */
+  if (TARGET_A16)
+    c_register_addr_space ("__far", ADDR_SPACE_FAR);
+  else
+    c_register_addr_space ("__far", ADDR_SPACE_GENERIC);
 }
index 39b3393..4659db3 100644 (file)
@@ -73,6 +73,7 @@ static bool m32c_fixed_condition_code_regs (unsigned int *, unsigned int *);
 static struct machine_function *m32c_init_machine_status (void);
 static void m32c_insert_attributes (tree, tree *);
 static bool m32c_legitimate_address_p (enum machine_mode, rtx, bool);
+static bool m32c_addr_space_legitimate_address_p (enum machine_mode, rtx, bool, addr_space_t);
 static rtx m32_function_arg (CUMULATIVE_ARGS *, enum machine_mode
                             const_tree, bool);
 static bool m32c_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
@@ -124,6 +125,18 @@ static GTY(()) rtx patternr[30];
 #define IS_CR_REGNO(regno) ((regno) >= SB_REGNO && (regno) <= PC_REGNO)
 #define IS_CR_REG(rtx) (GET_CODE (rtx) == REG && IS_CR_REGNO (REGNO (rtx)))
 
+static int
+far_addr_space_p (rtx x)
+{
+  if (GET_CODE (x) != MEM)
+    return 0;
+#if DEBUG0
+  fprintf(stderr, "\033[35mfar_addr_space: "); debug_rtx(x);
+  fprintf(stderr, " = %d\033[0m\n", MEM_ADDR_SPACE (x) == ADDR_SPACE_FAR);
+#endif
+  return MEM_ADDR_SPACE (x) == ADDR_SPACE_FAR;
+}
+
 /* We do most RTX matching by converting the RTX into a string, and
    using string compares.  This vastly simplifies the logic in many of
    the functions in this file.
@@ -166,6 +179,16 @@ encode_pattern_1 (rtx x)
     case CONST:
       encode_pattern_1 (XEXP (x, 0));
       break;
+    case SIGN_EXTEND:
+      *patternp++ = '^';
+      *patternp++ = 'S';
+      encode_pattern_1 (XEXP (x, 0));
+      break;
+    case ZERO_EXTEND:
+      *patternp++ = '^';
+      *patternp++ = 'Z';
+      encode_pattern_1 (XEXP (x, 0));
+      break;
     case PLUS:
       *patternp++ = '+';
       encode_pattern_1 (XEXP (x, 0));
@@ -553,7 +576,7 @@ m32c_hard_regno_nregs_1 (int regno, enum machine_mode mode)
     return nregs_table[regno].qi_regs;
   if (GET_MODE_SIZE (mode) <= 2)
     return nregs_table[regno].hi_regs;
-  if (regno == A0_REGNO && mode == PSImode && TARGET_A16)
+  if (regno == A0_REGNO && mode == SImode && TARGET_A16)
     return 2;
   if ((GET_MODE_SIZE (mode) <= 3 || mode == PSImode) && TARGET_A24)
     return nregs_table[regno].pi_regs;
@@ -993,6 +1016,8 @@ m32c_const_ok_for_constraint_p (HOST_WIDE_INT value,
   return 0;
 }
 
+#define A0_OR_PSEUDO(x) (IS_REG(x, A0_REGNO) || REGNO (x) >= FIRST_PSEUDO_REGISTER)
+
 /* Implements EXTRA_CONSTRAINT_STR (see next function too).  'S' is
    for memory constraints, plus "Rpa" for PARALLEL rtx's we use for
    call return values.  */
@@ -1000,6 +1025,29 @@ int
 m32c_extra_constraint_p2 (rtx value, char c ATTRIBUTE_UNUSED, const char *str)
 {
   encode_pattern (value);
+
+  if (far_addr_space_p (value))
+    {
+      if (memcmp (str, "SF", 2) == 0)
+       {
+         return (   (RTX_IS ("mr")
+                     && A0_OR_PSEUDO (patternr[1])
+                     && GET_MODE (patternr[1]) == SImode)
+                    || (RTX_IS ("m+^Sri")
+                        && A0_OR_PSEUDO (patternr[4])
+                        && GET_MODE (patternr[4]) == HImode)
+                    || (RTX_IS ("m+^Srs")
+                        && A0_OR_PSEUDO (patternr[4])
+                        && GET_MODE (patternr[4]) == HImode)
+                    || (RTX_IS ("m+^S+ris")
+                        && A0_OR_PSEUDO (patternr[5])
+                        && GET_MODE (patternr[5]) == HImode)
+                    || RTX_IS ("ms")
+                    );
+       }
+      return 0;
+    }
+
   if (memcmp (str, "Sd", 2) == 0)
     {
       /* This is the common "src/dest" address */
@@ -1067,6 +1115,10 @@ m32c_extra_constraint_p2 (rtx value, char c ATTRIBUTE_UNUSED, const char *str)
     {
       return r1h_operand (value, QImode);
     }
+  else if (memcmp (str, "SF", 2) == 0)
+    {
+      return 0;
+    }
 
   gcc_assert (str[0] != 'S');
 
@@ -1837,6 +1889,11 @@ m32c_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
   if (CONSTANT_P (x))
     return 1;
 
+  if (TARGET_A16 && GET_MODE (x) != HImode && GET_MODE (x) != SImode)
+    return 0;
+  if (TARGET_A24 && GET_MODE (x) != PSImode)
+    return 0;
+
   /* Wide references to memory will be split after reload, so we must
      ensure that all parts of such splits remain legitimate
      addresses.  */
@@ -1871,11 +1928,13 @@ m32c_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
         to please the assembler.  */
       switch (REGNO (patternr[0]))
        {
-       case A0_REGNO:
        case A1_REGNO:
        case SB_REGNO:
        case FB_REGNO:
        case SP_REGNO:
+         if (TARGET_A16 && GET_MODE (x) == SImode)
+           return 0;
+       case A0_REGNO:
          return 1;
 
        default:
@@ -1884,6 +1943,10 @@ m32c_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
          return 0;
        }
     }
+
+  if (TARGET_A16 && GET_MODE (x) == SImode)
+    return 0;
+
   if (RTX_IS ("+ri"))
     {
       /* This is more interesting, because different base registers
@@ -2097,6 +2160,204 @@ m32c_legitimate_constant_p (rtx x ATTRIBUTE_UNUSED)
 }
 
 
+/* Return the appropriate mode for a named address pointer.  */
+#undef TARGET_ADDR_SPACE_POINTER_MODE
+#define TARGET_ADDR_SPACE_POINTER_MODE m32c_addr_space_pointer_mode
+static enum machine_mode
+m32c_addr_space_pointer_mode (addr_space_t addrspace)
+{
+  switch (addrspace)
+    {
+    case ADDR_SPACE_GENERIC:
+      return TARGET_A24 ? PSImode : HImode;
+    case ADDR_SPACE_FAR:
+      return SImode;
+    default:
+      gcc_unreachable ();
+    }
+}
+
+/* Return the appropriate mode for a named address address.  */
+#undef TARGET_ADDR_SPACE_ADDRESS_MODE
+#define TARGET_ADDR_SPACE_ADDRESS_MODE m32c_addr_space_address_mode
+static enum machine_mode
+m32c_addr_space_address_mode (addr_space_t addrspace)
+{
+  switch (addrspace)
+    {
+    case ADDR_SPACE_GENERIC:
+      return TARGET_A24 ? PSImode : HImode;
+    case ADDR_SPACE_FAR:
+      return SImode;
+    default:
+      gcc_unreachable ();
+    }
+}
+
+/* Like m32c_legitimate_address_p, except with named addresses.  */
+#undef TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P
+#define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P \
+  m32c_addr_space_legitimate_address_p
+static bool
+m32c_addr_space_legitimate_address_p (enum machine_mode mode, rtx x,
+                                     bool strict, addr_space_t as)
+{
+  if (as == ADDR_SPACE_FAR)
+    {
+      if (TARGET_A24)
+       return 0;
+      encode_pattern (x);
+      if (RTX_IS ("r"))
+       {
+         if (GET_MODE (x) != SImode)
+           return 0;
+         switch (REGNO (patternr[0]))
+           {
+           case A0_REGNO:
+             return 1;
+
+           default:
+             if (IS_PSEUDO (patternr[0], strict))
+               return 1;
+             return 0;
+           }
+       }
+      if (RTX_IS ("+^Sri"))
+       {
+         int rn = REGNO (patternr[3]);
+         HOST_WIDE_INT offs = INTVAL (patternr[4]);
+         if (GET_MODE (patternr[3]) != HImode)
+           return 0;
+         switch (rn)
+           {
+           case A0_REGNO:
+             return (offs >= 0 && offs <= 0xfffff);
+
+           default:
+             if (IS_PSEUDO (patternr[3], strict))
+               return 1;
+             return 0;
+           }
+       }
+      if (RTX_IS ("+^Srs"))
+       {
+         int rn = REGNO (patternr[3]);
+         if (GET_MODE (patternr[3]) != HImode)
+           return 0;
+         switch (rn)
+           {
+           case A0_REGNO:
+             return 1;
+
+           default:
+             if (IS_PSEUDO (patternr[3], strict))
+               return 1;
+             return 0;
+           }
+       }
+      if (RTX_IS ("+^S+ris"))
+       {
+         int rn = REGNO (patternr[4]);
+         if (GET_MODE (patternr[4]) != HImode)
+           return 0;
+         switch (rn)
+           {
+           case A0_REGNO:
+             return 1;
+
+           default:
+             if (IS_PSEUDO (patternr[4], strict))
+               return 1;
+             return 0;
+           }
+       }
+      if (RTX_IS ("s"))
+       {
+         return 1;
+       }
+      return 0;
+    }
+
+  else if (as != ADDR_SPACE_GENERIC)
+    gcc_unreachable ();
+
+  return m32c_legitimate_address_p (mode, x, strict);
+}
+
+/* Like m32c_legitimate_address, except with named address support.  */
+#undef TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS
+#define TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS m32c_addr_space_legitimize_address
+static rtx
+m32c_addr_space_legitimize_address (rtx x, rtx oldx, enum machine_mode mode,
+                                   addr_space_t as)
+{
+  if (as != ADDR_SPACE_GENERIC)
+    {
+#if DEBUG0
+      fprintf (stderr, "\033[36mm32c_addr_space_legitimize_address for mode %s\033[0m\n", mode_name[mode]);
+      debug_rtx (x);
+      fprintf (stderr, "\n");
+#endif
+
+      if (GET_CODE (x) != REG)
+       {
+         x = force_reg (SImode, x);
+       }
+      return x;
+    }
+
+  return m32c_legitimize_address (x, oldx, mode);
+}
+
+/* Determine if one named address space is a subset of another.  */
+#undef TARGET_ADDR_SPACE_SUBSET_P
+#define TARGET_ADDR_SPACE_SUBSET_P m32c_addr_space_subset_p
+static bool
+m32c_addr_space_subset_p (addr_space_t subset, addr_space_t superset)
+{
+  gcc_assert (subset == ADDR_SPACE_GENERIC || subset == ADDR_SPACE_FAR);
+  gcc_assert (superset == ADDR_SPACE_GENERIC || superset == ADDR_SPACE_FAR);
+
+  if (subset == superset)
+    return true;
+
+  else
+    return (subset == ADDR_SPACE_GENERIC && superset == ADDR_SPACE_FAR);
+}
+
+#undef TARGET_ADDR_SPACE_CONVERT
+#define TARGET_ADDR_SPACE_CONVERT m32c_addr_space_convert
+/* Convert from one address space to another.  */
+static rtx
+m32c_addr_space_convert (rtx op, tree from_type, tree to_type)
+{
+  addr_space_t from_as = TYPE_ADDR_SPACE (TREE_TYPE (from_type));
+  addr_space_t to_as = TYPE_ADDR_SPACE (TREE_TYPE (to_type));
+  rtx result;
+
+  gcc_assert (from_as == ADDR_SPACE_GENERIC || from_as == ADDR_SPACE_FAR);
+  gcc_assert (to_as == ADDR_SPACE_GENERIC || to_as == ADDR_SPACE_FAR);
+
+  if (to_as == ADDR_SPACE_GENERIC && from_as == ADDR_SPACE_FAR)
+    {
+      /* This is unpredictable, as we're truncating off usable address
+        bits.  */
+
+      result = gen_reg_rtx (HImode);
+      emit_move_insn (result, simplify_subreg (HImode, op, SImode, 0));
+      return result;
+    }
+  else if (to_as == ADDR_SPACE_FAR && from_as == ADDR_SPACE_GENERIC)
+    {
+      /* This always works.  */
+      result = gen_reg_rtx (SImode);
+      emit_insn (gen_zero_extendhisi2 (result, op));
+      return result;
+    }
+  else
+    gcc_unreachable ();
+}
+
 /* Condition Code Status */
 
 #undef TARGET_FIXED_CONDITION_CODE_REGS
@@ -2350,6 +2611,12 @@ const conversions[] = {
   { 0, "mr", "z[1]" },
   { 0, "m+ri", "3[2]" },
   { 0, "m+rs", "3[2]" },
+  { 0, "m+^Zrs", "5[4]" },
+  { 0, "m+^Zri", "5[4]" },
+  { 0, "m+^Z+ris", "7+6[5]" },
+  { 0, "m+^Srs", "5[4]" },
+  { 0, "m+^Sri", "5[4]" },
+  { 0, "m+^S+ris", "7+6[5]" },
   { 0, "m+r+si", "4+5[2]" },
   { 0, "ms", "1" },
   { 0, "mi", "1" },
@@ -3392,6 +3659,11 @@ m32c_subreg (enum machine_mode outer,
 int
 m32c_prepare_move (rtx * operands, enum machine_mode mode)
 {
+  if (far_addr_space_p (operands[0])
+      && CONSTANT_P (operands[1]))
+    {
+      operands[1] = force_reg (GET_MODE (operands[0]), operands[1]);
+    }
   if (TARGET_A16 && mode == PSImode)
     return m32c_split_move (operands, mode, 1);
   if ((GET_CODE (operands[0]) == MEM)
@@ -3497,6 +3769,11 @@ m32c_split_move (rtx * operands, enum machine_mode mode, int split_all)
   if (m32c_extra_constraint_p (operands[0], 'S', "Ss"))
     split_all = 3;
 
+  if (TARGET_A16
+      && (far_addr_space_p (operands[0])
+         || far_addr_space_p (operands[1])))
+    split_all |= 1;
+
   /* We don't need to split these.  */
   if (TARGET_A24
       && split_all != 3
index c0eccb4..2159e5c 100644 (file)
@@ -567,6 +567,10 @@ typedef struct m32c_cumulative_args
 
 #define LEGITIMATE_CONSTANT_P(X) m32c_legitimate_constant_p (X)
 
+/* Address spaces.  */
+#define ADDR_SPACE_FAR 1
+
+
 /* Condition Code Status */
 
 #define REVERSIBLE_CC_MODE(MODE) 1
index 98a0db2..5ebd384 100644 (file)
 ;; example is code like this: a = *b where both a and b are spilled to
 ;; the stack.
 
+(define_insn "mov<mode>_far_op1"
+  [(set (match_operand:QHI 0 "register_operand" "=Rhi")
+       (mem:QHI (plus:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "Ra0"))
+                        (match_operand 2 "immediate_operand" "si"))))
+   ]
+  ""
+  "lde.<bwl>\t%D2[%1],%0"
+  [(set_attr "flags" "sz")]
+  )
+
+(define_insn "mov<mode>_far_op2"
+  [(set (mem:QHI (plus:SI (sign_extend:SI (match_operand:HI 0 "register_operand" "Ra0"))
+                        (match_operand 1 "immediate_operand" "si")))
+       (match_operand:QHI 2 "register_operand"
+                         "=Rhi"))
+   ]
+  ""
+  "ste.<bwl>\t%2,%D1[%0]"
+  [(set_attr "flags" "sz")]
+  )
+
 ;; Match push/pop before mov.b for passing char as arg,
 ;; e.g. stdlib/efgcvt.c.
 (define_insn "movqi_op"
   [(set (match_operand:QI 0 "m32c_nonimmediate_operand"
-                         "=Rqi*Rmm, <,          RqiSd*Rmm, SdSs,    Rqi*Rmm, Sd")
+                         "=SF,Rhi*Rmm, Rqi*Rmm, <,          RqiSd*Rmm, SdSs,    Rqi*Rmm, Sd")
        (match_operand:QI 1 "m32c_any_operand"
-                         "iRqi*Rmm, iRqiSd*Rmm, >,         Rqi*Rmm, SdSs,    i"))]
+                         "Rhi*Rmm,SF, iRqi*Rmm, iRqiSd*Rmm, >,         Rqi*Rmm, SdSs,    i"))]
   "m32c_mov_ok (operands, QImode)"
   "@
+    lde.b\t%1,%0
+    ste.b\t%1,%0
     mov.b\t%1,%0
     push.b\t%1
     pop.b\t%0
     mov.b\t%1,%0
     mov.b\t%1,%0
     mov.b\t%1,%0"
-  [(set_attr "flags" "sz,*,*,sz,sz,sz")]
+  [(set_attr "flags" "sz,sz,sz,*,*,sz,sz,sz")]
   )
 
 (define_expand "movqi"
 
 (define_insn "movhi_op"
   [(set (match_operand:HI 0 "m32c_nonimmediate_operand"
-                         "=Rhi*Rmm,     Sd, SdSs,   *Rcr, RhiSd*Rmm, <, RhiSd*Rmm, <, *Rcr")
+                         "=SF,Rhi*Rmm, Rhi*Rmm,     Sd, SdSs,   *Rcr, RhiSd*Rmm, <, RhiSd*Rmm, <, *Rcr")
        (match_operand:HI 1 "m32c_any_operand"
-                         "iRhi*RmmSdSs, i, Rhi*Rmm, RhiSd*Rmm, *Rcr, iRhiSd*Rmm, >, *Rcr, >"))]
+                         " Rhi*Rmm,SF, iRhi*RmmSdSs, i, Rhi*Rmm, RhiSd*Rmm, *Rcr, iRhiSd*Rmm, >, *Rcr, >"))]
   "m32c_mov_ok (operands, HImode)"
   "@
+   ste.w\t%1,%0
+   lde.w\t%1,%0
    mov.w\t%1,%0
    mov.w\t%1,%0
    mov.w\t%1,%0
@@ -70,7 +95,7 @@
    pop.w\t%0
    pushc\t%1
    popc\t%0"
-  [(set_attr "flags" "sz,sz,sz,n,n,n,n,n,n")]
+  [(set_attr "flags" "sz,sz,sz,sz,sz,n,n,n,n,n,n")]
   )
 
 (define_expand "movhi"
 
 ; All SI moves are split if TARGET_A16
 (define_insn_and_split "movsi_splittable"
-  [(set (match_operand:SI 0 "m32c_nonimmediate_operand" "=Rsi<*Rmm,RsiSd*Rmm,Ss")
-       (match_operand:SI 1 "m32c_any_operand" "iRsiSd*Rmm,iRsi>*Rmm,Rsi*Rmm"))]
+  [(set (match_operand:SI 0 "m32c_nonimmediate_operand" "=RsiRaa<*Rmm,  RsiRaaSd*Rmm,  Ss")
+       (match_operand:SI 1 "m32c_any_operand" "iRsiRaaSd*Rmm,  iRsiRaa>*Rmm,  RsiRaa*Rmm"))]
   "TARGET_A16"
   "#"
-  "TARGET_A16 && reload_completed"
+  "TARGET_A16"
   [(pc)]
   "m32c_split_move (operands, SImode, 1); DONE;"
   )