]> gcc.gnu.org Git - gcc.git/commitdiff
mips.c (mips_reg_names): Change hilo entry to "".
authorRichard Sandiford <rsandifo@redhat.com>
Mon, 9 Jun 2003 07:01:24 +0000 (07:01 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Mon, 9 Jun 2003 07:01:24 +0000 (07:01 +0000)
* config/mips/mips.c (mips_reg_names): Change hilo entry to "".
(mips_sw_reg_names): Likewise.
(mips_regno_to_class): Change hilo entry to NO_REGS.
(hilo_operand): Use MD_REG_P.
(extend_operator): New predicate.
(override_options): Remove 'a' constraint.
(mips_secondary_reload_class): Remove hilo handling.  Also remove
handling of (plus sp reg) reloads for mips16.
(mips_register_move_cost): Remove hilo handling.
* config/mips/mips.h (FIXED_REGISTERS): Make hilo entry fixed.
(MD_REG_LAST): Remove hilo from range.
(HILO_REGNUM): Delete.
(reg_class): Remove HILO_REG and HILO_AND_GR_REGS.
(REG_CLASS_NAMES, REG_CLASS_CONTENTS): Update accordingly.
(PREDICATE_CODES): Add entry for extend_operator.
(DEBUG_REGISTER_NAMES): Change hilo entry to "".
* config/mips/mips.md: Remove hilo clobbers wherever they occur.
Remove constraints from multiplication define_expands.  Remove
clobbers from "decorative" define_expand patterns.
(UNSPEC_HILO_DELAY): Delete.
(*mul_acc_si, *mul_sub_si): Add early-clobber to operand 6.
(mulsidi3, umulsidi3): Change pattern to match the TARGET_64BIT case.
Adjust C code to just emit insns for !TARGET_64BIT.
(mulsidi3_internal): Rename to mulsidi3_32bit.
(mulsidi3_64bit): Use a "d" constraint for the destination.
Use extend_operator so that the pattern can handle umulsidi3 as well.
Split the instruction after reload.
(*mulsidi3_64bit_parts): New pattern, generated by mulsidi3_64bit.
(umulsidi3_internal): Rename to umulsidi3_32bit.
(umulsidi3_64bit): Remove.
(*smsac_di, *umsac_di): Line-wrap fixes.
(udivsi3_internal): Don't allow operand 2 to be constant.
(udivdi3_internal, umodsi3_internal, umoddi3_internal): Likewise.
(movdi_internal2, movsi_internal): Remove hilo alternatives.
(reload_in[sd]i, reload_out[sd]i, hilo_delay): Remove.

From-SVN: r67654

gcc/ChangeLog
gcc/config/mips/mips.c
gcc/config/mips/mips.h
gcc/config/mips/mips.md

index da62392af1c0ac4bd450016c41df257922adf65c..5811a449d9ce54778dac479f76d1a7e7e61fae66 100644 (file)
@@ -1,3 +1,41 @@
+2003-06-09  Richard Sandiford  <rsandifo@redhat.com>
+
+       * config/mips/mips.c (mips_reg_names): Change hilo entry to "".
+       (mips_sw_reg_names): Likewise.
+       (mips_regno_to_class): Change hilo entry to NO_REGS.
+       (hilo_operand): Use MD_REG_P.
+       (extend_operator): New predicate.
+       (override_options): Remove 'a' constraint.
+       (mips_secondary_reload_class): Remove hilo handling.  Also remove
+       handling of (plus sp reg) reloads for mips16.
+       (mips_register_move_cost): Remove hilo handling.
+       * config/mips/mips.h (FIXED_REGISTERS): Make hilo entry fixed.
+       (MD_REG_LAST): Remove hilo from range.
+       (HILO_REGNUM): Delete.
+       (reg_class): Remove HILO_REG and HILO_AND_GR_REGS.
+       (REG_CLASS_NAMES, REG_CLASS_CONTENTS): Update accordingly.
+       (PREDICATE_CODES): Add entry for extend_operator.
+       (DEBUG_REGISTER_NAMES): Change hilo entry to "".
+       * config/mips/mips.md: Remove hilo clobbers wherever they occur.
+       Remove constraints from multiplication define_expands.  Remove
+       clobbers from "decorative" define_expand patterns.
+       (UNSPEC_HILO_DELAY): Delete.
+       (*mul_acc_si, *mul_sub_si): Add early-clobber to operand 6.
+       (mulsidi3, umulsidi3): Change pattern to match the TARGET_64BIT case.
+       Adjust C code to just emit insns for !TARGET_64BIT.
+       (mulsidi3_internal): Rename to mulsidi3_32bit.
+       (mulsidi3_64bit): Use a "d" constraint for the destination.
+       Use extend_operator so that the pattern can handle umulsidi3 as well.
+       Split the instruction after reload.
+       (*mulsidi3_64bit_parts): New pattern, generated by mulsidi3_64bit.
+       (umulsidi3_internal): Rename to umulsidi3_32bit.
+       (umulsidi3_64bit): Remove.
+       (*smsac_di, *umsac_di): Line-wrap fixes.
+       (udivsi3_internal): Don't allow operand 2 to be constant.
+       (udivdi3_internal, umodsi3_internal, umoddi3_internal): Likewise.
+       (movdi_internal2, movsi_internal): Remove hilo alternatives.
+       (reload_in[sd]i, reload_out[sd]i, hilo_delay): Remove.
+
 2003-06-09  Richard Sandiford  <rsandifo@redhat.com>
 
        PR target/10913
index 17bfd2b165156980b3c70c3cfa52aec8a3a5de22..605f3aef3d96f7297e983a60a6b5710b4f4864d4 100644 (file)
@@ -592,7 +592,7 @@ char mips_reg_names[][8] =
  "$f8",  "$f9",  "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
  "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
  "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
- "hi",   "lo",   "accum","$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",
+ "hi",   "lo",   "",     "$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",
  "$fcc5","$fcc6","$fcc7","", "",     "",     "",     "",
  "$c0r0", "$c0r1", "$c0r2", "$c0r3", "$c0r4", "$c0r5", "$c0r6", "$c0r7",
  "$c0r8", "$c0r9", "$c0r10","$c0r11","$c0r12","$c0r13","$c0r14","$c0r15",
@@ -621,7 +621,7 @@ char mips_sw_reg_names[][8] =
   "$f8",  "$f9",  "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
   "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
   "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
-  "hi",   "lo",   "accum","$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",
+  "hi",   "lo",   "",     "$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",
   "$fcc5","$fcc6","$fcc7","$rap", "",     "",     "",     "",
   "$c0r0", "$c0r1", "$c0r2", "$c0r3", "$c0r4", "$c0r5", "$c0r6", "$c0r7",
   "$c0r8", "$c0r9", "$c0r10","$c0r11","$c0r12","$c0r13","$c0r14","$c0r15",
@@ -656,7 +656,7 @@ const enum reg_class mips_regno_to_class[] =
   FP_REGS,     FP_REGS,        FP_REGS,        FP_REGS,
   FP_REGS,     FP_REGS,        FP_REGS,        FP_REGS,
   FP_REGS,     FP_REGS,        FP_REGS,        FP_REGS,
-  HI_REG,      LO_REG,         HILO_REG,       ST_REGS,
+  HI_REG,      LO_REG,         NO_REGS,        ST_REGS,
   ST_REGS,     ST_REGS,        ST_REGS,        ST_REGS,
   ST_REGS,     ST_REGS,        ST_REGS,        NO_REGS,
   NO_REGS,     NO_REGS,        NO_REGS,        NO_REGS,
@@ -1518,8 +1518,18 @@ hilo_operand (op, mode)
      enum machine_mode mode;
 {
   return ((mode == VOIDmode || mode == GET_MODE (op))
-         && REG_P (op)
-         && (REGNO (op) == HI_REGNUM || REGNO (op) == LO_REGNUM));
+         && REG_P (op) && MD_REG_P (REGNO (op)));
+}
+
+/* Return true if OP is an extension operator.  */
+
+int
+extend_operator (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  return ((mode == VOIDmode || mode == GET_MODE (op))
+         && (GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND));
 }
 
 /* Return nonzero if the code of this rtx pattern is EQ or NE.  */
@@ -5555,7 +5565,6 @@ override_options ()
   mips_char_to_class['f'] = (TARGET_HARD_FLOAT ? FP_REGS : NO_REGS);
   mips_char_to_class['h'] = HI_REG;
   mips_char_to_class['l'] = LO_REG;
-  mips_char_to_class['a'] = HILO_REG;
   mips_char_to_class['x'] = MD_REGS;
   mips_char_to_class['b'] = ALL_REGS;
   mips_char_to_class['c'] = (TARGET_ABICALLS ? PIC_FN_ADDR_REG :
@@ -8541,20 +8550,6 @@ mips_secondary_reload_class (class, mode, x, in_p)
       && DANGEROUS_FOR_LA25_P (x))
     return LEA_REGS;
 
-  /* We always require a general register when copying anything to
-     HILO_REGNUM, except when copying an SImode value from HILO_REGNUM
-     to a general register, or when copying from register 0.  */
-  if (class == HILO_REG && regno != GP_REG_FIRST + 0)
-    return ((! in_p
-            && gp_reg_p
-            && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (SImode))
-           ? NO_REGS : gr_regs);
-  else if (regno == HILO_REGNUM)
-    return ((in_p
-            && class == gr_regs
-            && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (SImode))
-           ? NO_REGS : gr_regs);
-
   /* Copying from HI or LO to anywhere other than a general register
      requires a general register.  */
   if (class == HI_REG || class == LO_REG || class == MD_REGS)
@@ -8636,19 +8631,6 @@ mips_secondary_reload_class (class, mode, x, in_p)
        }
       if (! gp_reg_p)
        {
-         /* The stack pointer isn't a valid operand to an add instruction,
-            so we need to load it into M16_REGS first.  This can happen as
-            a result of register elimination and form_sum converting
-            (plus reg (plus SP CONST)) to (plus (plus reg SP) CONST).  We
-            need an extra register if the dest is the same as the other
-            register.  In that case, we can't fix the problem by loading SP
-            into the dest first.  */
-         if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == REG
-             && GET_CODE (XEXP (x, 1)) == REG
-             && (XEXP (x, 0) == stack_pointer_rtx
-                 || XEXP (x, 1) == stack_pointer_rtx))
-           return (class == M16_REGS ? M16_NA_REGS : M16_REGS);
-
          if (class == M16_REGS || class == M16_NA_REGS)
            return NO_REGS;
          return M16_REGS;
