OSDN Git Service

mn10300: Re-write move patterns.
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 19 Jan 2011 16:57:37 +0000 (16:57 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 19 Jan 2011 16:57:37 +0000 (16:57 +0000)
Use the "D" and "A" constraints, and the enabled attribute to
unify all ofthe integer move patterns.  Delete the fake double
word move patterns; let the middle-end generate subregs as required.

Unfortunately, this somehow exposes a register pressure problem
with the udivmod pattern.  This is properly fixed with subsequent
patches that expose the MDR register.

In the meantime it is highly desirable to to preserve bisect-ability
of the patch series, so disable this pattern for AM30.

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

gcc/ChangeLog
gcc/config/mn10300/mn10300.md

index 9af2456..46ebaee 100644 (file)
@@ -1,3 +1,20 @@
+2011-01-19  Richard Henderson  <rth@redhat.com>
+
+       * config/mn10300/mn10300.md (*am33_movqi, *mn10300_movqi): Merge into
+       (*movqi_internal): ... here.
+       (*am33_movhi, *mn10300_movhi): Merge into...
+       (*movhi_internal): ... here.
+       (*movsi_internal): Use "r" instead of "dax" in constraints.  Use "A"
+       as the source/destination of moves from/to SP.
+       (movsf): Only allow for AM33-2.
+       (*movsf_internal): Use "r" instead of "dax"; use "F" instead of 
+       any integer constant constraint.  Only allow for AM33-2.  Tidy
+       all of the alternative outputs.
+       (movdi, movdf, *am33_2_movdf, *mn10300_movdf): Remove.
+       (udivmodsi4): Delete expander and promote *udivmodsi4.  Disallow
+       for MN103.
+       (udivsi3, umodsi3): New patterns for MN103 only.
+
 2011-01-19  Joern Rennecke  <amylaar@spamcop.net>
 
        * doc/tm.texi.in: Spell out that a lack of register class unions
index 8ae52c9..9cddebf 100644 (file)
   [(set (match_operand:QI 0 "nonimmediate_operand")
        (match_operand:QI 1 "general_operand"))]
   ""
-  "
 {
   /* One of the ops has to be in a register.  */
   if (!register_operand (operand0, QImode)
       && !register_operand (operand1, QImode))
-    operands[1] = copy_to_mode_reg (QImode, operand1);
-}")
-
-(define_insn "*am33_movqi"
-  [(set (match_operand:QI 0 "nonimmediate_operand"
-                         ;; 0       1      2      3     4       5
-                         "=d*x*a*f, d*x*a, d*x*a, m,   *f,      d*x*a")
-       (match_operand:QI 1 "general_operand"
-                          "0,       d*xai, m,     d*xa, d*xa*f, *f"))]
-  "TARGET_AM33
-   && (register_operand (operands[0], QImode)
-       || register_operand (operands[1], QImode))"
-  "*
-  {
-    switch (which_alternative)
-      {
-      case 0:
-        return \"nop\";
-      case 1:
-        gcc_assert (! CONST_DOUBLE_P (operands[1]));
-
-        if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
-           && CONST_INT_P (operands[1]))
-         {
-           HOST_WIDE_INT val = INTVAL (operands[1]);
-
-           if (((val & 0x80) && ! (val & 0xffffff00))
-               || ((val & 0x800000) && ! (val & 0xff000000)))
-             return \"movu %1,%0\";
-         }
-        return \"mov %1,%0\";
-      case 2:
-      case 3:
-        return \"movbu %1,%0\";
-      case 4:
-      case 5:
-        return \"fmov %1,%0\";
-      default:
-        gcc_unreachable ();
-      }
-  }"
-  [(set_attr_alternative "timings"
-                        [(const_int 11)
-                         (if_then_else (eq_attr "cpu" "am34")
-                                       (const_int 11) (const_int 22))
-                         (if_then_else (eq_attr "cpu" "am34")
-                                       (const_int 13) (const_int 24))
-                         (if_then_else (eq_attr "cpu" "am34")
-                                       (const_int 13) (const_int 24))
-                         (if_then_else (eq_attr "cpu" "am34")
-                                       (const_int 47) (const_int 25))
-                         (if_then_else (eq_attr "cpu" "am34")
-                                       (const_int 47) (const_int 25))
-                        ])
-  ]
-)
+    operands[1] = force_reg (QImode, operand1);
+})
 