@@ -9775,10 +9757,10 @@ mips_reorg ()
    should do this if the `movM' pattern's constraints do not allow
    such copying.
 
-   ??? We make make the cost of moving from HI/LO/HILO/MD into general
+   ??? We make the cost of moving from HI/LO into general
    registers the same as for one of moving general registers to
-   HI/LO/HILO/MD for TARGET_MIPS16 in order to prevent allocating a
-   pseudo to HI/LO/HILO/MD.  This might hurt optimizations though, it
+   HI/LO for TARGET_MIPS16 in order to prevent allocating a
+   pseudo to HI/LO.  This might hurt optimizations though, it
    isn't clear if it is wise.  And it might not work in all cases.  We
    could solve the DImode LO reg problem by using a multiply, just
    like reload_{in,out}si.  We could solve the SImode/HImode HI reg
@@ -9813,8 +9795,7 @@ mips_register_move_cost (mode, to, from)
        }
       else if (to == FP_REGS)
        return 4;
-      else if (to == HI_REG || to == LO_REG || to == MD_REGS
-              || to == HILO_REG)
+      else if (to == HI_REG || to == LO_REG || to == MD_REGS)
        {
          if (TARGET_MIPS16)
            return 12;
@@ -9835,8 +9816,7 @@ mips_register_move_cost (mode, to, from)
       else if (to == ST_REGS)
        return 8;
     }  /* from == FP_REGS */
-  else if (from == HI_REG || from == LO_REG || from == MD_REGS
-          || from == HILO_REG)
+  else if (from == HI_REG || from == LO_REG || from == MD_REGS)
     {
       if (GR_REG_CLASS_P (to))
        {
index fc4177a34a0d92b1b71dc17b5120105a7e6416a1..865603d50c5a0db95aaed5396234396e4901c51a 100644 (file)
@@ -1683,14 +1683,9 @@ do {                                                     \
 
    On the Mips, we have 32 integer registers, 32 floating point
    registers, 8 condition code registers, and the special registers
-   hi, lo, hilo, and rap.  Afetr that we have 32 COP0 registers, 32
-   COP2 registers, and 32 COp3 registers.  (COP1 is the floating-point
-   processor.)  The 8 condition code registers are only used if
-   mips_isa >= 4.  The hilo register is only used in 64 bit mode.  It
-   represents a 64 bit value stored as two 32 bit values in the hi and
-   lo registers; this is the result of the mult instruction.  rap is a
-   pointer to the stack where the return address reg ($31) was stored.
-   This is needed for C++ exception handling.  */
+   hi and lo.  After that we have 32 COP0 registers, 32 COP2 registers,
+   and 32 COP3 registers.  (COP1 is the floating-point processor.)
+   The 8 condition code registers are only used if mips_isa >= 4.  */
 
 #define FIRST_PSEUDO_REGISTER 176
 
@@ -1711,7 +1706,7 @@ do {                                                      \
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0,                      \
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                      \
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                      \
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,                      \
+  0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,                      \
   /* COP0 registers */                                                 \
   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,                      \
   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,                      \
@@ -1795,7 +1790,7 @@ do {                                                      \
 #define FP_DBX_FIRST ((write_symbols == DBX_DEBUG) ? 38 : 32)
 
 #define MD_REG_FIRST 64
-#define MD_REG_LAST  66
+#define MD_REG_LAST  65
 #define MD_REG_NUM   (MD_REG_LAST - MD_REG_FIRST + 1)
 #define MD_DBX_FIRST (FP_DBX_FIRST + FP_REG_NUM)
 
@@ -1822,7 +1817,6 @@ do {                                                      \
 #define AT_REGNUM      (GP_REG_FIRST + 1)
 #define HI_REGNUM      (MD_REG_FIRST + 0)
 #define LO_REGNUM      (MD_REG_FIRST + 1)
-#define HILO_REGNUM    (MD_REG_FIRST + 2)
 
 /* FPSW_REGNUM is the single condition code used if mips_isa < 4.  If
    mips_isa >= 4, it should not be used, and an arbitrary ST_REG
@@ -2002,14 +1996,12 @@ enum reg_class
   FP_REGS,                     /* floating point registers */
   HI_REG,                      /* hi register */
   LO_REG,                      /* lo register */
-  HILO_REG,                    /* hilo register pair for 64 bit mode mult */
   MD_REGS,                     /* multiply/divide registers (hi/lo) */
   COP0_REGS,                   /* generic coprocessor classes */
   COP2_REGS,
   COP3_REGS,
   HI_AND_GR_REGS,              /* union classes */
   LO_AND_GR_REGS,
-  HILO_AND_GR_REGS,
   HI_AND_FP_REGS,
   COP0_AND_GR_REGS,
   COP2_AND_GR_REGS,
@@ -2042,7 +2034,6 @@ enum reg_class
   "FP_REGS",                                                           \
   "HI_REG",                                                            \
   "LO_REG",                                                            \
-  "HILO_REG",                                                          \
   "MD_REGS",                                                           \
   /* coprocessor registers */                                          \
   "COP0_REGS",                                                         \
@@ -2050,7 +2041,6 @@ enum reg_class
   "COP3_REGS",                                                         \
   "HI_AND_GR_REGS",                                                    \
   "LO_AND_GR_REGS",                                                    \
-  "HILO_AND_GR_REGS",                                                  \
   "HI_AND_FP_REGS",                                                    \
   "COP0_AND_GR_REGS",                                                  \
   "COP2_AND_GR_REGS",                                                  \
@@ -2085,14 +2075,12 @@ enum reg_class
   { 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },  /* floating registers*/ \
   { 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000 },  /* hi register */       \
   { 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000 },  /* lo register */       \
-  { 0x00000000, 0x00000000, 0x00000004, 0x00000000, 0x00000000, 0x00000000 },  /* hilo register */     \
   { 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000 },  /* mul/div registers */ \
   { 0x00000000, 0x00000000, 0xffff0000, 0x0000ffff, 0x00000000, 0x00000000 }, /* cop0 registers */ \
   { 0x00000000, 0x00000000, 0x00000000, 0xffff0000, 0x0000ffff, 0x00000000 }, /* cop2 registers */ \
   { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffff0000, 0x0000ffff }, /* cop3 registers */ \
   { 0xffffffff, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000 },  /* union classes */     \
   { 0xffffffff, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000 },                          \
-  { 0xffffffff, 0x00000000, 0x00000004, 0x00000000, 0x00000000, 0x00000000 },                          \
   { 0x00000000, 0xffffffff, 0x00000001, 0x00000000, 0x00000000, 0x00000000 },                          \
   { 0xffffffff, 0x00000000, 0xffff0000, 0x0000ffff, 0x00000000, 0x00000000 },                  \
   { 0xffffffff, 0x00000000, 0x00000000, 0xffff0000, 0x0000ffff, 0x00000000 },  \
@@ -2186,7 +2174,6 @@ extern const enum reg_class mips_regno_to_class[];
    'h' Hi register
    'l' Lo register
    'x' Multiply/divide registers
-   'a' HILO_REG
    'z' FP Status register
    'B'  Cop0 register
    'C'  Cop2 register
@@ -3312,7 +3299,8 @@ typedef struct mips_args {
   {"consttable_operand",       { LABEL_REF, SYMBOL_REF, CONST_INT,     \
                                  CONST_DOUBLE, CONST }},               \
   {"fcc_register_operand",     { REG, SUBREG }},                       \
-  {"hilo_operand",             { REG }},
+  {"hilo_operand",             { REG }},                               \
+  {"extend_operator",          { ZERO_EXTEND, SIGN_EXTEND }},
 
 /* A list of predicates that do special things with modes, and so
    should not elicit warnings for VOIDmode match_operand.  */
@@ -3546,7 +3534,7 @@ typedef struct mips_args {
   "$f8",  "$f9",  "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",      \
   "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",      \
   "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",      \
-  "hi",   "lo",   "accum","$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",     \
+  "hi",   "lo",   "",     "$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",     \
   "$fcc5","$fcc6","$fcc7","$rap", "",     "",     "",     "",          \
   "$c0r0", "$c0r1", "$c0r2", "$c0r3", "$c0r4", "$c0r5", "$c0r6", "$c0r7",\
   "$c0r8", "$c0r9", "$c0r10","$c0r11","$c0r12","$c0r13","$c0r14","$c0r15",\
index 07b629c44ff8126510f840fd5fc9710d3d3826e4..10a3da04e10821d087c607b97059e8c7610ae574 100644 (file)
@@ -31,7 +31,6 @@
    (UNSPEC_LOAD_DF_HIGH                 1)
    (UNSPEC_STORE_DF_HIGH        2)
    (UNSPEC_GET_FNADDR           4)
-   (UNSPEC_HILO_DELAY           5)
    (UNSPEC_BLOCKAGE             6)
    (UNSPEC_LOADGP               7)
    (UNSPEC_SETJMP               8)
 ;; this by keeping the mflo with the mult on the R4000.
 
 (define_expand "mulsi3"
-  [(set (match_operand:SI 0 "register_operand" "=l")
-       (mult:SI (match_operand:SI 1 "register_operand" "d")
-                (match_operand:SI 2 "register_operand" "d")))
-   (clobber (match_scratch:SI 3 "=h"))
-   (clobber (match_scratch:SI 4 "=a"))]
+  [(set (match_operand:SI 0 "register_operand" "")
+       (mult:SI (match_operand:SI 1 "register_operand" "")
+                (match_operand:SI 2 "register_operand" "")))]
   ""
   "
 {
        (mult:SI (match_operand:SI 1 "register_operand" "d,d")
                 (match_operand:SI 2 "register_operand" "d,d")))
    (clobber (match_scratch:SI 3 "=h,h"))
-   (clobber (match_scratch:SI 4 "=l,X"))
-   (clobber (match_scratch:SI 5 "=a,a"))]
+   (clobber (match_scratch:SI 4 "=l,X"))]
   "GENERATE_MULT3_SI
    || TARGET_MAD"
   "*
 ;; Operand 1: GPR (1st multiplication operand)
 ;; Operand 2: GPR (2nd multiplication operand)
 ;; Operand 3: HI
-;; Operand 4: HILO
-;; Operand 5: GPR (destination)
+;; Operand 4: GPR (destination)
 (define_peephole2
   [(parallel
        [(set (match_operand:SI 0 "register_operand" "")
             (mult:SI (match_operand:SI 1 "register_operand" "")
                      (match_operand:SI 2 "register_operand" "")))
         (clobber (match_operand:SI 3 "register_operand" ""))
-        (clobber (scratch:SI))
-        (clobber (match_operand:SI 4 "register_operand" ""))])
-   (set (match_operand:SI 5 "register_operand" "")
+        (clobber (scratch:SI))])
+   (set (match_operand:SI 4 "register_operand" "")
         (match_dup 0))]
   "GENERATE_MULT3_SI
    && true_regnum (operands[0]) == LO_REGNUM
-   && GP_REG_P (true_regnum (operands[5]))
+   && GP_REG_P (true_regnum (operands[4]))
    && peep2_reg_dead_p (2, operands[0])"
   [(parallel
-       [(set (match_dup 5)
+       [(set (match_dup 4)
             (mult:SI (match_dup 1)
                      (match_dup 2)))
         (clobber (match_dup 3))
-        (clobber (match_dup 0))
-        (clobber (match_dup 4))])])
+        (clobber (match_dup 0))])])
 
 (define_insn "mulsi3_internal"
   [(set (match_operand:SI 0 "register_operand" "=l")
        (mult:SI (match_operand:SI 1 "register_operand" "d")
                 (match_operand:SI 2 "register_operand" "d")))
-   (clobber (match_scratch:SI 3 "=h"))
-   (clobber (match_scratch:SI 4 "=a"))]
+   (clobber (match_scratch:SI 3 "=h"))]
   "!TARGET_MIPS4000 || TARGET_MIPS16"
   "mult\\t%1,%2"
   [(set_attr "type"    "imul")
        (mult:SI (match_operand:SI 1 "register_operand" "d")
                 (match_operand:SI 2 "register_operand" "d")))
    (clobber (match_scratch:SI 3 "=h"))
-   (clobber (match_scratch:SI 4 "=l"))
-   (clobber (match_scratch:SI 5 "=a"))]
+   (clobber (match_scratch:SI 4 "=l"))]
   "TARGET_MIPS4000 && !TARGET_MIPS16"
   "mult\t%1,%2\;mflo\t%0"
   [(set_attr "type"    "imul")
                 (match_operand:SI 3 "register_operand" "0,l,*d")))
    (clobber (match_scratch:SI 4 "=h,h,h"))
    (clobber (match_scratch:SI 5 "=X,3,l"))
-   (clobber (match_scratch:SI 6 "=a,a,a"))
-   (clobber (match_scratch:SI 7 "=X,X,d"))]
+   (clobber (match_scratch:SI 6 "=X,X,&d"))]
   "(TARGET_MIPS3900
    || ISA_HAS_MADD_MSUB)
    && !TARGET_MIPS16"
                 (match_operand:SI 3 "register_operand" "")))
    (clobber (match_scratch:SI 4 ""))
    (clobber (match_scratch:SI 5 ""))
-   (clobber (match_scratch:SI 6 ""))
-   (clobber (match_scratch:SI 7 ""))]
+   (clobber (match_scratch:SI 6 ""))]
   "reload_completed && !TARGET_DEBUG_D_MODE
    && GP_REG_P (true_regnum (operands[0]))
    && GP_REG_P (true_regnum (operands[3]))"
-  [(parallel [(set (match_dup 7)
+  [(parallel [(set (match_dup 6)
                   (mult:SI (match_dup 1) (match_dup 2)))
              (clobber (match_dup 4))
-             (clobber (match_dup 5))
-             (clobber (match_dup 6))])
-   (set (match_dup 0) (plus:SI (match_dup 7) (match_dup 3)))]
+             (clobber (match_dup 5))])
+   (set (match_dup 0) (plus:SI (match_dup 6) (match_dup 3)))]
   "")
 
 ;; Splitter to copy result of MADD to a general register
                  (match_operand:SI          3 "register_operand" "")))
    (clobber (match_scratch:SI               4 ""))
    (clobber (match_scratch:SI               5 ""))
-   (clobber (match_scratch:SI               6 ""))
-   (clobber (match_scratch:SI               7 ""))]
+   (clobber (match_scratch:SI               6 ""))]
   "reload_completed && !TARGET_DEBUG_D_MODE
    && GP_REG_P (true_regnum (operands[0]))
    && true_regnum (operands[3]) == LO_REGNUM"
                             (match_dup 3)))
               (clobber (match_dup 4))
               (clobber (match_dup 5))
-              (clobber (match_dup 6))
-              (clobber (match_dup 7))])
+              (clobber (match_dup 6))])
    (set (match_dup 0) (match_dup 3))]
   "")
 
                          (match_operand:SI 2 "register_operand" "d,d"))
                 (match_operand:SI 3 "register_operand" "0,l")))
    (clobber (match_scratch:SI 4 "=h,h"))
-   (clobber (match_scratch:SI 5 "=X,3"))
-   (clobber (match_scratch:SI 6 "=a,a"))]
+   (clobber (match_scratch:SI 5 "=X,3"))]
   "ISA_HAS_MACC"
   "*
 {
        (plus:SI (mult:SI (match_dup 1)
                          (match_dup 2))
                 (match_dup 0)))
-   (clobber (match_scratch:SI 4 "=h"))
-   (clobber (match_scratch:SI 5 "=a"))]
+   (clobber (match_scratch:SI 4 "=h"))]
   "ISA_HAS_MACC && reload_completed"
   "macc\\t%3,%1,%2"
   [(set_attr "type"    "imadd")
 ;; Operand 1: GPR (1st multiplication operand)
 ;; Operand 2: GPR (2nd multiplication operand)
 ;; Operand 3: HI
-;; Operand 4: HILO
-;; Operand 5: GPR (destination)
+;; Operand 4: GPR (destination)
 (define_peephole2
   [(parallel
        [(set (match_operand:SI 0 "register_operand" "")
                               (match_operand:SI 2 "register_operand" ""))
                      (match_dup 0)))
        (clobber (match_operand:SI 3 "register_operand" ""))
-       (clobber (scratch:SI))
-       (clobber (match_operand:SI 4 "register_operand" ""))])
-   (set (match_operand:SI 5 "register_operand" "")
+       (clobber (scratch:SI))])
+   (set (match_operand:SI 4 "register_operand" "")
        (match_dup 0))]
   "ISA_HAS_MACC
    && true_regnum (operands[0]) == LO_REGNUM
-   && GP_REG_P (true_regnum (operands[5]))"
+   && GP_REG_P (true_regnum (operands[4]))"
   [(parallel [(set (match_dup 0)
                   (plus:SI (mult:SI (match_dup 1)
                                     (match_dup 2))
                            (match_dup 0)))
-             (set (match_dup 5)
+             (set (match_dup 4)
                   (plus:SI (mult:SI (match_dup 1)
                                     (match_dup 2))
                            (match_dup 0)))
-             (clobber (match_dup 3))
-             (clobber (match_dup 4))])]
+             (clobber (match_dup 3))])]
   "")
 
 ;; When we have a three-address multiplication instruction, it should
 ;; Operand 4: GPR (1st multiplication operand)
 ;; Operand 5: GPR (2nd multiplication operand)
 ;; Operand 6: HI
-;; Operand 7: HILO
 (define_peephole2
   [(match_scratch:SI 0 "d")
    (set (match_operand:SI 1 "register_operand" "")
                               (match_operand:SI 5 "register_operand" ""))
                      (match_dup 1)))
        (clobber (match_operand:SI 6 "register_operand" ""))
-       (clobber (match_dup 1))
-       (clobber (match_operand:SI 7 "register_operand" ""))])]
+       (clobber (match_dup 1))])]
   "ISA_HAS_MACC && GENERATE_MULT3_SI
    && true_regnum (operands[1]) == LO_REGNUM
    && peep2_reg_dead_p (2, operands[1])
                   (mult:SI (match_dup 4)
                            (match_dup 5)))
              (clobber (match_dup 6))
-             (clobber (match_dup 1))
-             (clobber (match_dup 7))])
+             (clobber (match_dup 1))])
    (set (match_dup 3)
        (plus:SI (match_dup 0)
                 (match_dup 2)))]
 ;; Operand 3: GPR (1st multiplication operand)
 ;; Operand 4: GPR (2nd multiplication operand)
 ;; Operand 5: HI
-;; Operand 6: HILO
-;; Operand 7: GPR (destination)
+;; Operand 6: GPR (destination)
 (define_peephole2
   [(match_scratch:SI 0 "d")
    (set (match_operand:SI 1 "register_operand" "")
                               (match_operand:SI 4 "register_operand" ""))
                      (match_dup 1)))
        (clobber (match_operand:SI 5 "register_operand" ""))
-       (clobber (scratch:SI))
-       (clobber (match_operand:SI 6 "register_operand" ""))])
+       (clobber (scratch:SI))])
    (match_dup 0)
-   (set (match_operand:SI 7 "register_operand" "")
+   (set (match_operand:SI 6 "register_operand" "")
        (match_dup 1))]
   "ISA_HAS_MACC && GENERATE_MULT3_SI
    && true_regnum (operands[1]) == LO_REGNUM
    && peep2_reg_dead_p (3, operands[1])
-   && GP_REG_P (true_regnum (operands[7]))"
+   && GP_REG_P (true_regnum (operands[6]))"
   [(parallel [(set (match_dup 0)
                   (mult:SI (match_dup 3)
                            (match_dup 4)))
              (clobber (match_dup 5))
-             (clobber (match_dup 1))
-             (clobber (match_dup 6))])
-   (set (match_dup 7)
+             (clobber (match_dup 1))])
+   (set (match_dup 6)
        (plus:SI (match_dup 0)
                 (match_dup 2)))]
   "")
                            (match_operand:SI 3 "register_operand" "d,d,d"))))
    (clobber (match_scratch:SI 4 "=h,h,h"))
    (clobber (match_scratch:SI 5 "=X,1,l"))
-   (clobber (match_scratch:SI 6 "=a,a,a"))
-   (clobber (match_scratch:SI 7 "=X,X,d"))]
+   (clobber (match_scratch:SI 6 "=X,X,&d"))]
   "ISA_HAS_MADD_MSUB"
   "*
 {
                            (match_operand:SI 3 "register_operand" ""))))
    (clobber (match_scratch:SI 4 ""))
    (clobber (match_scratch:SI 5 ""))
-   (clobber (match_scratch:SI 6 ""))
-   (clobber (match_scratch:SI 7 ""))]
+   (clobber (match_scratch:SI 6 ""))]
   "reload_completed && !TARGET_DEBUG_D_MODE
    && GP_REG_P (true_regnum (operands[0]))
    && GP_REG_P (true_regnum (operands[1]))"
-  [(parallel [(set (match_dup 7)
+  [(parallel [(set (match_dup 6)
                    (mult:SI (match_dup 2) (match_dup 3)))
               (clobber (match_dup 4))
-              (clobber (match_dup 5))
-              (clobber (match_dup 6))])
-   (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 7)))]
+              (clobber (match_dup 5))])
+   (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 6)))]
   "")
 
 ;; Splitter to copy result of MSUB to a general register
                            (match_operand:SI 3 "register_operand" ""))))
    (clobber (match_scratch:SI 4 ""))
    (clobber (match_scratch:SI 5 ""))
-   (clobber (match_scratch:SI 6 ""))
-   (clobber (match_scratch:SI 7 ""))]
+   (clobber (match_scratch:SI 6 ""))]
   "reload_completed && !TARGET_DEBUG_D_MODE
    && GP_REG_P (true_regnum (operands[0]))
    && true_regnum (operands[1]) == LO_REGNUM"
                              (mult:SI (match_dup 2) (match_dup 3))))
               (clobber (match_dup 4))
               (clobber (match_dup 5))
-              (clobber (match_dup 6))
-              (clobber (match_dup 7))])
+              (clobber (match_dup 6))])
    (set (match_dup 0) (match_dup 1))]
   "")
 
         (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
                          (match_operand:SI 2 "register_operand" "d,d"))))
    (clobber (match_scratch:SI              3                    "=h,h"))
-   (clobber (match_scratch:SI              4                    "=a,a"))
-   (clobber (match_scratch:SI              5                    "=X,l"))]
+   (clobber (match_scratch:SI              4                    "=X,l"))]
   "ISA_HAS_MULS"
   "@
    muls\\t$0,%1,%2
                   (mult:SI (match_operand:SI 2 "register_operand" "d,d")
                            (match_operand:SI 3 "register_operand" "d,d"))))
    (clobber (match_scratch:SI 4 "=h,h"))
-   (clobber (match_scratch:SI 5 "=X,1"))
-   (clobber (match_scratch:SI 6 "=a,a"))]
+   (clobber (match_scratch:SI 5 "=X,1"))]
   "ISA_HAS_MSAC"
   "*
 {
    (set_attr "mode"     "SI")])
 
 (define_expand "muldi3"
-  [(set (match_operand:DI 0 "register_operand" "=l")
-       (mult:DI (match_operand:DI 1 "register_operand" "d")
-                (match_operand:DI 2 "register_operand" "d")))
-   (clobber (match_scratch:DI 3 "=h"))
-   (clobber (match_scratch:DI 4 "=a"))]
+  [(set (match_operand:DI 0 "register_operand" "")
+       (mult:DI (match_operand:DI 1 "register_operand" "")
+                (match_operand:DI 2 "register_operand" "")))]
   "TARGET_64BIT"
 
   "
   [(set (match_operand:DI 0 "register_operand" "=l")
        (mult:DI (match_operand:DI 1 "register_operand" "d")
                 (match_operand:DI 2 "register_operand" "d")))
-   (clobber (match_scratch:DI 3 "=h"))
-   (clobber (match_scratch:DI 4 "=a"))]
+   (clobber (match_scratch:DI 3 "=h"))]
   "TARGET_64BIT && !TARGET_MIPS4000"
   "dmult\\t%1,%2"
   [(set_attr "type"    "imul")
        (mult:DI (match_operand:DI 1 "register_operand" "d")
                 (match_operand:DI 2 "register_operand" "d")))
    (clobber (match_scratch:DI 3 "=h"))
-   (clobber (match_scratch:DI 4 "=l"))
-   (clobber (match_scratch:DI 5 "=a"))]
+   (clobber (match_scratch:DI 4 "=l"))]
   "TARGET_64BIT && (GENERATE_MULT3_DI || TARGET_MIPS4000)"
   {
     if (GENERATE_MULT3_DI)
 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
 
 (define_expand "mulsidi3"
-  [(set (match_operand:DI 0 "register_operand" "=x")
-       (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
-                (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
+  [(parallel
+      [(set (match_operand:DI 0 "register_operand" "")
+           (mult:DI
+              (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
+              (sign_extend:DI (match_operand:SI 2 "register_operand" ""))))
+       (clobber (scratch:DI))
+       (clobber (scratch:DI))
+       (clobber (scratch:DI))])]
   ""
-  "
-{
-  if (TARGET_64BIT)
-    emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2]));
-  else
-    emit_insn (gen_mulsidi3_internal (operands[0], operands[1], operands[2]));
-  DONE;
-}")
+  {
+    if (!TARGET_64BIT)
+      {
+       emit_insn (gen_mulsidi3_32bit (operands[0], operands[1], operands[2]));
+       DONE;
+      }
+   })
 
-(define_insn "mulsidi3_internal"
+(define_insn "mulsidi3_32bit"
   [(set (match_operand:DI 0 "register_operand" "=x")
-       (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
-                (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))
-   (clobber (match_scratch:SI 3 "=a"))]
+       (mult:DI
+          (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
+          (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
   "!TARGET_64BIT"
   "mult\\t%1,%2"
   [(set_attr "type"    "imul")
    (set_attr "mode"    "SI")])
 
-(define_insn "mulsidi3_64bit"
-  [(set (match_operand:DI 0 "register_operand" "=a")
-       (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
-                (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))
-   (clobber (match_scratch:DI 3 "=l"))
-   (clobber (match_scratch:DI 4 "=h"))]
-  "TARGET_64BIT"
-  "mult\\t%1,%2"
-  [(set_attr "type"    "imul")
-   (set_attr "mode"    "SI")])
+(define_insn_and_split "*mulsidi3_64bit"
+  [(set (match_operand:DI 0 "register_operand" "=d")
+       (mult:DI (match_operator:DI 1 "extend_operator"
+                   [(match_operand:SI 3 "register_operand" "d")])
+                (match_operator:DI 2 "extend_operator"
+                   [(match_operand:SI 4 "register_operand" "d")])))
+   (clobber (match_scratch:DI 5 "=l"))
+   (clobber (match_scratch:DI 6 "=h"))
+   (clobber (match_scratch:DI 7 "=d"))]
+  "TARGET_64BIT && GET_CODE (operands[1]) == GET_CODE (operands[2])"
+  "#"
+  "&& reload_completed"
+  [(parallel
+       [(set (match_dup 5)
+            (sign_extend:DI
+               (mult:SI (match_dup 3)
+                        (match_dup 4))))
+       (set (match_dup 6)
+            (ashiftrt:DI
+               (mult:DI (match_dup 1)
+                        (match_dup 2))
+               (const_int 32)))])
+
+   ;; OP7 <- LO, OP0 <- HI
+   (set (match_dup 7) (match_dup 5))
+   (set (match_dup 0) (match_dup 6))
+
+   ;; Zero-extend OP7.
+   (set (match_dup 7)
+       (ashift:DI (match_dup 7)
+                  (const_int 32)))
+   (set (match_dup 7)
+       (lshiftrt:DI (match_dup 7)
+                    (const_int 32)))
 
-(define_expand "umulsidi3"
-  [(set (match_operand:DI 0 "register_operand" "=x")
-       (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
-                (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
+   ;; Shift OP0 into place.
+   (set (match_dup 0)
+       (ashift:DI (match_dup 0)
+                  (const_int 32)))
+
+   ;; OR the two halves together
+   (set (match_dup 0)
+       (ior:DI (match_dup 0)
+               (match_dup 7)))]
   ""
-  "
-{
-  if (TARGET_64BIT)
-    emit_insn (gen_umulsidi3_64bit (operands[0], operands[1], operands[2]));
-  else
-    emit_insn (gen_umulsidi3_internal (operands[0], operands[1], operands[2]));
+  [(set_attr "type"    "imul")
+   (set_attr "mode"    "SI")
+   (set_attr "length"  "24")])
 
-  DONE;
-}")
+(define_insn "*mulsidi3_64bit_parts"
+  [(set (match_operand:DI 0 "register_operand" "=l")
+       (sign_extend:DI
+          (mult:SI (match_operand:SI 2 "register_operand" "d")
+                   (match_operand:SI 3 "register_operand" "d"))))
+   (set (match_operand:DI 1 "register_operand" "=h")
+       (ashiftrt:DI
+          (mult:DI
+             (match_operator:DI 4 "extend_operator" [(match_dup 2)])
+             (match_operator:DI 5 "extend_operator" [(match_dup 3)]))
+          (const_int 32)))]
+  "TARGET_64BIT && GET_CODE (operands[4]) == GET_CODE (operands[5])"
+  {
+    if (GET_CODE (operands[4]) == SIGN_EXTEND)
+      return "mult\t%2,%3";
+    else
+      return "multu\t%2,%3";
+  }
+  [(set_attr "type" "imul")
+   (set_attr "mode" "SI")])
 
+(define_expand "umulsidi3"
+  [(parallel
+      [(set (match_operand:DI 0 "register_operand" "")
+           (mult:DI
+              (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
+              (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
+       (clobber (scratch:DI))
+       (clobber (scratch:DI))
+       (clobber (scratch:DI))])]
+  ""
+  {
+    if (!TARGET_64BIT)
+      {
+        emit_insn (gen_umulsidi3_32bit (operands[0], operands[1],
+                                       operands[2]));
+       DONE;
+      }
+  })
 
-(define_insn "umulsidi3_internal"
+(define_insn "umulsidi3_32bit"
   [(set (match_operand:DI 0 "register_operand" "=x")
-       (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
-                (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))
-   (clobber (match_scratch:SI 3 "=a"))]
+       (mult:DI
+          (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
+          (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
   "!TARGET_64BIT"
   "multu\\t%1,%2"
   [(set_attr "type"    "imul")
    (set_attr "mode"    "SI")])
 
-(define_insn "umulsidi3_64bit"
-  [(set (match_operand:DI 0 "register_operand" "=a")
-       (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
-                (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))
-   (clobber (match_scratch:DI 3 "=l"))
-   (clobber (match_scratch:DI 4 "=h"))]
-  "TARGET_64BIT"
-  "multu\\t%1,%2"
-  [(set_attr "type"    "imul")
-   (set_attr "mode"    "SI")])
-
-;; Widening multiply with negation.  It isn't worth using this pattern
-;; for 64-bit code since the reload sequence for HILO_REGNUM is so long.
+;; Widening multiply with negation.
 (define_insn "*muls_di"
   [(set (match_operand:DI 0 "register_operand" "=x")
         (neg:DI
         (mult:DI
          (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
-         (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))))
-   (clobber (match_scratch:SI 3 "=a"))]
+         (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
   "!TARGET_64BIT && ISA_HAS_MULS"
   "muls\\t$0,%1,%2"
   [(set_attr "type"     "imul")
        (neg:DI
         (mult:DI
          (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
-         (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))))
-   (clobber (match_scratch:SI 3 "=a"))]
+         (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
   "!TARGET_64BIT && ISA_HAS_MULS"
   "mulsu\\t$0,%1,%2"
   [(set_attr "type"     "imul")
    (set_attr "length"   "4")
    (set_attr "mode"     "SI")])
 
-;; Not used for 64-bit code: see comment for *muls_di.
 (define_insn "*smsac_di"
   [(set (match_operand:DI 0 "register_operand" "=x")
-        (minus:DI (match_operand:DI 3 "register_operand" "0")
-                 (mult:DI
-                  (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
-                  (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))))
-   (clobber (match_scratch:SI 4 "=a"))]
+        (minus:DI
+          (match_operand:DI 3 "register_operand" "0")
+          (mult:DI
+             (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
+             (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
   "!TARGET_64BIT && ISA_HAS_MSAC"
   "*
 {
 
 (define_insn "*umsac_di"
   [(set (match_operand:DI 0 "register_operand" "=x")
-       (minus:DI (match_operand:DI 3 "register_operand" "0")
-                 (mult:DI
-                  (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
-                  (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))))
-   (clobber (match_scratch:SI 4 "=a"))]
+       (minus:DI
+          (match_operand:DI 3 "register_operand" "0")
+          (mult:DI
+             (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
+             (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
   "!TARGET_64BIT && ISA_HAS_MSAC"
   "*
 {
 
 ;; _highpart patterns
 (define_expand "umulsi3_highpart"
-  [(set (match_operand:SI 0 "register_operand" "=h")
+  [(set (match_operand:SI 0 "register_operand" "")
        (truncate:SI
         (lshiftrt:DI
-         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
-                  (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
+         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
+                  (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
          (const_int 32))))]
   ""
   "
          (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
                   (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
          (const_int 32))))
-   (clobber (match_scratch:SI 3 "=l"))
-   (clobber (match_scratch:SI 4 "=a"))]
+   (clobber (match_scratch:SI 3 "=l"))]
   "!ISA_HAS_MULHI"
   "multu\\t%1,%2"
   [(set_attr "type"   "imul")
                   (zero_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
          (const_int 32))))
    (clobber (match_scratch:SI 3 "=l,l"))
-   (clobber (match_scratch:SI 4 "=a,a"))
-   (clobber (match_scratch:SI 5 "=X,h"))]
+   (clobber (match_scratch:SI 4 "=X,h"))]
   "ISA_HAS_MULHI"
   "@
    multu\\t%1,%2
                    (zero_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
          (const_int 32))))
    (clobber (match_scratch:SI 3 "=l,l"))
-   (clobber (match_scratch:SI 4 "=a,a"))
-   (clobber (match_scratch:SI 5 "=X,h"))]
+   (clobber (match_scratch:SI 4 "=X,h"))]
   "ISA_HAS_MULHI"
   "@
    mulshiu\\t%.,%1,%2
    (set_attr "length" "4")])
 
 (define_expand "smulsi3_highpart"
-  [(set (match_operand:SI 0 "register_operand" "=h")
+  [(set (match_operand:SI 0 "register_operand" "")
        (truncate:SI
         (lshiftrt:DI
-         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
-                  (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
+         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
+                  (sign_extend:DI (match_operand:SI 2 "register_operand" "")))
          (const_int 32))))]
   ""
   "
          (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
                   (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
          (const_int 32))))
-   (clobber (match_scratch:SI 3 "=l"))
-   (clobber (match_scratch:SI 4 "=a"))]
+   (clobber (match_scratch:SI 3 "=l"))]
   "!ISA_HAS_MULHI"
   "mult\\t%1,%2"
   [(set_attr "type"    "imul")
                   (sign_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
          (const_int 32))))
    (clobber (match_scratch:SI 3 "=l,l"))
-   (clobber (match_scratch:SI 4 "=a,a"))
-   (clobber (match_scratch:SI 5 "=X,h"))]
+   (clobber (match_scratch:SI 4 "=X,h"))]
   "ISA_HAS_MULHI"
   "@
    mult\\t%1,%2
                    (sign_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
          (const_int 32))))
    (clobber (match_scratch:SI 3 "=l,l"))
-   (clobber (match_scratch:SI 4 "=a,a"))
-   (clobber (match_scratch:SI 5 "=X,h"))]
+   (clobber (match_scratch:SI 4 "=X,h"))]
   "ISA_HAS_MULHI"
   "@
    mulshi\\t%.,%1,%2
           (sign_extend:TI (match_operand:DI 1 "register_operand" "d"))
           (sign_extend:TI (match_operand:DI 2 "register_operand" "d")))
          (const_int 64))))
-   (clobber (match_scratch:DI 3 "=l"))
-   (clobber (match_scratch:DI 4 "=a"))]
+   (clobber (match_scratch:DI 3 "=l"))]
   "TARGET_64BIT"
   "dmult\\t%1,%2"
   [(set_attr "type"    "imul")
           (zero_extend:TI (match_operand:DI 1 "register_operand" "d"))
           (zero_extend:TI (match_operand:DI 2 "register_operand" "d")))
          (const_int 64))))
-   (clobber (match_scratch:DI 3 "=l"))
-   (clobber (match_scratch:DI 4 "=a"))]
+   (clobber (match_scratch:DI 3 "=l"))]
   "TARGET_64BIT"
   "dmultu\\t%1,%2"
   [(set_attr "type"    "imul")
        (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
                          (match_operand:SI 2 "register_operand" "d"))
                 (match_dup 0)))
-   (clobber (match_scratch:SI 3 "=h"))
-   (clobber (match_scratch:SI 4 "=a"))]
+   (clobber (match_scratch:SI 3 "=h"))]
   "TARGET_MAD"
   "mad\\t%1,%2"
   [(set_attr "type"    "imadd")
    (set_attr "mode"    "SI")])
 
-;; Only use this pattern in 32-bit code: see *muls_di.
 (define_insn "*umul_acc_di"
   [(set (match_operand:DI 0 "register_operand" "=x")
        (plus:DI
         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
                  (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
-        (match_operand:DI 3 "register_operand" "0")))
-   (clobber (match_scratch:SI 4 "=a"))]
+        (match_operand:DI 3 "register_operand" "0")))]
   "(TARGET_MAD || ISA_HAS_MACC)
    && !TARGET_64BIT"
   "*
        (plus:DI
         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
                  (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
-        (match_operand:DI 3 "register_operand" "0")))
-   (clobber (match_scratch:SI 4 "=a"))]
+        (match_operand:DI 3 "register_operand" "0")))]
   "(TARGET_MAD || ISA_HAS_MACC)
    && !TARGET_64BIT"
   "*
 ;; available.
 
 (define_expand "divmodsi4"
-  [(set (match_operand:SI 0 "register_operand" "=d")
-       (div:SI (match_operand:SI 1 "register_operand" "d")
-               (match_operand:SI 2 "register_operand" "d")))
-   (set (match_operand:SI 3 "register_operand" "=d")
+  [(set (match_operand:SI 0 "register_operand" "")
+       (div:SI (match_operand:SI 1 "register_operand" "")
+               (match_operand:SI 2 "register_operand" "")))
+   (set (match_operand:SI 3 "register_operand" "")
        (mod:SI (match_dup 1)
-               (match_dup 2)))
-   (clobber (match_scratch:SI 4 "=l"))
-   (clobber (match_scratch:SI 5 "=h"))
-   (clobber (match_scratch:SI 6 "=a"))]
+               (match_dup 2)))]
   "optimize"
   "
 {
                (match_operand:SI 2 "register_operand" "d")))
    (set (match_operand:SI 3 "register_operand" "=h")
        (mod:SI (match_dup 1)
-               (match_dup 2)))
-   (clobber (match_scratch:SI 4 "=a"))]
+               (match_dup 2)))]
   "optimize"
   "div\\t$0,%1,%2"
   [(set_attr "type"    "idiv")
    (set_attr "mode"    "SI")])
 
 (define_expand "divmoddi4"
-  [(set (match_operand:DI 0 "register_operand" "=d")
-       (div:DI (match_operand:DI 1 "register_operand" "d")
-               (match_operand:DI 2 "register_operand" "d")))
-   (set (match_operand:DI 3 "register_operand" "=d")
+  [(set (match_operand:DI 0 "register_operand" "")
+       (div:DI (match_operand:DI 1 "register_operand" "")
+               (match_operand:DI 2 "register_operand" "")))
+   (set (match_operand:DI 3 "register_operand" "")
        (mod:DI (match_dup 1)
-               (match_dup 2)))
-   (clobber (match_scratch:DI 4 "=l"))
-   (clobber (match_scratch:DI 5 "=h"))
-   (clobber (match_scratch:DI 6 "=a"))]
+               (match_dup 2)))]
   "TARGET_64BIT && optimize"
   "
 {
                (match_operand:DI 2 "register_operand" "d")))
    (set (match_operand:DI 3 "register_operand" "=h")
        (mod:DI (match_dup 1)
-               (match_dup 2)))
-   (clobber (match_scratch:DI 4 "=a"))]
+               (match_dup 2)))]
   "TARGET_64BIT && optimize"
   "ddiv\\t$0,%1,%2"
   [(set_attr "type"    "idiv")
    (set_attr "mode"    "SI")])
 
 (define_expand "udivmodsi4"
-  [(set (match_operand:SI 0 "register_operand" "=d")
-       (udiv:SI (match_operand:SI 1 "register_operand" "d")
-                (match_operand:SI 2 "register_operand" "d")))
-   (set (match_operand:SI 3 "register_operand" "=d")
+  [(set (match_operand:SI 0 "register_operand" "")
+       (udiv:SI (match_operand:SI 1 "register_operand" "")
+                (match_operand:SI 2 "register_operand" "")))
+   (set (match_operand:SI 3 "register_operand" "")
        (umod:SI (match_dup 1)
-                (match_dup 2)))
-   (clobber (match_scratch:SI 4 "=l"))
-   (clobber (match_scratch:SI 5 "=h"))
-   (clobber (match_scratch:SI 6 "=a"))]
+                (match_dup 2)))]
   "optimize"
   "
 {
                 (match_operand:SI 2 "register_operand" "d")))
    (set (match_operand:SI 3 "register_operand" "=h")
        (umod:SI (match_dup 1)
-                (match_dup 2)))
-   (clobber (match_scratch:SI 4 "=a"))]
+                (match_dup 2)))]
   "optimize"
   "divu\\t$0,%1,%2"
   [(set_attr "type"    "idiv")
    (set_attr "mode"    "SI")])
 
 (define_expand "udivmoddi4"
-  [(set (match_operand:DI 0 "register_operand" "=d")
-       (udiv:DI (match_operand:DI 1 "register_operand" "d")
-                (match_operand:DI 2 "register_operand" "d")))
-   (set (match_operand:DI 3 "register_operand" "=d")
+  [(set (match_operand:DI 0 "register_operand" "")
+       (udiv:DI (match_operand:DI 1 "register_operand" "")
+                (match_operand:DI 2 "register_operand" "")))
+   (set (match_operand:DI 3 "register_operand" "")
        (umod:DI (match_dup 1)
-                (match_dup 2)))
-   (clobber (match_scratch:DI 4 "=l"))
-   (clobber (match_scratch:DI 5 "=h"))
-   (clobber (match_scratch:DI 6 "=a"))]
+                (match_dup 2)))]
   "TARGET_64BIT && optimize"
   "
 {
                 (match_operand:DI 2 "register_operand" "d")))
    (set (match_operand:DI 3 "register_operand" "=h")
        (umod:DI (match_dup 1)
-                (match_dup 2)))
-   (clobber (match_scratch:DI 4 "=a"))]
+                (match_dup 2)))]
   "TARGET_64BIT && optimize"
   "ddivu\\t$0,%1,%2"
   [(set_attr "type"    "idiv")
    (set_attr "length" "12")])
 
 (define_expand "divsi3"
-  [(set (match_operand:SI 0 "register_operand" "=l")
-       (div:SI (match_operand:SI 1 "register_operand" "d")
-               (match_operand:SI 2 "register_operand" "d")))
-   (clobber (match_scratch:SI 3 "=h"))
-   (clobber (match_scratch:SI 4 "=a"))]
+  [(set (match_operand:SI 0 "register_operand" "")
+       (div:SI (match_operand:SI 1 "register_operand" "")
+               (match_operand:SI 2 "register_operand" "")))]
   "!optimize"
   "
 {
 (define_insn "divsi3_internal"
   [(set (match_operand:SI 0 "register_operand" "=l")
        (div:SI (match_operand:SI 1 "register_operand" "d")
-               (match_operand:SI 2 "nonmemory_operand" "di")))
-   (clobber (match_scratch:SI 3 "=h"))
-   (clobber (match_scratch:SI 4 "=a"))]
+               (match_operand:SI 2 "register_operand" "d")))
+   (clobber (match_scratch:SI 3 "=h"))]
   "!optimize"
   "div\\t$0,%1,%2"
   [(set_attr "type"    "idiv")
    (set_attr "mode"    "SI")])
 
 (define_expand "divdi3"
-  [(set (match_operand:DI 0 "register_operand" "=l")
-       (div:DI (match_operand:DI 1 "register_operand" "d")
-               (match_operand:DI 2 "register_operand" "d")))
-   (clobber (match_scratch:DI 3 "=h"))
-   (clobber (match_scratch:DI 4 "=a"))]
+  [(set (match_operand:DI 0 "register_operand" "")
+       (div:DI (match_operand:DI 1 "register_operand" "")
+               (match_operand:DI 2 "register_operand" "")))]
   "TARGET_64BIT && !optimize"
   "
 {
 (define_insn "divdi3_internal"
   [(set (match_operand:DI 0 "register_operand" "=l")
        (div:DI (match_operand:DI 1 "register_operand" "d")
-               (match_operand:DI 2 "nonmemory_operand" "di")))
-   (clobber (match_scratch:SI 3 "=h"))
-   (clobber (match_scratch:SI 4 "=a"))]
+               (match_operand:DI 2 "register_operand" "d")))
+   (clobber (match_scratch:SI 3 "=h"))]
   "TARGET_64BIT && !optimize"
   "ddiv\\t$0,%1,%2"
   [(set_attr "type"    "idiv")
    (set_attr "mode"    "DI")])
 
 (define_expand "modsi3"
-  [(set (match_operand:SI 0 "register_operand" "=h")
-       (mod:SI (match_operand:SI 1 "register_operand" "d")
-               (match_operand:SI 2 "register_operand" "d")))
-   (clobber (match_scratch:SI 3 "=l"))
-   (clobber (match_scratch:SI 4 "=a"))]
+  [(set (match_operand:SI 0 "register_operand" "")
+       (mod:SI (match_operand:SI 1 "register_operand" "")
+               (match_operand:SI 2 "register_operand" "")))]
   "!optimize"
   "
 {
 (define_insn "modsi3_internal"
   [(set (match_operand:SI 0 "register_operand" "=h")
        (mod:SI (match_operand:SI 1 "register_operand" "d")
-               (match_operand:SI 2 "nonmemory_operand" "di")))
-   (clobber (match_scratch:SI 3 "=l"))
-   (clobber (match_scratch:SI 4 "=a"))]
+               (match_operand:SI 2 "register_operand" "d")))
+   (clobber (match_scratch:SI 3 "=l"))]
   "!optimize"
   "div\\t$0,%1,%2"
   [(set_attr "type"    "idiv")
    (set_attr "mode"    "SI")])
 
 (define_expand "moddi3"
-  [(set (match_operand:DI 0 "register_operand" "=h")
-       (mod:DI (match_operand:DI 1 "register_operand" "d")
-               (match_operand:DI 2 "register_operand" "d")))
-   (clobber (match_scratch:DI 3 "=l"))
-   (clobber (match_scratch:DI 4 "=a"))]
+  [(set (match_operand:DI 0 "register_operand" "")
+       (mod:DI (match_operand:DI 1 "register_operand" "")
+               (match_operand:DI 2 "register_operand" "")))]
   "TARGET_64BIT && !optimize"
   "
 {
 (define_insn "moddi3_internal"
   [(set (match_operand:DI 0 "register_operand" "=h")
        (mod:DI (match_operand:DI 1 "register_operand" "d")
-               (match_operand:DI 2 "nonmemory_operand" "di")))
-   (clobber (match_scratch:SI 3 "=l"))
-   (clobber (match_scratch:SI 4 "=a"))]
+               (match_operand:DI 2 "register_operand" "d")))
+   (clobber (match_scratch:SI 3 "=l"))]
   "TARGET_64BIT && !optimize"
   "ddiv\\t$0,%1,%2"
   [(set_attr "type"    "idiv")
    (set_attr "mode"    "DI")])
 
 (define_expand "udivsi3"
-  [(set (match_operand:SI 0 "register_operand" "=l")
-       (udiv:SI (match_operand:SI 1 "register_operand" "d")
-                (match_operand:SI 2 "register_operand" "d")))
-   (clobber (match_scratch:SI 3 "=h"))
-   (clobber (match_scratch:SI 4 "=a"))]
+  [(set (match_operand:SI 0 "register_operand" "")
+       (udiv:SI (match_operand:SI 1 "register_operand" "")
+                (match_operand:SI 2 "register_operand" "")))]
   "!optimize"
   "
 {
 (define_insn "udivsi3_internal"
   [(set (match_operand:SI 0 "register_operand" "=l")
        (udiv:SI (match_operand:SI 1 "register_operand" "d")
-                (match_operand:SI 2 "nonmemory_operand" "di")))
-   (clobber (match_scratch:SI 3 "=h"))
-   (clobber (match_scratch:SI 4 "=a"))]
+                (match_operand:SI 2 "register_operand" "d")))
+   (clobber (match_scratch:SI 3 "=h"))]
   "!optimize"
   "divu\\t$0,%1,%2"
   [(set_attr "type"    "idiv")
    (set_attr "mode"    "SI")])
 
 (define_expand "udivdi3"
-  [(set (match_operand:DI 0 "register_operand" "=l")
-       (udiv:DI (match_operand:DI 1 "register_operand" "d")
-                (match_operand:DI 2 "register_operand" "di")))
-   (clobber (match_scratch:DI 3 "=h"))
-   (clobber (match_scratch:DI 4 "=a"))]
+  [(set (match_operand:DI 0 "register_operand" "")
+       (udiv:DI (match_operand:DI 1 "register_operand" "")
+                (match_operand:DI 2 "register_operand" "")))]
   "TARGET_64BIT && !optimize"
   "
 {
 (define_insn "udivdi3_internal"
   [(set (match_operand:DI 0 "register_operand" "=l")
        (udiv:DI (match_operand:DI 1 "register_operand" "d")
-                (match_operand:DI 2 "nonmemory_operand" "di")))
-   (clobber (match_scratch:SI 3 "=h"))
-   (clobber (match_scratch:SI 4 "=a"))]
+                (match_operand:DI 2 "register_operand" "d")))
+   (clobber (match_scratch:SI 3 "=h"))]
   "TARGET_64BIT && !optimize"
   "ddivu\\t$0,%1,%2"
   [(set_attr "type"    "idiv")
    (set_attr "mode"    "DI")])
 
 (define_expand "umodsi3"
-  [(set (match_operand:SI 0 "register_operand" "=h")
-       (umod:SI (match_operand:SI 1 "register_operand" "d")
-                (match_operand:SI 2 "register_operand" "d")))
-   (clobber (match_scratch:SI 3 "=l"))
-   (clobber (match_scratch:SI 4 "=a"))]
+  [(set (match_operand:SI 0 "register_operand" "")
+       (umod:SI (match_operand:SI 1 "register_operand" "")
+                (match_operand:SI 2 "register_operand" "")))]
   "!optimize"
   "
 {
 (define_insn "umodsi3_internal"
   [(set (match_operand:SI 0 "register_operand" "=h")
        (umod:SI (match_operand:SI 1 "register_operand" "d")
-                (match_operand:SI 2 "nonmemory_operand" "di")))
-   (clobber (match_scratch:SI 3 "=l"))
-   (clobber (match_scratch:SI 4 "=a"))]
+                (match_operand:SI 2 "register_operand" "d")))
+   (clobber (match_scratch:SI 3 "=l"))]
   "!optimize"
   "divu\\t$0,%1,%2"
   [(set_attr "type"    "idiv")
    (set_attr "mode"    "SI")])
 
 (define_expand "umoddi3"
-  [(set (match_operand:DI 0 "register_operand" "=h")
-       (umod:DI (match_operand:DI 1 "register_operand" "d")
-                (match_operand:DI 2 "register_operand" "di")))
-   (clobber (match_scratch:DI 3 "=l"))
-   (clobber (match_scratch:DI 4 "=a"))]
+  [(set (match_operand:DI 0 "register_operand" "")
+       (umod:DI (match_operand:DI 1 "register_operand" "")
+                (match_operand:DI 2 "register_operand" "")))]
   "TARGET_64BIT && !optimize"
   "
 {
 (define_insn "umoddi3_internal"
   [(set (match_operand:DI 0 "register_operand" "=h")
        (umod:DI (match_operand:DI 1 "register_operand" "d")
-                (match_operand:DI 2 "nonmemory_operand" "di")))
-   (clobber (match_scratch:SI 3 "=l"))
-   (clobber (match_scratch:SI 4 "=a"))]
+                (match_operand:DI 2 "register_operand" "d")))
+   (clobber (match_scratch:SI 3 "=l"))]
   "TARGET_64BIT && !optimize"
   "ddivu\\t$0,%1,%2"
   [(set_attr "type"    "idiv")
@@ -5143,17 +5106,17 @@ move\\t%0,%z4\\n\\
    (set_attr "length"  "8,8,8,8,12,*,*,8")])
 
 (define_insn "movdi_internal2"
-  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*x,*d,*x,*a,*B*C*D,*B*C*D,*d,*m")
-       (match_operand:DI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*J,*x,*d,*J,*d,*m,*B*C*D,*B*C*D"))]
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*x,*d,*x,*B*C*D,*B*C*D,*d,*m")
+       (match_operand:DI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*J,*x,*d,*d,*m,*B*C*D,*B*C*D"))]
   "TARGET_64BIT && !TARGET_MIPS16
    && (register_operand (operands[0], DImode)
        || register_operand (operands[1], DImode)
        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
        || operands[1] == CONST0_RTX (DImode))"
   { return mips_output_move (operands[0], operands[1]); }
-  [(set_attr "type"    "move,const,const,load,store,move,xfer,load,xfer,store,hilo,hilo,hilo,hilo,xfer,load,xfer,store")
+  [(set_attr "type"    "move,const,const,load,store,move,xfer,load,xfer,store,hilo,hilo,hilo,xfer,load,xfer,store")
    (set_attr "mode"    "DI")
-   (set_attr "length"  "4,*,*,*,*,4,4,*,4,*,4,4,4,8,8,*,8,*")])
+   (set_attr "length"  "4,*,*,*,*,4,4,*,4,*,4,4,4,8,*,8,*")])
 
 (define_insn "*movdi_internal2_mips16"
   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m,*d")
@@ -5224,168 +5187,6 @@ move\\t%0,%z4\\n\\
     }
 }")
 
-;; Handle input reloads in DImode.
-;; This is mainly to handle reloading HILO_REGNUM.  Note that we may
-;; see it as the source or the destination, depending upon which way
-;; reload handles the instruction.
-;; Making the second operand TImode is a trick.  The compiler may
-;; reuse the same register for operand 0 and operand 2.  Using TImode
-;; gives us two registers, so we can always use the one which is not
-;; used.
-
-(define_expand "reload_indi"
-  [(set (match_operand:DI 0 "register_operand" "=b")
-       (match_operand:DI 1 "" "b"))
-   (clobber (match_operand:TI 2 "register_operand" "=&d"))]
-  "TARGET_64BIT"
-  "
-{
-  rtx scratch = gen_rtx_REG (DImode,
-                            (REGNO (operands[0]) == REGNO (operands[2])
-                             ? REGNO (operands[2]) + 1
-                             : REGNO (operands[2])));
-
-  if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
-    {
-      if (GET_CODE (operands[1]) == MEM)
-       {
-         rtx memword, offword, hi_word, lo_word;
-         rtx addr = find_replacement (&XEXP (operands[1], 0));
-         rtx op1 = replace_equiv_address (operands[1], addr);
-
-         scratch = gen_rtx_REG (SImode, REGNO (scratch));
-         memword = adjust_address (op1, SImode, 0);
-         offword = adjust_address (op1, SImode, 4);
-
-         if (BYTES_BIG_ENDIAN)
-           {
-             hi_word = memword;
-             lo_word = offword;
-           }
-         else
-           {
-             hi_word = offword;
-             lo_word = memword;
-           }
-         emit_move_insn (scratch, hi_word);
-         emit_move_insn (gen_rtx_REG (SImode, 64), scratch);
-         emit_move_insn (scratch, lo_word);
-         emit_move_insn (gen_rtx (REG, SImode, 65), scratch);
-         emit_insn (gen_hilo_delay (operands[0]));
-       }
-      else
-       {
-         emit_insn (gen_ashrdi3 (scratch, operands[1], GEN_INT (32)));
-         emit_insn (gen_movdi (gen_rtx_REG (DImode, 64), scratch));
-         emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32)));
-         emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32)));
-         emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), scratch));
-          emit_insn (gen_hilo_delay (operands[0]));
-       }
-      DONE;
-    }
-  if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
-    {
-      emit_insn (gen_movdi (scratch, gen_rtx_REG (DImode, 65)));
-      emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
-      emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
-      emit_insn (gen_movdi (operands[0], gen_rtx_REG (DImode, 64)));
-      emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
-      emit_insn (gen_iordi3 (operands[0], operands[0], scratch));
-      emit_insn (gen_hilo_delay (operands[1]));
-      DONE;
-    }
-  /* This handles moves between a float register and HI/LO.  */
-  emit_move_insn (scratch, operands[1]);
-  emit_move_insn (operands[0], scratch);
-  DONE;
-}")
-
-;; Handle output reloads in DImode.
-
-;; Reloading HILO_REG in MIPS16 mode requires two scratch registers, so we
-;; use a TImode scratch reg.
-
-(define_expand "reload_outdi"
-  [(set (match_operand:DI 0 "general_operand" "=b")
-       (match_operand:DI 1 "register_operand" "b"))
-   (clobber (match_operand:TI 2 "register_operand" "=&d"))]
-  "TARGET_64BIT"
-  "
-{
-  rtx scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
-
-  if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
-    {
-      emit_insn (gen_ashrdi3 (scratch, operands[1], GEN_INT (32)));
-      emit_insn (gen_movdi (gen_rtx (REG, DImode, 64), scratch));
-      emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32)));
-      emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32)));
-      emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), scratch));
-      emit_insn (gen_hilo_delay (operands[0]));
-      DONE;
-    }
-  if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
-    {
-      if (GET_CODE (operands[0]) == MEM)
-       {
-         rtx scratch, memword, offword, hi_word, lo_word;
-         rtx addr = find_replacement (&XEXP (operands[0], 0));
-         rtx op0 = replace_equiv_address (operands[0], addr);
-
-         scratch = gen_rtx_REG (SImode, REGNO (operands[2]));
-         memword = adjust_address (op0, SImode, 0);
-         offword = adjust_address (op0, SImode, 4);
-
-         if (BYTES_BIG_ENDIAN)
-           {
-             hi_word = memword;
-             lo_word = offword;
-           }
-         else
-           {
-             hi_word = offword;
-             lo_word = memword;
-           }
-         emit_move_insn (scratch, gen_rtx_REG (SImode, 64));
-         emit_move_insn (hi_word, scratch);
-         emit_move_insn (scratch, gen_rtx_REG (SImode, 65));
-         emit_move_insn (lo_word, scratch);
-         emit_insn (gen_hilo_delay (operands[1]));
-       }
-      else if (TARGET_MIPS16 && ! M16_REG_P (REGNO (operands[0])))
-       {
-         /* Handle the case where operand[0] is not a 'd' register,
-            and hence we can not directly move from the HILO register
-            into it.  */
-         rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
-         emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65)));
-         emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
-         emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
-         emit_insn (gen_movdi (scratch2, gen_rtx (REG, DImode, 64)));
-         emit_insn (gen_ashldi3 (scratch2, scratch2, GEN_INT (32)));
-         emit_insn (gen_iordi3 (scratch, scratch, scratch2));
-         emit_insn (gen_movdi (operands[0], scratch));
-         emit_insn (gen_hilo_delay (operands[1]));
-       }
-      else
-       {
-         emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65)));
-         emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
-         emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
-         emit_insn (gen_movdi (operands[0], gen_rtx (REG, DImode, 64)));
-         emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
-         emit_insn (gen_iordi3 (operands[0], operands[0], scratch));
-         emit_insn (gen_hilo_delay (operands[1]));
-       }
-      DONE;
-    }
-  /* This handles moves between a float register and HI/LO.  */
-  emit_move_insn (scratch, operands[1]);
-  emit_move_insn (operands[0], scratch);
-  DONE;
-}")
-
 ;; 32-bit Integer moves
 
 ;; Unlike most other insns, the move insns can't be split with
@@ -5443,25 +5244,25 @@ move\\t%0,%z4\\n\\
 ;; in FP registers (off by default, use -mdebugh to enable).
 
 (define_insn "movsi_internal"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*d,*z,*x,*d,*x,*d,*B*C*D,*B*C*D,*d,*m")
-       (match_operand:SI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*z,*d,J,*x,*d,*a,*d,*m,*B*C*D,*B*C*D"))]
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*d,*z,*x,*d,*x,*B*C*D,*B*C*D,*d,*m")
+       (match_operand:SI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*z,*d,J,*x,*d,*d,*m,*B*C*D,*B*C*D"))]
   "!TARGET_MIPS16
    && (register_operand (operands[0], SImode)
        || register_operand (operands[1], SImode)
        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
   { return mips_output_move (operands[0], operands[1]); }
-  [(set_attr "type"    "move,const,const,load,store,move,xfer,load,xfer,store,xfer,xfer,hilo,hilo,hilo,hilo,xfer,load,xfer,store")
+  [(set_attr "type"    "move,const,const,load,store,move,xfer,load,xfer,store,xfer,xfer,hilo,hilo,hilo,xfer,load,xfer,store")
    (set_attr "mode"    "SI")
-   (set_attr "length"  "4,*,*,*,*,4,4,*,4,*,4,4,4,4,4,4,4,*,4,*")])
+   (set_attr "length"  "4,*,*,*,*,4,4,*,4,*,4,4,4,4,4,4,*,4,*")])
 
 (define_insn ""
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m,*d,*d")
-       (match_operand:SI 1 "move_operand" "d,d,y,K,N,U,m,d,*x,*a"))]
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m,*d")
+       (match_operand:SI 1 "move_operand" "d,d,y,K,N,U,m,d,*x"))]
   "TARGET_MIPS16
    && (register_operand (operands[0], SImode)
        || register_operand (operands[1], SImode))"
   { return mips_output_move (operands[0], operands[1]); }
-  [(set_attr "type"    "move,move,move,arith,arith,const,load,store,hilo,hilo")
+  [(set_attr "type"    "move,move,move,arith,arith,const,load,store,hilo")
    (set_attr "mode"    "SI")
    (set_attr_alternative "length"
                [(const_int 4)
@@ -5476,7 +5277,6 @@ move\\t%0,%z4\\n\\
                 (const_string "*")
                 (const_string "*")
                 (const_string "*")
-                (const_int 4)
                 (const_int 4)])])
 
 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
@@ -5564,157 +5364,6 @@ move\\t%0,%z4\\n\\
   operands[1] = GEN_INT (- INTVAL (operands[1]));
 }")
 
-;; Reload HILO_REGNUM in SI mode.  This needs a scratch register in
-;; order to set the sign bit correctly in the HI register.
-
-(define_expand "reload_outsi"
-  [(set (match_operand:SI 0 "general_operand" "=b")
-       (match_operand:SI 1 "register_operand" "b"))
-   (clobber (match_operand:SI 2 "register_operand" "=&d"))]
-  "TARGET_64BIT || TARGET_MIPS16"
-  "
-{
-  if (TARGET_64BIT
-      && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
-    {
-      emit_insn (gen_movsi (gen_rtx_REG (SImode, 65), operands[1]));
-      emit_insn (gen_ashrsi3 (operands[2], operands[1], GEN_INT (31)));
-      emit_insn (gen_movsi (gen_rtx (REG, SImode, 64), operands[2]));
-      emit_insn (gen_hilo_delay (operands[0]));
-      DONE;
-    }
-  /* Use a mult to reload LO on mips16.  ??? This is hideous.  */
-  if (TARGET_MIPS16
-      && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == LO_REGNUM)
-    {
-      emit_insn (gen_movsi (operands[2], GEN_INT (1)));
-      /* This is gen_mulsi3_internal, but we need to fill in the
-        scratch registers.  */
-      emit_insn (gen_rtx (PARALLEL, VOIDmode,
-                         gen_rtvec (3,
-                                    gen_rtx (SET, VOIDmode,
-                                             operands[0],
-                                             gen_rtx (MULT, SImode,
-                                                      operands[1],
-                                                      operands[2])),
-                                    gen_rtx (CLOBBER, VOIDmode,
-                                             gen_rtx (REG, SImode, 64)),
-                                    gen_rtx (CLOBBER, VOIDmode,
-                                             gen_rtx (REG, SImode, 66)))));
-      DONE;
-    }
-  /* FIXME: I don't know how to get a value into the HI register.  */
-  if (GET_CODE (operands[0]) == REG
-      && (TARGET_MIPS16 ? M16_REG_P (REGNO (operands[0]))
-         : GP_REG_P (REGNO (operands[0]))))
-    {
-      emit_move_insn (operands[0], operands[1]);
-      DONE;
-    }
-  /* This handles moves between a float register and HI/LO.  */
-  emit_move_insn (operands[2], operands[1]);
-  emit_move_insn (operands[0], operands[2]);
-  DONE;
-}")
-
-;; Reload a value into HI or LO.  There is no mthi or mtlo on mips16,
-;; so we use a mult.  ??? This is hideous, and we ought to figure out
-;; something better.
-
-;; We use no predicate for operand1, because it may be a PLUS, and there
-;; is no convenient predicate for that.
-
-(define_expand "reload_insi"
-  [(set (match_operand:SI 0 "register_operand" "=b")
-       (match_operand:SI 1 "" "b"))
-   (clobber (match_operand:SI 2 "register_operand" "=&d"))]
-  "TARGET_MIPS16"
-  "
-{
-  if (TARGET_MIPS16
-      && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == LO_REGNUM)
-    {
-      emit_insn (gen_movsi (operands[2], GEN_INT (1)));
-      /* This is gen_mulsi3_internal, but we need to fill in the
-        scratch registers.  */
-      emit_insn (gen_rtx (PARALLEL, VOIDmode,
-                         gen_rtvec (3,
-                                    gen_rtx (SET, VOIDmode,
-                                             operands[0],
-                                             gen_rtx (MULT, SImode,
-                                                      operands[1],
-                                                      operands[2])),
-                                    gen_rtx (CLOBBER, VOIDmode,
-                                             gen_rtx (REG, SImode, 64)),
-                                    gen_rtx (CLOBBER, VOIDmode,
-                                             gen_rtx (REG, SImode, 66)))));
-      DONE;
-    }
-
-  /* If this is a plus, then this must be an add of the stack pointer against
-     either a hard register or a pseudo.  */
-  if (TARGET_MIPS16 && GET_CODE (operands[1]) == PLUS)
-    {
-      rtx plus_op;
-
-      if (XEXP (operands[1], 0) == stack_pointer_rtx)
-       plus_op = XEXP (operands[1], 1);
-      else if (XEXP (operands[1], 1) == stack_pointer_rtx)
-       plus_op = XEXP (operands[1], 0);
-      else
-       abort ();
-
-      /* We should have a register now.  */
-      if (GET_CODE (plus_op) != REG)
-       abort ();
-
-      if (REGNO (plus_op) < FIRST_PSEUDO_REGISTER)
-       {
-         /* We have to have at least one temporary register which is not
-            overlapping plus_op.  */
-         if (! rtx_equal_p (plus_op, operands[0]))
-           {
-             emit_move_insn (operands[0], stack_pointer_rtx);
-             emit_insn (gen_addsi3 (operands[0], operands[0], plus_op));
-           }
-         else if (! rtx_equal_p (plus_op, operands[2]))
-           {
-             emit_move_insn (operands[2], stack_pointer_rtx);
-             emit_insn (gen_addsi3 (operands[0], plus_op, operands[2]));
-           }
-         else
-           abort ();
-       }
-      else
-       {
-         /* We need two registers in this case.  */
-         if (! rtx_equal_p (operands[0], operands[2]))
-           {
-             emit_move_insn (operands[0], stack_pointer_rtx);
-             emit_move_insn (operands[2], plus_op);
-             emit_insn (gen_addsi3 (operands[0], operands[0], operands[2]));
-           }
-         else
-           abort ();
-       }
-      DONE;
-    }
-
-  /* FIXME: I don't know how to get a value into the HI register.  */
-  emit_move_insn (operands[0], operands[1]);
-  DONE;
-}")
-
-;; This insn is for the unspec delay for HILO.
-
-(define_insn "hilo_delay"
-  [(unspec [(match_operand 0 "register_operand" "=b")] UNSPEC_HILO_DELAY)]
-  ""
-  ""
-  [(set_attr "type" "nop")
-   (set_attr "mode" "none")
-   (set_attr "can_delay" "no")])
-
 ;; This insn handles moving CCmode values.  It's really just a
 ;; slightly simplified copy of movsi_internal2, with additional cases
 ;; to move a condition register to a general register and to move
This page took 0.146452 seconds and 5 git commands to generate.