-(define_insn "*mn10300_movqi"
-  [(set (match_operand:QI 0 "nonimmediate_operand" "=d*a,d,d,!*a,d*a,d,m")
-       (match_operand:QI 1 "general_operand"       "0,  I,i,i,  da, m,d"))]
-  "register_operand (operands[0], QImode)
-   || register_operand (operands[1], QImode)"
-  "*
+(define_insn "*movqi_internal"
+  [(set (match_operand:QI 0 "nonimmediate_operand" "=*r,D*r,D*r,D,m")
+       (match_operand:QI 1 "general_operand"      "  0,D*r,  i,m,D"))]
+  "(register_operand (operands[0], QImode)
+    || register_operand (operands[1], QImode))"
 {
   switch (which_alternative)
     {
     case 0:
-      return \"nop\";
+      return "";
     case 1:
     case 2:
+      return "mov %1,%0";
     case 3:
     case 4:
-      gcc_assert (! CONST_DOUBLE_P (operands[1]));
-      return \"mov %1,%0\";
-    case 5:
-    case 6:
-      return \"movbu %1,%0\";
+      return "movbu %1,%0";
     default:
       gcc_unreachable ();
     }
-}"
+}
   [(set_attr_alternative "timings"
-                        [(const_int 11)
-                         (const_int 11)
-                         (if_then_else (eq_attr "cpu" "am34")
-                                       (const_int 11) (const_int 22))
-                         (if_then_else (eq_attr "cpu" "am34")
-                                       (const_int 11) (const_int 22))
-                         (if_then_else (eq_attr "cpu" "am34")
-                                       (const_int 11) (const_int 22))
-                         (if_then_else (eq_attr "cpu" "am34")
-                                       (const_int 13) (const_int 24))
-                         (if_then_else (eq_attr "cpu" "am34")
-                                       (const_int 13) (const_int 24))
-                        ])
-  ]
+        [(const_int 11)
+         (const_int 11)
+         (const_int 11)
+         (if_then_else (eq_attr "cpu" "am34")
+                       (const_int 13) (const_int 24))
+         (if_then_else (eq_attr "cpu" "am34")
+                       (const_int 11) (const_int 22))
+        ])]
 )
 
 ;; movhi
   [(set (match_operand:HI 0 "nonimmediate_operand")
        (match_operand:HI 1 "general_operand"))]
   ""
-  "
 {
   /* One of the ops has to be in a register.  */
   if (!register_operand (operand1, HImode)
       && !register_operand (operand0, HImode))
-    operands[1] = copy_to_mode_reg (HImode, operand1);
-}")
-
-(define_insn "*am33_movhi"
-  [(set (match_operand:HI 0 "nonimmediate_operand"
-                         ;; 0       1       2      3     4         5
-                         "=d*x*a*f, d*x*a,  d*x*a, m,    *f,       d*x*a")
-       (match_operand:HI 1 "general_operand"
-                         "0,        d*x*ai, m,     d*x*a, d*x*a*f, *f"))]
-  "TARGET_AM33
-   && (register_operand (operands[0], HImode)
-       || register_operand (operands[1], HImode))"
-  "*
-{
-  switch (which_alternative)
-    {
-    case 0:
-      return \"nop\";
-    case 1:
-      gcc_assert (! CONST_DOUBLE_P (operands[1]));
-
-      if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
-         && CONST_INT_P (operands[1]))
-       {
-         HOST_WIDE_INT val = INTVAL (operands[1]);
-
-         if (((val & 0x80) && ! (val & 0xffffff00))
-             || ((val & 0x800000) && ! (val & 0xff000000)))
-           return \"movu %1,%0\";
-       }
-      return \"mov %1,%0\";
-    case 2:
-    case 3:
-      return \"movhu %1,%0\";
-    case 4:
-    case 5:
-      return \"fmov %1,%0\";
-    default:
-      gcc_unreachable ();
-    }
-}"
-  [(set_attr_alternative "timings"
-                        [(const_int 11)
-                         (if_then_else (eq_attr "cpu" "am34")
-                                       (const_int 11) (const_int 22))
-                         (if_then_else (eq_attr "cpu" "am34")
-                                       (const_int 13) (const_int 24))
-                         (if_then_else (eq_attr "cpu" "am34")
-                                       (const_int 13) (const_int 24))
-                         (if_then_else (eq_attr "cpu" "am34")
-                                       (const_int 47) (const_int 25))
-                         (if_then_else (eq_attr "cpu" "am34")
-                                       (const_int 47) (const_int 25))
-                        ])
-  ]
-)
+    operands[1] = force_reg (HImode, operand1);
+})
 
-(define_insn "*mn10300_movhi"
-  [(set (match_operand:HI 0 "nonimmediate_operand" "=d*a,d,d,!*a,d*a,d,m")
-       (match_operand:HI 1 "general_operand"       "0,  I,i,i,  da, m,d"))]
-  "register_operand (operands[0], HImode)
-   || register_operand (operands[1], HImode)"
-  "*
+(define_insn "*movhi_internal"
+  [(set (match_operand:HI 0 "nonimmediate_operand" "=*r,D*r,D*r,D,m")
+       (match_operand:HI 1 "general_operand"      "  0,  i,D*r,m,D"))]
+  "(register_operand (operands[0], HImode)
+    || register_operand (operands[1], HImode))"
 {
   switch (which_alternative)
     {
     case 0:
-      return \"nop\";
+      return "";
     case 1:
+      /* Note that "MOV imm8,An" is already zero-extending, and is 2 bytes.
+        We have "MOV imm16,Dn" at 3 bytes.  The only win for the 4 byte
+        movu is for an 8-bit unsigned move into Rn.  */
+      if (TARGET_AM33
+         && CONST_INT_P (operands[1])
+         && IN_RANGE (INTVAL (operands[1]), 0x80, 0xff)
+         && REGNO_EXTENDED_P (REGNO (operands[0]), 1))
+       return "movu %1,%0";
+      /* FALLTHRU */
     case 2:
+      return "mov %1,%0";
     case 3:
     case 4:
-      gcc_assert (! CONST_DOUBLE_P (operands[1]));
-      return \"mov %1,%0\";
-    case 5:
-    case 6:
-      return \"movhu %1,%0\";
+      return "movhu %1,%0";
     default:
       gcc_unreachable ();
     }
-}"
+}
   [(set_attr_alternative "timings"
-                        [(const_int 11)
-                         (const_int 11)
-                         (if_then_else (eq_attr "cpu" "am34")
-                                       (const_int 11) (const_int 22))
-                         (if_then_else (eq_attr "cpu" "am34")
-                                       (const_int 11) (const_int 22))
-                         (if_then_else (eq_attr "cpu" "am34")
-                                       (const_int 11) (const_int 22))
-                         (if_then_else (eq_attr "cpu" "am34")
-                                       (const_int 13) (const_int 24))
-                         (if_then_else (eq_attr "cpu" "am34")
-                                       (const_int 13) (const_int 24))
-                        ])
-  ]
+        [(const_int 11)
+         (const_int 11)
+         (if_then_else (eq_attr "cpu" "am34")
+                       (const_int 11) (const_int 22))
+         (if_then_else (eq_attr "cpu" "am34")
+                       (const_int 13) (const_int 24))
+         (if_then_else (eq_attr "cpu" "am34")
+                       (const_int 11) (const_int 22))
+        ])]
 )
 
 ;; movsi and helpers
   [(set (match_operand:SI 0 "nonimmediate_operand")
        (match_operand:SI 1 "general_operand"))]
   ""
-  "
 {
   /* One of the ops has to be in a register.  */
   if (!register_operand (operand1, SImode)
       && !register_operand (operand0, SImode))
-    operands[1] = copy_to_mode_reg (SImode, operand1);
+    operands[1] = force_reg (SImode, operand1);
   if (flag_pic)
     {
       rtx temp;
                                      0, OPTAB_LIB_WIDEN);
        }
     }
-}")
+})
 
 (define_insn "*movsi_internal"
   [(set (match_operand:SI 0 "nonimmediate_operand"
-                         "=dax, dax,  m,   dax, ax,!*y")
+                         "=r,r,r,m,r, A,*y,*y")
        (match_operand:SI 1 "general_operand"
-                         "0,    Idax, dax, im, !*y, ax"))
-  ]
+                         " 0,i,r,r,m,*y, A, i"))]
   "register_operand (operands[0], SImode)
    || register_operand (operands[1], SImode)"
-  "*
-  {
-    if (which_alternative == 0)
-      return \"nop\";
-
-    gcc_assert (! CONST_DOUBLE_P (operands[1]));
-
-    if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
-        && CONST_INT_P (operands[1]))
-      {
-        HOST_WIDE_INT val = INTVAL (operands[1]);
-
-        if (((val & 0x80) && ! (val & 0xffffff00))
-            || ((val & 0x800000) && ! (val & 0xff000000)))
-          return \"movu %1, %0\";
-      }
-
-    return \"mov %1, %0\";
-  }"
-  [(set_attr_alternative "timings"
-                        [(const_int 11)
-                         (if_then_else (eq_attr "cpu" "am34")
-                                       (const_int 13) (const_int 24))
-                         (if_then_else (eq_attr "cpu" "am34")
-                                       (const_int 13) (const_int 24))
-                         (if_then_else (eq_attr "cpu" "am34")
-                                       (const_int 13) (const_int 24))
-                         (if_then_else (eq_attr "cpu" "am34")
-                                       (const_int 13) (const_int 24))
-                         (if_then_else (eq_attr "cpu" "am34")
-                                       (const_int 13) (const_int 24))
-                        ])
-  ]
+{
+  switch (which_alternative)
+    {
+    case 0:
+      return "";
+    case 1: /* imm-reg*/
+      /* See movhi for a discussion of sizes for 8-bit movu.  Note that the
+        24-bit movu is 6 bytes, which is the same size as the full 32-bit
+        mov form for An and Dn.  So again movu is only a win for Rn.  */
+      if (TARGET_AM33
+         && CONST_INT_P (operands[1])
+         && REGNO_EXTENDED_P (REGNO (operands[0]), 1))
+       {
+         HOST_WIDE_INT val = INTVAL (operands[1]);
+         if (IN_RANGE (val, 0x80, 0xff)
+             || IN_RANGE (val, 0x800000, 0xffffff))
+           return "movu %1,%0";
+       }
+      /* FALLTHRU */
+    case 2:  /* reg-reg */
+    case 3:  /* reg-mem */
+    case 4:  /* mem-reg */
+    case 5:  /* sp-reg */
+    case 6:  /* reg-sp */
+    case 7:  /* imm-sp */
+      return "mov %1,%0";
+    default:
+      gcc_unreachable ();
+    }
+}
+  [(set_attr "isa" "*,*,*,*,*,*,*,am33")
+   (set_attr_alternative "timings"
+        [(const_int 11)
+         (const_int 22)
+         (const_int 11)
+         (if_then_else (eq_attr "cpu" "am34")
+                       (const_int 11) (const_int 22))
+         (if_then_else (eq_attr "cpu" "am34")
+                       (const_int 13) (const_int 24))
+         (if_then_else (eq_attr "cpu" "am34")
+                       (const_int 11) (const_int 22))
+         (if_then_else (eq_attr "cpu" "am34")
+                       (const_int 13) (const_int 24))
+         (const_int 11)
+        ])]
 )
 
 (define_expand "movsf"
   [(set (match_operand:SF 0 "nonimmediate_operand")
        (match_operand:SF 1 "general_operand"))]
-  ""
-  "
+  "TARGET_AM33_2"
 {
   /* One of the ops has to be in a register.  */
   if (!register_operand (operand1, SFmode)
       && !register_operand (operand0, SFmode))
-    operands[1] = copy_to_mode_reg (SFmode, operand1);
-}")
+    operands[1] = force_reg (SFmode, operand1);
+})
 
 (define_insn "*movsf_internal"
-  [(set (match_operand:SF 0 "nonimmediate_operand"
-                         ;; 0    1    2       3     4     5
-                         "=fdxa, dxa, f,      dxaQ, daxm, dax")
-       (match_operand:SF 1 "general_operand"
-                         " 0,    G,   fdxaQF, f,    dax,  daxFm"))
-  ]
-  "register_operand (operands[0], SFmode)
-   || register_operand (operands[1], SFmode)"
-  "*
-  {
-    switch (which_alternative)
-      {
-      case 0:
-        return \"nop\";
-      /* case 1: below.  */
-      case 2:
-      case 3:
-        return \"fmov %1, %0\";
-      case 1:
-      case 4:
-      case 5:
-        if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
-           && CONST_INT_P (operands[1]))
-         {
-           HOST_WIDE_INT val = INTVAL (operands[1]);
-
-           if (((val & 0x80) && ! (val & 0xffffff00))
-               || ((val & 0x800000) && ! (val & 0xff000000)))
-             return \"movu %1, %0\";
-         }
-        return \"mov %1, %0\";
-      default:
-        gcc_unreachable ();
-      }
-  }"
-  [(set_attr_alternative "timings"
-                        [(const_int 11)
-                         (if_then_else (eq_attr "cpu" "am34")
-                                       (const_int 13) (const_int 24))
-                         (if_then_else (eq_attr "cpu" "am34")
-                                       (const_int 47) (const_int 25))
-                         (if_then_else (eq_attr "cpu" "am34")
-                                       (const_int 47) (const_int 25))
-                         (if_then_else (eq_attr "cpu" "am34")
-                                       (const_int 13) (const_int 24))
-                         (if_then_else (eq_attr "cpu" "am34")
-                                       (const_int 13) (const_int 24))
-                        ])
-  ]
-)
-
-(define_expand "movdi"
-  [(set (match_operand:DI 0 "nonimmediate_operand")
-       (match_operand:DI 1 "general_operand"))]
-  ""
-  "
-{
-  /* One of the ops has to be in a register.  */
-  if (!register_operand (operand1, DImode)
-      && !register_operand (operand0, DImode))
-    operands[1] = copy_to_mode_reg (DImode, operand1);
-}")
-
-
-(define_insn "*movdi_internal"                   ;;   0 1  2  3 4   5   6  7 8  9
-  [(set (match_operand:DI 0 "nonimmediate_operand" "=dx,ax,dx,a,dxm,dxm,a, a,dx,a")
-       (match_operand:DI 1 "general_operand"        "0,0, I, I,dx, a,  dx,a,im,im"))]
-  "register_operand (operands[0], DImode)
-   || register_operand (operands[1], DImode)"
-  "*
+  [(set (match_operand:SF 0 "nonimmediate_operand" "=rf,r,f,r,f,r,f,r,m,f,Q")
+       (match_operand:SF 1 "general_operand"      "  0,F,F,r,f,f,r,m,r,Q,f"))]
+  "TARGET_AM33_2
+   && (register_operand (operands[0], SFmode)
+       || register_operand (operands[1], SFmode))"
 {
-  long val[2];
-  REAL_VALUE_TYPE rv;
-
   switch (which_alternative)
     {
-      case 0:
-      case 1:
-       return \"nop\";
-
-      case 2:
-       return \"mov 0, %L0\;mov 0, %H0\";
-
-      case 3:
-       if (rtx_equal_p (operands[0], operands[1]))
-         return \"sub %L1,%L0\;mov %L0,%H0\";
-       else
-         return \"mov %1,%L0\;mov %L0,%H0\";
-      case 4:
-      case 5:
-      case 6:
-      case 7:
-      case 8:
-      case 9:
-       if (CONST_INT_P (operands[1]))
-         {
-           rtx low, high;
-           split_double (operands[1], &low, &high);
-           val[0] = INTVAL (low);
-           val[1] = INTVAL (high);
-         }
-       if (CONST_DOUBLE_P (operands[1]))
-         {
-           if (GET_MODE (operands[1]) == DFmode)
-             {
-               REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
-               REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
-             }
-           else if (GET_MODE (operands[1]) == VOIDmode
-                    || GET_MODE (operands[1]) == DImode)
-             {
-               val[0] = CONST_DOUBLE_LOW (operands[1]);
-               val[1] = CONST_DOUBLE_HIGH (operands[1]);
-             }
-         }
-
-       if (MEM_P (operands[1])
-           && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
-         {
-           rtx temp = operands[0];
-
-           while (GET_CODE (temp) == SUBREG)
-             temp = SUBREG_REG (temp);
-
-           gcc_assert (REG_P (temp));
-
-           if (reg_overlap_mentioned_p (gen_rtx_REG (SImode, REGNO (temp)),
-                                        XEXP (operands[1], 0)))
-             return \"mov %H1,%H0\;mov %L1,%L0\";
-           else
-             return \"mov %L1,%L0\;mov %H1,%H0\";
-
-         }
-       else if (MEM_P (operands[1])
-                && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
-                && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
-         {
-           rtx xoperands[2];
-
-           xoperands[0] = operands[0];
-           xoperands[1] = XEXP (operands[1], 0);
-
-           output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\",
-                            xoperands);
-           return \"\";
-         }
-       else
-         {
-           if ((CONST_INT_P (operands[1])
-                || CONST_DOUBLE_P (operands[1]))
-               && val[0] == 0)
-             {
-               if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
-                 output_asm_insn (\"mov 0, %L0\", operands);
-               else
-                 output_asm_insn (\"mov %L1,%L0\", operands);
-             }
-           else if ((CONST_INT_P (operands[1])
-                     || CONST_DOUBLE_P (operands[1]))
-                    && (REGNO_REG_CLASS (true_regnum (operands[0]))
-                        == EXTENDED_REGS)
-                    && (((val[0] & 0x80) && ! (val[0] & 0xffffff00))
-                        || ((val[0] & 0x800000) && ! (val[0] & 0xff000000))))
-             output_asm_insn (\"movu %L1,%L0\", operands);
-           else
-             output_asm_insn (\"mov %L1,%L0\", operands);
-
-           if ((CONST_INT_P (operands[1])
-                || CONST_DOUBLE_P (operands[1]))
-               && val[1] == 0)
-             {
-               if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
-                 output_asm_insn (\"mov 0, %H0\", operands);
-               else
-                 output_asm_insn (\"mov %H1,%H0\", operands);
-             }
-           else if ((CONST_INT_P (operands[1])
-                     || CONST_DOUBLE_P (operands[1]))
-                    && val[0] == val[1])
-             output_asm_insn (\"mov %L0,%H0\", operands);
-           else if ((CONST_INT_P (operands[1])
-                     || CONST_DOUBLE_P (operands[1]))
-                    && (REGNO_REG_CLASS (true_regnum (operands[0]))
-                        == EXTENDED_REGS)
-                    && (((val[1] & 0x80) && ! (val[1] & 0xffffff00))
-                        || ((val[1] & 0x800000) && ! (val[1] & 0xff000000))))
-             output_asm_insn (\"movu %H1,%H0\", operands);
-           else
-             output_asm_insn (\"mov %H1,%H0\", operands);
-           return \"\";
-         }
-    default:
-      gcc_unreachable ();
-    }
-  }"
-  ;; The timing of "37" is an approximation of the worst case sceanario.
-  [(set_attr_alternative "timings"
-                        [(const_int 11)
-                         (const_int 11)
-                         (const_int 22)
-                         (const_int 22)
-                         (const_int 37)
-                         (const_int 37)
-                         (const_int 37)
-                         (const_int 37)
-                         (const_int 37)
-                         (const_int 37)
-                        ])
-  ]
-)
-
-(define_expand "movdf"
-  [(set (match_operand:DF 0 "nonimmediate_operand")
-       (match_operand:DF 1 "general_operand"))]
-  ""
-  "
-{
-  /* One of the ops has to be in a register.  */
-  if (!register_operand (operand1, DFmode)
-      && !register_operand (operand0, DFmode))
-    operands[1] = copy_to_mode_reg (DFmode, operand1);
-}")
-
-(define_insn "*am33_2_movdf"
-  [(set (match_operand:DF 0 "nonimmediate_operand"
-                         ;; 0   1   2    3    4 5 6   7   8  9 10 11
-                         "=fdax,dax,fdxa,f,   f,Q,dxm,dxm,a, a,dx,a")
-       (match_operand:DF 1 "general_operand"
-                         " 0,   G,  f,   dxaF,Q,f,dx, a,  dx,a,Fm,Fm"))]
-  "TARGET_AM33_2
-   && (register_operand (operands[0], DFmode)
-       || register_operand (operands[1], DFmode))"
-  "*
-  {
-    long val[2];
-    REAL_VALUE_TYPE rv;
-
-    switch (which_alternative)
-      {
-      case 0:
-       return \"nop\";
-
-      case 1:
-       return \"mov 0, %L0\; mov 0, %H0\";
-
-      case 2:
-      case 3:
-        return \"fmov %L1, %L0\; fmov %H1, %H0\";
-
-      case 4:
-       if (MEM_P (operands[1])
-           && CONST_INT_P (XEXP (operands[1], 0))
-           && (INTVAL (XEXP (operands[1], 0)) & 7) == 0)
-         return \"fmov %D1, %D0\";
-       else
-          return \"fmov %L1, %L0\; fmov %H1, %H0\";
-
-      case 5:
-       if (MEM_P (operands[0])
-           && CONST_INT_P (XEXP (operands[0], 0))
-           && (INTVAL (XEXP (operands[0], 0)) & 7) == 0)
-         return \"fmov %D1, %D0\";
-       else
-          return \"fmov %L1, %L0\; fmov %H1, %H0\";
-
-      case 6:
-      case 7:
-      case 8:
-      case 9:
-      case 10:
-      case 11:
-       if (CONST_INT_P (operands[1]))
-         {
-           rtx low, high;
-           split_double (operands[1], &low, &high);
-           val[0] = INTVAL (low);
-           val[1] = INTVAL (high);
-         }
-       if (CONST_DOUBLE_P (operands[1]))
-         {
-           if (GET_MODE (operands[1]) == DFmode)
-             {
-               REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
-               REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
-             }
-           else if (GET_MODE (operands[1]) == VOIDmode
-                    || GET_MODE (operands[1]) == DImode)
-             {
-               val[0] = CONST_DOUBLE_LOW (operands[1]);
-               val[1] = CONST_DOUBLE_HIGH (operands[1]);
-             }
-         }
-
-       if (MEM_P (operands[1])
-           && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
-         {
-           rtx temp = operands[0];
-
-           while (GET_CODE (temp) == SUBREG)
-             temp = SUBREG_REG (temp);
-
-           gcc_assert (REG_P (temp));
-
-           if (reg_overlap_mentioned_p (gen_rtx_REG (SImode, REGNO (temp)),
-                                        XEXP (operands[1], 0)))
-             return \"mov %H1, %H0\; mov %L1, %L0\";
-           else
-             return \"mov %L1, %L0\; mov %H1, %H0\";
-
-         }
-       else if (MEM_P (operands[1])
-                && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
-                && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
-         {
-           rtx xoperands[2];
-
-           xoperands[0] = operands[0];
-           xoperands[1] = XEXP (operands[1], 0);
-
-           output_asm_insn (\"mov %1, %L0\; mov (4, %L0), %H0\; mov (%L0), %L0\",
-                            xoperands);
-           return \"\";
-         }
-       else
-         {
-           if ((CONST_INT_P (operands[1])
-                || CONST_DOUBLE_P (operands[1]))
-               && val[0] == 0)
-             {
-               if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
-                 output_asm_insn (\"mov 0, %L0\", operands);
-               else
-                 output_asm_insn (\"mov %L1,%L0\", operands);
-             }
-           else if ((CONST_INT_P (operands[1])
-                     || CONST_DOUBLE_P (operands[1]))
-                    && (REGNO_REG_CLASS (true_regnum (operands[0]))
-                        == EXTENDED_REGS)
-                    && (((val[0] & 0x80) && ! (val[0] & 0xffffff00))
-                        || ((val[0] & 0x800000) && ! (val[0] & 0xff000000))))
-             output_asm_insn (\"movu %L1, %L0\", operands);
-           else
-             output_asm_insn (\"mov %L1, %L0\", operands);
-
-           if ((CONST_INT_P (operands[1])
-                || CONST_DOUBLE_P (operands[1]))
-               && val[1] == 0)
-             {
-               if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
-                 output_asm_insn (\"mov 0, %H0\", operands);
-               else
-                 output_asm_insn (\"mov %H1, %H0\", operands);
-             }
-           else if ((CONST_INT_P (operands[1])
-                     || CONST_DOUBLE_P (operands[1]))
-                    && val[0] == val[1])
-             output_asm_insn (\"mov %L0,%H0\", operands);
-           else if ((CONST_INT_P (operands[1])
-                     || CONST_DOUBLE_P (operands[1]))
-                    && (REGNO_REG_CLASS (true_regnum (operands[0]))
-                        == EXTENDED_REGS)
-                    && (((val[1] & 0x80) && ! (val[1] & 0xffffff00))
-                        || ((val[1] & 0x800000) && ! (val[1] & 0xff000000))))
-             output_asm_insn (\"movu %H1, %H0\", operands);
-           else
-             output_asm_insn (\"mov %H1, %H0\", operands);
-           return \"\";
-         }
+    case 0:
+      return "";
+    case 1:
+    case 3:
+    case 7:
+    case 8:
+      return "mov %1,%0";
+    case 2:
+    case 4:
+    case 5:
+    case 6:
+    case 9:
+    case 10:
+      return "fmov %1,%0";
     default:
       gcc_unreachable ();
     }
-  }"
-  ;; The timing of "37" is an approximation of the worst case sceanario.
+}
   [(set_attr_alternative "timings"
-                        [(const_int 11)
-                         (const_int 22)
-                         (const_int 22)
-                         (const_int 22)
-                         (const_int 22)
-                         (const_int 37)
-                         (const_int 37)
-                         (const_int 37)
-                         (const_int 37)
-                         (const_int 37)
-                         (const_int 37)
-                         (const_int 37)
-                        ])
-  ]
+                [(const_int 11)
+                 (const_int 22)
+                 (if_then_else (eq_attr "cpu" "am34")
+                               (const_int 47) (const_int 25))
+                 (const_int 11)
+                 (if_then_else (eq_attr "cpu" "am34")
+                               (const_int 13) (const_int 14))
+                 (if_then_else (eq_attr "cpu" "am34")
+                               (const_int 13) (const_int 12))
+                 (if_then_else (eq_attr "cpu" "am34")
+                               (const_int 13) (const_int 14))
+                 (if_then_else (eq_attr "cpu" "am34")
+                               (const_int 13) (const_int 24))
+                 (if_then_else (eq_attr "cpu" "am34")
+                               (const_int 13) (const_int 24))
+                 (if_then_else (eq_attr "cpu" "am34")
+                               (const_int 13) (const_int 24))
+                 (if_then_else (eq_attr "cpu" "am34")
+                               (const_int 13) (const_int 24))
+                ])]
 )
 
-(define_insn "*mn10300_movdf"
-  [(set (match_operand:DF 0 "nonimmediate_operand"
-                         ;;0    1    2    3    4   5  6   7
-                         "=dxa, dax, dxm, dxm, a,  a, dx, a")
-       (match_operand:DF 1 "general_operand"
-                         " 0,   G,   dx,  a,   dx, a, Fm, Fm"))]
-  "register_operand (operands[0], DFmode)
-   || register_operand (operands[1], DFmode)"
-  "*
-  {
-    long val[2];
-    REAL_VALUE_TYPE rv;
-
-    switch (which_alternative)
-      {
-      case 0:
-       return \"nop\";
-
-      case 1:
-       return \"mov 0, %L0\; mov 0, %H0\";
-
-      case 2:
-      case 3:
-      case 4:
-      case 5:
-      case 6:
-      case 7:
-       if (CONST_INT_P (operands[1]))
-         {
-           rtx low, high;
-           split_double (operands[1], &low, &high);
-           val[0] = INTVAL (low);
-           val[1] = INTVAL (high);
-         }
-        if (CONST_DOUBLE_P (operands[1]))
-         {
-           if (GET_MODE (operands[1]) == DFmode)
-             {
-               REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
-               REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
-             }
-           else if (GET_MODE (operands[1]) == VOIDmode
-                    || GET_MODE (operands[1]) == DImode)
-             {
-               val[0] = CONST_DOUBLE_LOW (operands[1]);
-               val[1] = CONST_DOUBLE_HIGH (operands[1]);
-             }
-         }
-
-       if (MEM_P (operands[1])
-           && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
-         {
-           rtx temp = operands[0];
-
-           while (GET_CODE (temp) == SUBREG)
-             temp = SUBREG_REG (temp);
-
-           gcc_assert (REG_P (temp));
-
-           if (reg_overlap_mentioned_p (gen_rtx_REG (SImode, REGNO (temp)),
-                                        XEXP (operands[1], 0)))
-             return \"mov %H1, %H0\; mov %L1, %L0\";
-           else
-             return \"mov %L1, %L0\; mov %H1, %H0\";
-         }
-       else if (MEM_P (operands[1])
-                && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
-                && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
-         {
-           rtx xoperands[2];
-
-           xoperands[0] = operands[0];
-           xoperands[1] = XEXP (operands[1], 0);
-
-           output_asm_insn (\"mov %1, %L0\; mov (4, %L0), %H0\; mov (%L0), %L0\",
-                            xoperands);
-           return \"\";
-         }
-       else
-         {
-           if ((CONST_INT_P (operands[1])
-                || CONST_DOUBLE_P (operands[1]))
-               && val[0] == 0)
-             {
-               if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
-                 output_asm_insn (\"mov 0, %L0\", operands);
-               else
-                 output_asm_insn (\"mov %L1, %L0\", operands);
-             }
-           else if ((CONST_INT_P (operands[1])
-                     || CONST_DOUBLE_P (operands[1]))
-                    && (REGNO_REG_CLASS (true_regnum (operands[0]))
-                        == EXTENDED_REGS)
-                    && (((val[0] & 0x80) && ! (val[0] & 0xffffff00))
-                        || ((val[0] & 0x800000) && ! (val[0] & 0xff000000))))
-             output_asm_insn (\"movu %L1, %L0\", operands);
-           else
-             output_asm_insn (\"mov %L1, %L0\", operands);
-
-           if ((CONST_INT_P (operands[1])
-                || CONST_DOUBLE_P (operands[1]))
-               && val[1] == 0)
-             {
-               if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
-                 output_asm_insn (\"mov 0, %H0\", operands);
-               else
-                 output_asm_insn (\"mov %H1, %H0\", operands);
-             }
-           else if ((CONST_INT_P (operands[1])
-                     || CONST_DOUBLE_P (operands[1]))
-                    && val[0] == val[1])
-             output_asm_insn (\"mov %L0, %H0\", operands);
-           else if ((CONST_INT_P (operands[1])
-                     || CONST_DOUBLE_P (operands[1]))
-                    && (REGNO_REG_CLASS (true_regnum (operands[0]))
-                        == EXTENDED_REGS)
-                    && (((val[1] & 0x80) && ! (val[1] & 0xffffff00))
-                        || ((val[1] & 0x800000) && ! (val[1] & 0xff000000))))
-             output_asm_insn (\"movu %H1, %H0\", operands);
-           else
-             output_asm_insn (\"mov %H1, %H0\", operands);
-           return \"\";
-         }
-    default:
-      gcc_unreachable ();
-    }
-  }"
-  ;; Timings of "37" is approximation of the worst case sceanario.
-  [(set_attr_alternative "timings"
-                        [(const_int 11)
-                         (const_int 22)
-                         (const_int 37)
-                         (const_int 37)
-                         (const_int 37)
-                         (const_int 37)
-                         (const_int 37)
-                         (const_int 37)
-                        ])
-  ]
-)
 \f
 ;; ----------------------------------------------------------------------
 ;; ADD INSTRUCTIONS
                                       (const_int 24) (const_int 23)))]
 )
 
-(define_expand "udivmodsi4"
-  [(parallel [(set (match_operand:SI          0 "register_operand")
-                  (udiv:SI (match_operand:SI 1 "general_operand")
-                           (match_operand:SI 2 "general_operand")))
-             (set (match_operand:SI          3 "register_operand")
-                  (umod:SI (match_dup 1) (match_dup 2)))
-             (clobber (reg:CC CC_REG))
-            ])
-  ]
-  ""
-  "{
-    if (!register_operand (operands[1], SImode))
-      operands[1] = copy_to_mode_reg (SImode, operands[1]);
-    if (!register_operand (operands[2], SImode))
-      operands[2] = copy_to_mode_reg (SImode, operands[2]);
-   }"
-)
-
-(define_insn "*udivmodsi4"
-  [(set (match_operand:SI          0 "register_operand" "=dx")
+;; ??? This pattern causes too-high register pressure for MN103.
+;; ??? To be fixed by exposing the MDR register properly.
+(define_insn "udivmodsi4"
+  [(set (match_operand:SI          0 "register_operand" "=D")
        (udiv:SI (match_operand:SI 1 "register_operand" "0")
-                (match_operand:SI 2 "register_operand" "dx")))
+                (match_operand:SI 2 "register_operand" "D")))
    (set (match_operand:SI          3 "register_operand" "=&d")
        (umod:SI (match_dup 1) (match_dup 2)))
-   (clobber (reg:CC CC_REG))
-  ]
-  ""
-  "*
+   (clobber (reg:CC CC_REG))]
+  "TARGET_AM33"
 {
-  output_asm_insn (\"sub %3,%3\;mov %3,mdr\", operands);
-
+  output_asm_insn ("clr %3\;ext %3", operands);
   if (find_reg_note (insn, REG_UNUSED, operands[3]))
-    return \"divu %2,%0\";
+    return "divu %2,%0";
   else
-    return \"divu %2,%0\;mov mdr,%3\";
-}"
+    return "divu %2,%0\;mov mdr,%3";
+}
   ;; Timings:  AM33   AM34
   ;;  SUB       1/1    1/1
   ;;  MOV       1/1    1/1
                                       (const_int 4546) (const_int 4142)))]
 )
 
+;; ??? In the meantime MN103 can use these two patterns,
+;; which reduce the register pressure by one.
+(define_insn "udivsi3"
+  [(set (match_operand:SI          0 "register_operand" "=&d")
+       (udiv:SI (match_operand:SI 1 "register_operand" "d")
+                (match_operand:SI 2 "register_operand" "d")))
+   (clobber (reg:CC CC_REG))]
+  "!TARGET_AM33"
+  "clr %0\;ext %0\;mov %1,%0\;divu %2,%0"
+  [(set_attr "timings" "4142")]
+)
+
+(define_insn "umodsi3"
+  [(set (match_operand:SI          0 "register_operand" "=&d")
+       (umod:SI (match_operand:SI 1 "register_operand" "d")
+                (match_operand:SI 2 "register_operand" "d")))
+   (clobber (reg:CC CC_REG))]
+  "!TARGET_AM33"
+  "clr %0\;ext %0\;mov %1,%0\;divu %2,%0\;mov mdr,%0"
+  [(set_attr "timings" "4142")]
+)
+
 (define_insn "divmodsi4"
   [(set (match_operand:SI          0 "register_operand" "=dx")
        (div:SI (match_operand:SI  1 "register_operand"  "0")