Patch to rework MIPS handling of SIGN_EXTENDs

Richard Sandiford rsandifo@redhat.com
Wed May 22 13:07:00 GMT 2002


My first patch was inconsistent in its handling of unpredicated
match_operands.  recog() wouldn't pass the operand through
OPERAND_ADDRESS, but insn_extract() and match_dup would.
MIPS doesn't care, but other ports might, if they started
to use OPERAND_ADDRESS.

Here's a revised version, which applies OPERAND_ADDRESS to all
match_operands, match_dups and match_scratches.  Only the genrecog
stuff has changed.

With current genrecog, a predicated match_operand gives something like:

    if (general_operand (x1, SImode))
      {
	operands[2] = x1;
	goto L4000;
      }

The general_operand check is represented as a DT_pred node,
and the assignment and state change come from a DT_accept_op.
In the worst case, OPERAND_ADDRESS would be needed three times:

     if (general_operand (*OPERAND_ADDRESS (&x1),
			  GET_MODE (x1) == SImode
			  ? GET_MODE (*OPERAND_ADDRESS (&x1))
			  : SImode))
	{
	  operands[2] = *OPERAND_ADDRESS (&x1);
	  goto L4000;
	}

It'd be better to store *OPERAND_ADDRESS (&x1) somewhere first, and
the natural place seems to be operands[].  The DT_pred code would
then look like:

     if ((operands[2] = *OPERAND_ADDRESS (&x1),
	  general_operand (operands[2],
			   GET_MODE (x1) == SImode
			   ? GET_MODE (operands[2])
			   : SImode)))
	...

As far as I can tell, DT_accept_op exists only to assign to operands[].
I wondered at first whether the algorithm needs an unconditional op
after a DT_pred, but it doesn't seem to.  So the DT_accept_op would
no longer be needed here.

I can think of wwo ways of extending this behaviour to unpredicated
match_operands:

1. Keep the existing tree ops.  Make DT_pred handle OPERAND_ADDRESS
   for predicated operands, and DT_accept_op handle it for
   unpredicated ones.  [The original patch did the first bit,
   but not the second.]

2. Remove DT_accept_op and create a DT_pred for all match_operands.

The patch below plumps for (2).  For:

    (match_operator:SI 2 "comparison_operator" [(...)])

  the DT_pred condition would be something like:

    (operands[2] = x1, comparison_operator (x1, SImode))

For unpredicated match_operands, it would be:

    (operands[2] = *OPERAND_ADDRESS (&x1), 1)

For unpredicated match_operators, it's just:

    (operands[2] = x1, 1)

In theory, using DT_preds for unconditional ops could add dead code
to the recogniser, because you might get conditions like:

    if ((operands[2] = x1, 1))
      ...
    ...

But gcc should get rid of the fall-through code.  And on the plus side,
we use fewer labels than before, because we can chain more conditions
together.  Example from x86 (reformated):

  if ((operands[0] = *OPERAND_ADDRESS (&x2),
       memory_operand (operands[0],
                       (GET_MODE (x2) == HImode
			? GET_MODE (operands[0])
			: HImode)))
      && (TARGET_80387))
    {
      return 166;
    }

One oddity, though: why does the code for MATCH_OP_DUP create a
DT_accept_op node after a DT_dup one?

    case MATCH_OP_DUP:
      code = UNKNOWN;

      test = new_decision_test (DT_dup, &place);
      test->u.dup = XINT (pattern, 0);

      test = new_decision_test (DT_accept_op, &place);
      test->u.opno = XINT (pattern, 0);

      for (i = 0; i < (size_t) XVECLEN (pattern, 1); i++)
	{
	  subpos[depth] = i + '0';
	  sub = add_to_sequence (XVECEXP (pattern, 1, i),
				 &sub->success, subpos, insn_type, 0);
	}
      goto fini;

It means we generate code like:

  if (rtx_equal_p (x3, operands[3]))
    {
      operands[3] = x3;
      goto L1376;
    }

(taken from the ARM output).  Is the extra assignment needed for some
reason?  The patch just removes it.

FWIW, only the ARM and PowerPC ports seem to use match_op_dup when
recognising.  To check this part of the patch, I did a regression
test on arm-elf.  I also looked at the match_op_dup part of the new
insn-recog.c, and it seemed OK.

Summary of genrecog changes:

    - Remove DT_accept_op.

    - Merge the data for DT_pred and DT_dup.  Both need to know the
      operand number, and whether the node came from a 'leaf' matcher
      (match_operand, match_scratch or match_dup).  The DT_pred info
      is a superset of the DT_dup stuff.

    - Create a DT_pred for all match_operands.  For unpredicated ones,
      u.op.name is "" and u.op.index is -1.  They act just like a
      predicate that isn't mentioned in PREDICATE_CODES, except
      that no mode checking is done.

    - When comparing a leaf DT_pred with a non-leaf one, or with a
      DT_code, consider the leaf pred to match all the codes in
      OPERAND_ADDRESS_CODES [same as last patch].

    - Remove the handling of DT_accept_op from write_action() and
      is_unconditional().

    - Remove DT_accept_op checks in make_insn_sequence().  At the
      moment, it has to make sure that it doesn't add a new test
      after a DT_accept_op, since they must come last in a chain.

As before, patch tested on mips64-elf, including with -mlong64 multilibs.
Bootstrapped and regression tested on i686-pc-linux-gnu.  Also regression
tested on arm-elf.

Richard  


	* doc/tm.texi: Describe OPERAND_ADDRESS and OPERAND_ADDRESS_CODES.
	* doc/md.texi: Mention them in the match_operand description.
	* defaults.h (OPERAND_ADDRESS): Define.
	* genextract.c (struct extraction): Add 'leaf_p'.
	(leaf_p): New array.
	(gen_insn): Clear it, check it and copy it.
	(walk_rtx) [MATCH_OPERAND, MATCH_SCRATCH]: Set leaf_p.
	(main): Pass leaf operands through OPERAND_ADDRESS.
	* genpeep.c (match_rtx) [MATCH_OPERAND]: Likewise.
	* genrecog.c (operand_address_codes): New array.
	(enum decision_type): Remove DT_accept_op.
	(struct decision_test): Remove 'opno' and 'dup'.  Rename 'pred' to
	'op' and use it for DT_dup as well as DT_pred.  Add 'leaf_p' to 'op'.
	(add_to_sequence): Generate DT_preds even when there's no predicate.
	Don't generate DT_accept_ops.  Set the new decision_test fields.
	(predicate_can_match): New, mostly extracted from...
	(maybe_both_true_2): ...here.  Take into account the codes matched
	by OPERAND_ADDRESS when comparing decision_test nodes.  Don't assume
	that mode checking is done when there is no predicate.
	(maybe_both_true_1): Remove DT_accept_op handling.
	(nodes_identical_1): Likewise.  Combine DT_pred and DT_dup handling.
	Check the new decision_test fields.
	(write_switch): Change 'u.pred' to 'u.op'.
	(write_cond): Pass match_operand, match_scratch and match_dup
	operands through OPERAND_ADDRESS.  For DT_pred, set up operands[]
	before checking the predicate.
	(write_action): Remove DT_accept_op handling.  Remove 'depth' arg.
	(is_unconditional): Remoeve DT_accept_op handling.
	(write_node): Update call to write_action.
	(debug_decision_2): Print the new decision_test fields.
	* recog.c (extract_insn): Set operand_mode[] to the mode of the
	matched operand, unless it has VOIDmode, in which case use the
	match mode.  (Reverses previous order.)

	* config/mips/mips-protos.h (se_arith_operand): Remove.
	(reg_or_0_operand): Declare.
	* config/mips/mips.h (PREDICATE_CODES): Remove predicates below.
	(OPERAND_ADDRESS, OPERAND_ADDRESS_CODES): Define.
	* config/mips/mips.c (movdi_operand, se_register_operand): Remove.
	(se_reg_or_0_operand, se_uns_arith_operand, se_arith_operand): Remove.
	(se_nonmemory_operand, se_nonimmediate_operand): Remove.
	(mips_move_2words): Remove SIGN_EXTEND handling.
	(print_operand, mips_secondary_reload_class): Likewise.
	* config/mips/mips.md: Replace se_* predicates with non-se versions.
	Move movsidi3 & related patterns above movdi3.
	(*paradoxical_extendhidi2): Remove.
	(movdi_internal2): Use move_operand instead of movdi_operand.
	In the condition, use VOIDmode to match the source argument.

Index: doc/tm.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/tm.texi,v
retrieving revision 1.132
diff -c -d -p -r1.132 tm.texi
*** doc/tm.texi	19 May 2002 21:53:53 -0000	1.132
--- doc/tm.texi	22 May 2002 14:58:50 -0000
*************** through the macros defined in the @file{
*** 38,43 ****
--- 38,44 ----
  * Varargs::		Defining the varargs macros.
  * Trampolines::         Code set up at run time to enter a nested function.
  * Library Calls::       Controlling how library routines are implicitly called.
+ * Operands::            Changing the way operands are matched.
  * Addressing Modes::    Defining addressing modes valid for memory operands.
  * Condition Code::      Defining how insns update the condition code.
  * Costs::               Defining relative costs of different operations.
*************** at once to the method-lookup library fun
*** 4673,4678 ****
--- 4674,4761 ----
  
  The default calling convention passes just the object and the selector
  to the lookup function, which returns a pointer to the method.
+ @end table
+ 
+ @node Operands
+ @section Operands
+ @cindex operands
+ 
+ These macros change the way that instructions are matched to @file{.md}
+ file patterns.  Few back ends need to use them.
+ 
+ @table @code
+ @cindex @code{match_operand}, customizing
+ @cindex @code{match_scratch}, customizing
+ @cindex @code{match_dup}, customizing
+ @findex OPERAND_ADDRESS
+ @item OPERAND_ADDRESS (@var{opaddr})
+ Define this macro if you would like to filter operands before they are
+ matched by @code{match_operand}, @code{match_scratch} or
+ @code{match_dup}.  @var{opaddr} points to the unfiltered operand, and
+ the macro should return a pointer to the ``real'' operand.  It is this
+ operand that must satisfy a @code{match_operand}'s predicate, and that
+ will be reloaded if it doesn't meet the given constraints.
+ 
+ The filtered operand need not have the same mode as the original one.
+ If a @code{match_operand} or @code{match_scratch} specifies a mode,
+ @code{recog} will first check whether @samp{*@var{opaddr}} has
+ this mode.  If it does, the predicate will be passed the mode of
+ the filtered operand, otherwise it will be passed the match mode
+ as normal.
+ 
+ For example, consider a pattern such as:
+ 
+ @smallexample
+ (set (match_operand:DI 0 "register_operand" "r")
+      (plus:DI (match_operand:DI 1 "register_operand" "r")
+               (match_operand:DI 2 "register_operand" "r")))
+ @end smallexample
+ 
+ When matched against an insn:
+ 
+ @smallexample
+ (set @var{x0} (plus:DI @var{x1} @var{x2}))
+ @end smallexample
+ 
+ operand 0 will be at location @samp{OPERAND_ADDRESS (&@var{x0})},
+ operand 1 will be at location @samp{OPERAND_ADDRESS (&@var{x1})},
+ and so on.  For brevity, consider operand 0, and let @var{y0}
+ be @samp{*OPERAND_ADDRESS (&@var{x0})}.
+ 
+ The @samp{register_operand} predicate and @samp{r} constraint
+ apply to @var{y0} rather than @var{x0}.  If @var{x0} had @code{DImode},
+ the condition for operand 0 would be:
+ 
+ @smallexample
+ register_operand (@var{y0}, GET_MODE (@var{y0}))
+ @end smallexample
+ 
+ otherwise it would be:
+ 
+ @smallexample
+ register_operand (@var{y0}, DImode)
+ @end smallexample
+ 
+ It can be useful to define @code{OPERAND_ADDRESS} when certain rtx
+ operations come ``for free''.  For example, when a 64-bit MIPS
+ processor stores an @code{SImode} value in a register, it will
+ sign-extend the value to 64 bits.  So any instruction that takes a
+ @code{DImode} register operand can also take a sign-extension of an
+ @code{SImode} one.  When given an rtx of the form
+ @samp{(sign_extend:DI @var{x})}, where @var{x} is an @code{SImode}
+ register, the MIPS version of this macro returns a pointer to @var{x}.
+ 
+ The default definition of this macro just returns @var{opaddr}.  If
+ you define this macro, you should also define @code{OPERAND_ADDRESS_CODES}.
+ 
+ Note that this macro has no effect on other matching expressions,
+ such as @code{match_parallel} or @code{match_operator}.
+ 
+ @findex OPERAND_ADDRESS_CODES
+ @item OPERAND_ADDRESS_CODES
+ A comma-separated list of codes that @code{OPERAND_ADDRESS} can match.
+ For example, the MIPS back end defines it as @samp{SIGN_EXTEND}, since
+ @code{OPERAND_ADDRESS} matches certain forms of @samp{sign_extend} rtx.
  @end table
  
  @node Addressing Modes
Index: doc/md.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/md.texi,v
retrieving revision 1.40
diff -c -d -p -r1.40 md.texi
*** doc/md.texi	4 May 2002 00:31:28 -0000	1.40
--- doc/md.texi	22 May 2002 14:58:52 -0000
*************** substitution of the operands.
*** 244,252 ****
  This expression is a placeholder for operand number @var{n} of
  the insn.  When constructing an insn, operand number @var{n}
  will be substituted at this point.  When matching an insn, whatever
! appears at this position in the insn will be taken as operand
! number @var{n}; but it must satisfy @var{predicate} or this instruction
! pattern will not match at all.
  
  Operand numbers must be chosen consecutively counting from zero in
  each instruction pattern.  There may be only one @code{match_operand}
--- 244,253 ----
  This expression is a placeholder for operand number @var{n} of
  the insn.  When constructing an insn, operand number @var{n}
  will be substituted at this point.  When matching an insn, whatever
! appears at this position in the insn will be passed through
! @code{OPERAND_ADDRESS} (@pxref{Operands}) and the result taken
! as operand number @var{n}.  The operand must satisfy @var{predicate}
! or the instruction pattern will not match at all.
  
  Operand numbers must be chosen consecutively counting from zero in
  each instruction pattern.  There may be only one @code{match_operand}
Index: defaults.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/defaults.h,v
retrieving revision 1.75
diff -c -d -p -r1.75 defaults.h
*** defaults.h	17 May 2002 23:25:19 -0000	1.75
--- defaults.h	22 May 2002 14:58:52 -0000
*************** You Lose!  You must define PREFERRED_DEB
*** 495,500 ****
--- 495,504 ----
     && !ROUND_TOWARDS_ZERO)
  #endif
  
+ #ifndef OPERAND_ADDRESS
+ #define OPERAND_ADDRESS(OP) (OP)
+ #endif
+ 
  #ifndef HOT_TEXT_SECTION_NAME
  #define HOT_TEXT_SECTION_NAME "text.hot"
  #endif
Index: genextract.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genextract.c,v
retrieving revision 1.51
diff -c -d -p -r1.51 genextract.c
*** genextract.c	7 Mar 2002 22:03:27 -0000	1.51
--- genextract.c	22 May 2002 14:58:52 -0000
*************** struct extraction
*** 42,47 ****
--- 42,48 ----
  {
    int op_count;
    char *oplocs[MAX_RECOG_OPERANDS];
+   bool leaf_p[MAX_RECOG_OPERANDS];
    int dup_count;
    char *duplocs[MAX_DUP_OPERANDS];
    int dupnums[MAX_DUP_OPERANDS];
*************** static int op_count;
*** 76,81 ****
--- 77,86 ----
  
  static char *oplocs[MAX_RECOG_OPERANDS];
  
+ /* True for operands that are matched by MATCH_OPERAND or MATCH_SCRATCH.  */
+ 
+ bool leaf_p[MAX_RECOG_OPERANDS];
+ 
  /* Number the occurrences of MATCH_DUP in each instruction,
     starting at 0 for the first occurrence.  */
  
*************** gen_insn (insn)
*** 111,116 ****
--- 116,122 ----
  
    /* No operands seen so far in this pattern.  */
    memset (oplocs, 0, sizeof oplocs);
+   memset (leaf_p, 0, sizeof leaf_p);
  
    /* Walk the insn's pattern, remembering at all times the path
       down to the walking point.  */
*************** gen_insn (insn)
*** 139,144 ****
--- 145,157 ----
  	continue;
  
        for (i = 0; i < op_count; i++)
+ 	if (p->leaf_p[i] != leaf_p[i])
+ 	  break;
+ 
+       if (i != op_count)
+ 	continue;
+ 
+       for (i = 0; i < op_count; i++)
  	if (p->oplocs[i] != oplocs[i]
  	    && ! (p->oplocs[i] != 0 && oplocs[i] != 0
  		  && ! strcmp (p->oplocs[i], oplocs[i])))
*************** gen_insn (insn)
*** 172,178 ****
    link->next = 0;
  
    for (i = 0; i < op_count; i++)
!     p->oplocs[i] = oplocs[i];
  
    for (i = 0; i < dup_count; i++)
      p->dupnums[i] = dupnums[i], p->duplocs[i] = duplocs[i];
--- 185,194 ----
    link->next = 0;
  
    for (i = 0; i < op_count; i++)
!     {
!       p->oplocs[i] = oplocs[i];
!       p->leaf_p[i] = leaf_p[i];
!     }
  
    for (i = 0; i < dup_count; i++)
      p->dupnums[i] = dupnums[i], p->duplocs[i] = duplocs[i];
*************** walk_rtx (x, path)
*** 206,211 ****
--- 222,228 ----
      case MATCH_OPERAND:
      case MATCH_SCRATCH:
        oplocs[XINT (x, 0)] = xstrdup (path);
+       leaf_p[XINT (x, 0)] = 1;
        op_count = MAX (op_count, XINT (x, 0) + 1);
        break;
  
*************** from the machine description file `md'. 
*** 464,472 ****
  	    }
  	  else
  	    {
! 	      printf ("      ro[%d] = *(ro_loc[%d] = &", i, i);
  	      print_path (p->oplocs[i]);
! 	      printf (");\n");
  	    }
  	}
  
--- 481,490 ----
  	    }
  	  else
  	    {
! 	      printf ("      ro[%d] = *(ro_loc[%d] = %s(&", i, i,
! 		      (p->leaf_p[i] ? "OPERAND_ADDRESS " : ""));
  	      print_path (p->oplocs[i]);
! 	      printf ("));\n");
  	    }
  	}
  
Index: genpeep.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genpeep.c,v
retrieving revision 1.52
diff -c -d -p -r1.52 genpeep.c
*** genpeep.c	2 Dec 2001 00:04:19 -0000	1.52
--- genpeep.c	22 May 2002 14:58:52 -0000
*************** match_rtx (x, path, fail_label)
*** 170,176 ****
        print_path (path);
        printf (";\n");
  
!       printf ("  operands[%d] = x;\n", XINT (x, 0));
        if (XSTR (x, 1) && XSTR (x, 1)[0])
  	printf ("  if (! %s (x, %smode)) goto L%d;\n",
  		XSTR (x, 1), GET_MODE_NAME (GET_MODE (x)), fail_label);
--- 170,176 ----
        print_path (path);
        printf (";\n");
  
!       printf ("  operands[%d] = *OPERAND_ADDRESS (&x);\n", XINT (x, 0));
        if (XSTR (x, 1) && XSTR (x, 1)[0])
  	printf ("  if (! %s (x, %smode)) goto L%d;\n",
  		XSTR (x, 1), GET_MODE_NAME (GET_MODE (x)), fail_label);
Index: genrecog.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genrecog.c,v
retrieving revision 1.117
diff -c -d -p -r1.117 genrecog.c
*** genrecog.c	21 Mar 2002 07:14:18 -0000	1.117
--- genrecog.c	22 May 2002 14:58:53 -0000
***************
*** 60,65 ****
--- 60,71 ----
  #define OUTPUT_LABEL(INDENT_STRING, LABEL_NUMBER) \
    printf("%sL%d: ATTRIBUTE_UNUSED_LABEL\n", (INDENT_STRING), (LABEL_NUMBER))
  
+ #ifdef OPERAND_ADDRESS_CODES
+ static RTX_CODE operand_address_codes[] = { OPERAND_ADDRESS_CODES, 0 };
+ #else
+ static RTX_CODE operand_address_codes[] = { 0 };
+ #endif
+ 
  /* Holds an array of names indexed by insn_code_number.  */
  static char **insn_name_ptr = 0;
  static int insn_name_ptr_size = 0;
*************** struct decision_head
*** 74,82 ****
    struct decision *last;
  };
  
! /* A single test.  The two accept types aren't tests per-se, but
!    their equality (or lack thereof) does affect tree merging so
!    it is convenient to keep them here.  */
  
  struct decision_test
  {
--- 80,87 ----
    struct decision *last;
  };
  
! /* A single test.  DT_accept_insn isn't a test per-se, but it's
!    convenient to keep it here.  */
  
  struct decision_test
  {
*************** struct decision_test
*** 89,95 ****
        DT_mode, DT_code, DT_veclen,
        DT_elt_zero_int, DT_elt_one_int, DT_elt_zero_wide, DT_elt_zero_wide_safe,
        DT_veclen_ge, DT_dup, DT_pred, DT_c_test,
!       DT_accept_op, DT_accept_insn
      } type;
  
    union
--- 94,100 ----
        DT_mode, DT_code, DT_veclen,
        DT_elt_zero_int, DT_elt_one_int, DT_elt_zero_wide, DT_elt_zero_wide_safe,
        DT_veclen_ge, DT_dup, DT_pred, DT_c_test,
!       DT_accept_insn
      } type;
  
    union
*************** struct decision_test
*** 99,114 ****
  
      struct
      {
        const char *name;		/* Predicate to call.  */
        int index;		/* Index into `preds' or -1.  */
        enum machine_mode mode;	/* Machine mode for node.  */
!     } pred;
  
      const char *c_test;		/* Additional test to perform.  */
      int veclen;			/* Length of vector.  */
-     int dup;			/* Number of operand to compare against.  */
      HOST_WIDE_INT intval;	/* Value for XINT for XWINT.  */
-     int opno;			/* Operand number matched.  */
  
      struct {
        int code_number;		/* Insn number matched.  */
--- 104,119 ----
  
      struct
      {
+       int opno;			/* Operand number.  */
+       bool leaf_p;		/* True if MATCH_(OPERAND|SCRATCH|DUP).  */
        const char *name;		/* Predicate to call.  */
        int index;		/* Index into `preds' or -1.  */
        enum machine_mode mode;	/* Machine mode for node.  */
!     } op;
  
      const char *c_test;		/* Additional test to perform.  */
      int veclen;			/* Length of vector.  */
      HOST_WIDE_INT intval;	/* Value for XINT for XWINT.  */
  
      struct {
        int code_number;		/* Insn number matched.  */
*************** static void validate_pattern
*** 238,243 ****
--- 243,250 ----
  static struct decision *add_to_sequence
    PARAMS ((rtx, struct decision_head *, const char *, enum routine_type, int));
  
+ static bool predicate_can_match
+   PARAMS ((RTX_CODE, struct decision_test *, int));
  static int maybe_both_true_2
    PARAMS ((struct decision_test *, struct decision_test *));
  static int maybe_both_true_1
*************** static struct decision *write_switch
*** 274,280 ****
  static void write_cond
    PARAMS ((struct decision_test *, int, enum routine_type));
  static void write_action
!   PARAMS ((struct decision *, struct decision_test *, int, int,
  	   struct decision *, enum routine_type));
  static int is_unconditional
    PARAMS ((struct decision_test *, enum routine_type));
--- 281,287 ----
  static void write_cond
    PARAMS ((struct decision_test *, int, enum routine_type));
  static void write_action
!   PARAMS ((struct decision *, struct decision_test *, int,
  	   struct decision *, enum routine_type));
  static int is_unconditional
    PARAMS ((struct decision_test *, enum routine_type));
*************** add_to_sequence (pattern, last, position
*** 853,908 ****
  	      code = UNKNOWN;
  	  }
  
! 	if (pred_name[0] != 0)
! 	  {
! 	    test = new_decision_test (DT_pred, &place);
! 	    test->u.pred.name = pred_name;
! 	    test->u.pred.mode = mode;
  
! 	    /* See if we know about this predicate and save its number.
! 	       If we do, and it only accepts one code, note that fact.
  
! 	       If we know that the predicate does not allow CONST_INT,
! 	       we know that the only way the predicate can match is if
! 	       the modes match (here we use the kludge of relying on the
! 	       fact that "address_operand" accepts CONST_INT; otherwise,
! 	       it would have to be a special case), so we can test the
! 	       mode (but we need not).  This fact should considerably
! 	       simplify the generated code.  */
  
! 	    for (i = 0; i < NUM_KNOWN_PREDS; i++)
! 	      if (! strcmp (preds[i].name, pred_name))
! 		break;
  
! 	    if (i < NUM_KNOWN_PREDS)
! 	      {
! 		int j;
  
! 		test->u.pred.index = i;
  
! 		if (preds[i].codes[1] == 0 && code == UNKNOWN)
! 		  code = preds[i].codes[0];
  
! 		allows_const_int = 0;
! 		for (j = 0; preds[i].codes[j] != 0; j++)
! 		  if (preds[i].codes[j] == CONST_INT)
! 		    {
! 		      allows_const_int = 1;
! 		      break;
! 		    }
! 	      }
! 	    else
! 	      test->u.pred.index = -1;
  	  }
  
  	/* Can't enforce a mode if we allow const_int.  */
  	if (allows_const_int)
  	  mode = VOIDmode;
  
- 	/* Accept the operand, ie. record it in `operands'.  */
- 	test = new_decision_test (DT_accept_op, &place);
- 	test->u.opno = XINT (pattern, 0);
- 
  	if (was_code == MATCH_OPERATOR || was_code == MATCH_PARALLEL)
  	  {
  	    char base = (was_code == MATCH_OPERATOR ? '0' : 'a');
--- 860,911 ----
  	      code = UNKNOWN;
  	  }
  
! 	test = new_decision_test (DT_pred, &place);
! 	test->u.op.opno = XINT (pattern, 0);
! 	test->u.op.leaf_p = (was_code == MATCH_OPERAND
! 			     || was_code == MATCH_SCRATCH);
! 	test->u.op.name = pred_name;
! 	test->u.op.mode = mode;
  
! 	/* See if we know about this predicate and save its number.
! 	   If we do, and it only accepts one code, note that fact.
  
! 	   If we know that the predicate does not allow CONST_INT,
! 	   we know that the only way the predicate can match is if
! 	   the modes match (here we use the kludge of relying on the
! 	   fact that "address_operand" accepts CONST_INT; otherwise,
! 	   it would have to be a special case), so we can test the
! 	   mode (but we need not).  This fact should considerably
! 	   simplify the generated code.  */
  
! 	for (i = 0; i < NUM_KNOWN_PREDS; i++)
! 	  if (! strcmp (preds[i].name, pred_name))
! 	    break;
  
! 	if (i < NUM_KNOWN_PREDS)
! 	  {
! 	    int j;
  
! 	    test->u.op.index = i;
  
! 	    if (preds[i].codes[1] == 0 && code == UNKNOWN)
! 	      code = preds[i].codes[0];
  
! 	    allows_const_int = 0;
! 	    for (j = 0; preds[i].codes[j] != 0; j++)
! 	      if (preds[i].codes[j] == CONST_INT)
! 		{
! 		  allows_const_int = 1;
! 		  break;
! 		}
  	  }
+ 	else
+ 	  test->u.op.index = -1;
  
  	/* Can't enforce a mode if we allow const_int.  */
  	if (allows_const_int)
  	  mode = VOIDmode;
  
  	if (was_code == MATCH_OPERATOR || was_code == MATCH_PARALLEL)
  	  {
  	    char base = (was_code == MATCH_OPERATOR ? '0' : 'a');
*************** add_to_sequence (pattern, last, position
*** 920,929 ****
        code = UNKNOWN;
  
        test = new_decision_test (DT_dup, &place);
!       test->u.dup = XINT (pattern, 0);
! 
!       test = new_decision_test (DT_accept_op, &place);
!       test->u.opno = XINT (pattern, 0);
  
        for (i = 0; i < (size_t) XVECLEN (pattern, 1); i++)
  	{
--- 923,930 ----
        code = UNKNOWN;
  
        test = new_decision_test (DT_dup, &place);
!       test->u.op.opno = XINT (pattern, 0);
!       test->u.op.leaf_p = false;
  
        for (i = 0; i < (size_t) XVECLEN (pattern, 1); i++)
  	{
*************** add_to_sequence (pattern, last, position
*** 938,944 ****
        code = UNKNOWN;
  
        test = new_decision_test (DT_dup, &place);
!       test->u.dup = XINT (pattern, 0);
        goto fini;
  
      case ADDRESS:
--- 939,946 ----
        code = UNKNOWN;
  
        test = new_decision_test (DT_dup, &place);
!       test->u.op.opno = XINT (pattern, 0);
!       test->u.op.leaf_p = (GET_CODE (pattern) == MATCH_DUP);
        goto fini;
  
      case ADDRESS:
*************** add_to_sequence (pattern, last, position
*** 1054,1059 ****
--- 1056,1088 ----
    return sub;
  }
  
+ /* Return true if D (known to be a DT_pred) might match an rtx with
+    the given code.  Check against OPERAND_ADDRESS_CODES if D is a leaf
+    predicate and CHECK_LEAVES is true.  */
+ 
+ static bool
+ predicate_can_match (code, d, check_leaves)
+      RTX_CODE code;
+      struct decision_test *d;
+      int check_leaves;
+ {
+   const RTX_CODE *c;
+ 
+   if (d->u.op.index < 0)
+     return true;
+ 
+   for (c = &preds[d->u.op.index].codes[0]; *c; c++)
+     if (*c == code)
+       return true;
+ 
+   if (check_leaves && d->u.op.leaf_p)
+     for (c = operand_address_codes; *c; c++)
+       if (*c == code)
+ 	return true;
+ 
+   return false;
+ }
+ 
  /* A subroutine of maybe_both_true; examines only one test.
     Returns > 0 for "definitely both true" and < 0 for "maybe both true".  */
  
*************** maybe_both_true_2 (d1, d2)
*** 1085,1113 ****
  	}
      }
  
-   /* If either has a predicate that we know something about, set
-      things up so that D1 is the one that always has a known
-      predicate.  Then see if they have any codes in common.  */
- 
    if (d1->type == DT_pred || d2->type == DT_pred)
      {
!       if (d2->type == DT_pred)
  	{
  	  struct decision_test *tmp;
  	  tmp = d1, d1 = d2, d2 = tmp;
  	}
  
        /* If D2 tests a mode, see if it matches D1.  */
!       if (d1->u.pred.mode != VOIDmode)
  	{
  	  if (d2->type == DT_mode)
  	    {
! 	      if (d1->u.pred.mode != d2->u.mode
  		  /* The mode of an address_operand predicate is the
  		     mode of the memory, not the operand.  It can only
  		     be used for testing the predicate, so we must
  		     ignore it here.  */
! 		  && strcmp (d1->u.pred.name, "address_operand") != 0)
  		return 0;
  	    }
  	  /* Don't check two predicate modes here, because if both predicates
--- 1114,1143 ----
  	}
      }
  
    if (d1->type == DT_pred || d2->type == DT_pred)
      {
!       /* Set things up so that D1 is the predicate.  If both D1 and D2
! 	 are predicates, make sure that D1 is a leaf if D2 is.  */
!       if (d2->type == DT_pred
! 	  && !(d1->type == DT_pred && d1->u.op.leaf_p))
  	{
  	  struct decision_test *tmp;
  	  tmp = d1, d1 = d2, d2 = tmp;
  	}
  
        /* If D2 tests a mode, see if it matches D1.  */
!       if (d1->u.op.mode != VOIDmode)
  	{
  	  if (d2->type == DT_mode)
  	    {
! 	      if (d1->u.op.mode != d2->u.mode
! 		  /* Mode checking is not done when there is no predicate.  */
! 		  && d1->u.op.name[0] != 0
  		  /* The mode of an address_operand predicate is the
  		     mode of the memory, not the operand.  It can only
  		     be used for testing the predicate, so we must
  		     ignore it here.  */
! 		  && strcmp (d1->u.op.name, "address_operand") != 0)
  		return 0;
  	    }
  	  /* Don't check two predicate modes here, because if both predicates
*************** maybe_both_true_2 (d1, d2)
*** 1116,1158 ****
  	     separate DT_mode that will make maybe_both_true_1 return 0.  */
  	}
  
!       if (d1->u.pred.index >= 0)
  	{
  	  /* If D2 tests a code, see if it is in the list of valid
! 	     codes for D1's predicate.  */
! 	  if (d2->type == DT_code)
! 	    {
! 	      const RTX_CODE *c = &preds[d1->u.pred.index].codes[0];
! 	      while (*c != 0)
! 		{
! 		  if (*c == d2->u.code)
! 		    break;
! 		  ++c;
! 		}
! 	      if (*c == 0)
! 		return 0;
! 	    }
  
! 	  /* Otherwise see if the predicates have any codes in common.  */
! 	  else if (d2->type == DT_pred && d2->u.pred.index >= 0)
! 	    {
! 	      const RTX_CODE *c1 = &preds[d1->u.pred.index].codes[0];
! 	      int common = 0;
  
! 	      while (*c1 != 0 && !common)
! 		{
! 		  const RTX_CODE *c2 = &preds[d2->u.pred.index].codes[0];
! 		  while (*c2 != 0 && !common)
! 		    {
! 		      common = (*c1 == *c2);
! 		      ++c2;
! 		    }
! 		  ++c1;
! 		}
  
! 	      if (!common)
! 		return 0;
! 	    }
  	}
      }
  
--- 1146,1183 ----
  	     separate DT_mode that will make maybe_both_true_1 return 0.  */
  	}
  
!       /* Now see whether D1 and D2 can match the same code.  Take
! 	 into account the two-stage nature of leaf DT_preds: we
! 	 apply OPERAND_ADDRESS to the candidate rtx, then we test
! 	 the predicate.  */
!       if (d2->type == DT_code)
  	{
  	  /* If D2 tests a code, see if it is in the list of valid
! 	     codes for D1's predicate.  Include OPERAND_ADDRESS_CODES
! 	     if D1 is a leaf node.  */
! 	  if (!predicate_can_match (d2->u.code, d1, true))
! 	    return 0;
! 	}
!       else if (d2->type == DT_pred && d2->u.op.index >= 0)
! 	{
! 	  /* See whether D1 and D2 can match the same code.  When one is
! 	     a leaf and the other is not, we have to treat the leaf as
! 	     matching all the codes in OPERAND_ADDRESS_CODES.  We don't
! 	     in other cases, since OPERAND_ADDRESS will then be applied
! 	     before both predicates, or neither.
  
! 	     We've already made sure that D1 is a leaf if D2 is.  Go
! 	     through D2's codes, and match them against D1's.  Also
! 	     match D2's codes against OPERAND_ADDRESS_CODES if D1 is a
! 	     leaf and D2 is not.  */
! 	  const RTX_CODE *c;
  
! 	  for (c = &preds[d2->u.op.index].codes[0]; *c != 0; c++)
! 	    if (predicate_can_match (*c, d1, !d2->u.op.leaf_p))
! 	      break;
  
! 	  if (*c == 0)
! 	    return 0;
  	}
      }
  
*************** maybe_both_true_1 (d1, d2)
*** 1174,1184 ****
  {
    struct decision_test *t1, *t2;
  
-   /* A match_operand with no predicate can match anything.  Recognize
-      this by the existence of a lone DT_accept_op test.  */
-   if (d1->type == DT_accept_op || d2->type == DT_accept_op)
-     return 1;
- 
    /* Eliminate pairs of tests while they can exactly match.  */
    while (d1 && d2 && d1->type == d2->type)
      {
--- 1199,1204 ----
*************** nodes_identical_1 (d1, d2)
*** 1284,1293 ****
      case DT_code:
        return d1->u.code == d2->u.code;
  
-     case DT_pred:
-       return (d1->u.pred.mode == d2->u.pred.mode
- 	      && strcmp (d1->u.pred.name, d2->u.pred.name) == 0);
- 
      case DT_c_test:
        return strcmp (d1->u.c_test, d2->u.c_test) == 0;
  
--- 1304,1309 ----
*************** nodes_identical_1 (d1, d2)
*** 1296,1302 ****
        return d1->u.veclen == d2->u.veclen;
  
      case DT_dup:
!       return d1->u.dup == d2->u.dup;
  
      case DT_elt_zero_int:
      case DT_elt_one_int:
--- 1312,1323 ----
        return d1->u.veclen == d2->u.veclen;
  
      case DT_dup:
!     case DT_pred:
!       return (d1->u.op.opno == d2->u.op.opno
! 	      && d1->u.op.leaf_p == d2->u.op.leaf_p
! 	      && (d1->type == DT_dup
! 		  || (d1->u.op.mode == d2->u.op.mode
! 		      && strcmp (d1->u.op.name, d2->u.op.name) == 0)));
  
      case DT_elt_zero_int:
      case DT_elt_one_int:
*************** nodes_identical_1 (d1, d2)
*** 1304,1312 ****
      case DT_elt_zero_wide_safe:
        return d1->u.intval == d2->u.intval;
  
-     case DT_accept_op:
-       return d1->u.opno == d2->u.opno;
- 
      case DT_accept_insn:
        /* Differences will be handled in merge_accept_insn.  */
        return 1;
--- 1325,1330 ----
*************** write_switch (start, depth)
*** 1837,1851 ****
  	ret = p;
  
        while (p && p->tests->type == DT_pred
! 	     && p->tests->u.pred.index >= 0)
  	{
  	  const RTX_CODE *c;
  
! 	  for (c = &preds[p->tests->u.pred.index].codes[0]; *c ; ++c)
  	    if (codemap[(int) *c] != 0)
  	      goto pred_done;
  
! 	  for (c = &preds[p->tests->u.pred.index].codes[0]; *c ; ++c)
  	    {
  	      printf ("    case ");
  	      print_code (*c);
--- 1855,1869 ----
  	ret = p;
  
        while (p && p->tests->type == DT_pred
! 	     && p->tests->u.op.index >= 0)
  	{
  	  const RTX_CODE *c;
  
! 	  for (c = &preds[p->tests->u.op.index].codes[0]; *c; ++c)
  	    if (codemap[(int) *c] != 0)
  	      goto pred_done;
  
! 	  for (c = &preds[p->tests->u.op.index].codes[0]; *c; ++c)
  	    {
  	      printf ("    case ");
  	      print_code (*c);
*************** write_cond (p, depth, subroutine_type)
*** 2011,2022 ****
        break;
  
      case DT_dup:
!       printf ("rtx_equal_p (x%d, operands[%d])", depth, p->u.dup);
        break;
  
      case DT_pred:
!       printf ("%s (x%d, %smode)", p->u.pred.name, depth,
! 	      GET_MODE_NAME (p->u.pred.mode));
        break;
  
      case DT_c_test:
--- 2029,2073 ----
        break;
  
      case DT_dup:
!       /* Operands matched by MATCH_OPERAND and MATCH_SCRATCH have been passed
! 	 through OPERAND_ADDRESS.  For MATCH_DUPs, we need to pass the
! 	 candidate rtx through the same function.  */
!       printf ("rtx_equal_p (");
!       printf (p->u.op.leaf_p ? "*OPERAND_ADDRESS (&x%d)" : "x%d", depth);
!       printf (", operands[%d])", p->u.op.opno);
        break;
  
      case DT_pred:
!       /* First set up operands[].  Pass the candidate operand through
! 	 OPERAND_ADDRESS if the original rtx was MATCH_OPERAND or
! 	 MATCH_SCRATCH.  */
!       printf ("(operands[%d] = ", p->u.op.opno);
!       printf (p->u.op.leaf_p ? "*OPERAND_ADDRESS (&x%d)" : "x%d", depth);
!       if (p->u.op.name[0] != 0)
! 	{
! 	  const char *mode_prefix;
! 
! 	  /* Now call the predicate.  */
! 	  printf (", %s (operands[%d], ", p->u.op.name, p->u.op.opno);
! 	  mode_prefix = GET_MODE_NAME (p->u.op.mode);
! 	  if (p->u.op.leaf_p && p->u.op.mode != VOIDmode)
! 	    {
! 	      /* OPERAND_ADDRESS may return an operand with a different mode.
! 		 If the original operand had the required mode, we should
! 		 pass the new operand's mode to the predicate.  */
! 	      printf ("(GET_MODE (x%d) == %smode", depth, mode_prefix);
! 	      printf (" ? GET_MODE (operands[%d])", p->u.op.opno);
! 	      printf (" : %smode)", mode_prefix);
! 	    }
! 	  else
! 	    printf ("%smode", mode_prefix);
! 	  printf ("))");
! 	}
!       else
! 	{
! 	  /* There's no predicate, so we always accept.  */
! 	  printf (", 1)");
! 	}
        break;
  
      case DT_c_test:
*************** write_cond (p, depth, subroutine_type)
*** 2047,2056 ****
     perform a state change.  For the `accept' tests we must do more work.  */
  
  static void
! write_action (p, test, depth, uncond, success, subroutine_type)
       struct decision *p;
       struct decision_test *test;
!      int depth, uncond;
       struct decision *success;
       enum routine_type subroutine_type;
  {
--- 2098,2107 ----
     perform a state change.  For the `accept' tests we must do more work.  */
  
  static void
! write_action (p, test, uncond, success, subroutine_type)
       struct decision *p;
       struct decision_test *test;
!      int uncond;
       struct decision *success;
       enum routine_type subroutine_type;
  {
*************** write_action (p, test, depth, uncond, su
*** 2059,2065 ****
  
    if (uncond)
      indent = "  ";
!   else if (test->type == DT_accept_op || test->type == DT_accept_insn)
      {
        fputs ("    {\n", stdout);
        indent = "      ";
--- 2110,2116 ----
  
    if (uncond)
      indent = "  ";
!   else if (test->type == DT_accept_insn)
      {
        fputs ("    {\n", stdout);
        indent = "      ";
*************** write_action (p, test, depth, uncond, su
*** 2068,2086 ****
    else
      indent = "    ";
  
-   if (test->type == DT_accept_op)
-     {
-       printf("%soperands[%d] = x%d;\n", indent, test->u.opno, depth);
- 
-       /* Only allow DT_accept_insn to follow.  */
-       if (test->next)
- 	{
- 	  test = test->next;
- 	  if (test->type != DT_accept_insn)
- 	    abort ();
- 	}
-     }
- 
    /* Sanity check that we're now at the end of the list of tests.  */
    if (test->next)
      abort ();
--- 2119,2124 ----
*************** is_unconditional (t, subroutine_type)
*** 2142,2150 ****
       struct decision_test *t;
       enum routine_type subroutine_type;
  {
-   if (t->type == DT_accept_op)
-     return 1;
- 
    if (t->type == DT_accept_insn)
      {
        switch (subroutine_type)
--- 2180,2185 ----
*************** write_node (p, depth, subroutine_type)
*** 2198,2204 ****
        printf (")\n");
      }
  
!   write_action (p, last_test, depth, uncond, p->success.first, subroutine_type);
  
    return uncond > 0;
  }
--- 2233,2239 ----
        printf (")\n");
      }
  
!   write_action (p, last_test, uncond, p->success.first, subroutine_type);
  
    return uncond > 0;
  }
*************** make_insn_sequence (insn, type)
*** 2507,2517 ****
    if (c_test[0])
      {
        /* Need a new node if we have another test to add.  */
-       if (test->type == DT_accept_op)
- 	{
- 	  last = new_decision (c_test_pos, &last->success);
- 	  place = &last->tests;
- 	}
        test = new_decision_test (DT_c_test, &place);
        test->u.c_test = c_test;
      }
--- 2542,2547 ----
*************** make_insn_sequence (insn, type)
*** 2571,2581 ****
  	      /* We definitely have a new test to add -- create a new
  		 node if needed.  */
  	      place = &test->next;
- 	      if (test->type == DT_accept_op)
- 		{
- 		  last = new_decision ("", &last->success);
- 		  place = &last->tests;
- 		}
  
  	      if (c_test[0])
  		{
--- 2601,2606 ----
*************** debug_decision_2 (test)
*** 2783,2793 ****
        fprintf (stderr, "veclen>=%d", test->u.veclen);
        break;
      case DT_dup:
!       fprintf (stderr, "dup=%d", test->u.dup);
        break;
      case DT_pred:
!       fprintf (stderr, "pred=(%s,%s)",
! 	       test->u.pred.name, GET_MODE_NAME(test->u.pred.mode));
        break;
      case DT_c_test:
        {
--- 2808,2819 ----
        fprintf (stderr, "veclen>=%d", test->u.veclen);
        break;
      case DT_dup:
!       fprintf (stderr, "dup=(%d,%d)", test->u.op.opno, test->u.op.leaf_p);
        break;
      case DT_pred:
!       fprintf (stderr, "pred=(%d,%d,%s,%s)",
! 	       test->u.op.opno, test->u.op.leaf_p,
! 	       test->u.op.name, GET_MODE_NAME (test->u.op.mode));
        break;
      case DT_c_test:
        {
*************** debug_decision_2 (test)
*** 2796,2804 ****
  	memcpy (sub+16, "...", 4);
  	fprintf (stderr, "c_test=\"%s\"", sub);
        }
-       break;
-     case DT_accept_op:
-       fprintf (stderr, "A_op=%d", test->u.opno);
        break;
      case DT_accept_insn:
        fprintf (stderr, "A_insn=(%d,%d)",
--- 2822,2827 ----
Index: recog.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/recog.c,v
retrieving revision 1.154
diff -c -d -p -r1.154 recog.c
*** recog.c	17 May 2002 02:31:48 -0000	1.154
--- recog.c	22 May 2002 14:58:54 -0000
*************** extract_insn (insn)
*** 2141,2150 ****
        for (i = 0; i < noperands; i++)
  	{
  	  recog_data.constraints[i] = insn_data[icode].operand[i].constraint;
! 	  recog_data.operand_mode[i] = insn_data[icode].operand[i].mode;
! 	  /* VOIDmode match_operands gets mode from their real operand.  */
  	  if (recog_data.operand_mode[i] == VOIDmode)
! 	    recog_data.operand_mode[i] = GET_MODE (recog_data.operand[i]);
  	}
      }
    for (i = 0; i < noperands; i++)
--- 2141,2149 ----
        for (i = 0; i < noperands; i++)
  	{
  	  recog_data.constraints[i] = insn_data[icode].operand[i].constraint;
! 	  recog_data.operand_mode[i] = GET_MODE (recog_data.operand[i]);
  	  if (recog_data.operand_mode[i] == VOIDmode)
! 	    recog_data.operand_mode[i] = insn_data[icode].operand[i].mode;
  	}
      }
    for (i = 0; i < noperands; i++)
Index: config/mips/mips-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mips/mips-protos.h,v
retrieving revision 1.22
diff -c -d -p -r1.22 mips-protos.h
*** config/mips/mips-protos.h	18 May 2002 23:47:15 -0000	1.22
--- config/mips/mips-protos.h	22 May 2002 14:58:54 -0000
*************** extern int              mips_register_mo
*** 122,128 ****
  							 enum reg_class));
  
  extern int		pic_address_needs_scratch PARAMS ((rtx));
- extern int		se_arith_operand PARAMS ((rtx, enum machine_mode));
  extern int              mips_legitimate_address_p PARAMS ((enum machine_mode,
  							   rtx, int));
  extern int              mips_reg_mode_ok_for_base_p PARAMS ((rtx,
--- 122,127 ----
*************** extern int		m16_simm8_8 PARAMS ((rtx, en
*** 146,151 ****
--- 145,151 ----
  extern int		m16_nsimm8_8 PARAMS ((rtx, enum machine_mode));
  extern int		m16_usym8_4 PARAMS ((rtx, enum machine_mode));
  extern int		m16_usym5_4 PARAMS ((rtx, enum machine_mode));
+ extern int		reg_or_0_operand PARAMS ((rtx, enum machine_mode));
  
  #ifdef RTX_CODE
  extern rtx		gen_int_relational PARAMS ((enum rtx_code, rtx, rtx,
Index: config/mips/mips.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.h,v
retrieving revision 1.184
diff -c -d -p -r1.184 mips.h
*** config/mips/mips.h	19 May 2002 05:23:16 -0000	1.184
--- config/mips/mips.h	22 May 2002 14:58:55 -0000
*************** typedef struct mips_args {
*** 3794,3813 ****
    {"move_operand", 		{ CONST_INT, CONST_DOUBLE, CONST,	\
  				  SYMBOL_REF, LABEL_REF, SUBREG,	\
  				  REG, MEM}},				\
-   {"movdi_operand",		{ CONST_INT, CONST_DOUBLE, CONST,	\
- 				  SYMBOL_REF, LABEL_REF, SUBREG, REG,	\
- 				  MEM, SIGN_EXTEND }},			\
-   {"se_register_operand",	{ SUBREG, REG, SIGN_EXTEND }},		\
-   {"se_reg_or_0_operand",	{ REG, CONST_INT, CONST_DOUBLE, SUBREG,	\
- 				  SIGN_EXTEND }},			\
-   {"se_uns_arith_operand",	{ REG, CONST_INT, SUBREG,		\
- 				  SIGN_EXTEND }},			\
-   {"se_arith_operand",		{ REG, CONST_INT, SUBREG,		\
- 				  SIGN_EXTEND }},			\
-   {"se_nonmemory_operand",	{ CONST_INT, CONST_DOUBLE, CONST,	\
- 				  SYMBOL_REF, LABEL_REF, SUBREG,	\
- 				  REG, SIGN_EXTEND }},			\
-   {"se_nonimmediate_operand",   { SUBREG, REG, MEM, SIGN_EXTEND }},	\
    {"consttable_operand",	{ LABEL_REF, SYMBOL_REF, CONST_INT,	\
  				  CONST_DOUBLE, CONST }},		\
    {"extend_operator",           { SIGN_EXTEND, ZERO_EXTEND }},          \
--- 3794,3799 ----
*************** do									\
*** 4690,4692 ****
--- 4676,4694 ----
        }									\
    }									\
  while (0)
+ 
+ /* On 64-bit targets, the result of a 32-bit register operation is
+    sign-extended to 64 bits.  Any pattern that accepts a DImode
+    reg_or_0_operand can also accept a sign-extended SImode one.  */
+ 
+ #define OPERAND_ADDRESS(OP)				\
+   (TARGET_64BIT						\
+    && GET_CODE (*(OP)) == SIGN_EXTEND			\
+    && GET_MODE (*(OP)) == DImode			\
+    && reg_or_0_operand (XEXP (*(OP), 0), SImode)	\
+    ? &XEXP (*(OP), 0)					\
+    : (OP))
+ 
+ /* The list of codes that OPERAND_ADDRESS can match.  */
+ 
+ #define OPERAND_ADDRESS_CODES SIGN_EXTEND
Index: config/mips/mips.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.c,v
retrieving revision 1.202
diff -c -d -p -r1.202 mips.c
*** config/mips/mips.c	19 May 2002 07:55:37 -0000	1.202
--- config/mips/mips.c	22 May 2002 14:58:59 -0000
*************** move_operand (op, mode)
*** 1189,1342 ****
  		&& ! mips16_constant (op, mode, 1, 0)));
  }
  
- /* Return nonzero if OPERAND is valid as a source operand for movdi.
-    This accepts not only general_operand, but also sign extended
-    constants and registers.  We need to accept sign extended constants
-    in case a sign extended register which is used in an expression,
-    and is equivalent to a constant, is spilled.  */
- 
- int
- movdi_operand (op, mode)
-      rtx op;
-      enum machine_mode mode;
- {
-   if (TARGET_64BIT
-       && mode == DImode
-       && GET_CODE (op) == SIGN_EXTEND
-       && GET_MODE (op) == DImode
-       && (GET_MODE (XEXP (op, 0)) == SImode
- 	  || (GET_CODE (XEXP (op, 0)) == CONST_INT
- 	      && GET_MODE (XEXP (op, 0)) == VOIDmode))
-       && (register_operand (XEXP (op, 0), SImode)
- 	  || immediate_operand (XEXP (op, 0), SImode)))
-     return 1;
- 
-   return (general_operand (op, mode)
- 	  && ! (TARGET_MIPS16
- 		&& GET_CODE (op) == SYMBOL_REF
- 		&& ! mips16_constant (op, mode, 1, 0)));
- }
- 
- /* Like register_operand, but when in 64 bit mode also accept a sign
-    extend of a 32 bit register, since the value is known to be already
-    sign extended.  */
- 
- int
- se_register_operand (op, mode)
-      rtx op;
-      enum machine_mode mode;
- {
-   if (TARGET_64BIT
-       && mode == DImode
-       && GET_CODE (op) == SIGN_EXTEND
-       && GET_MODE (op) == DImode
-       && GET_MODE (XEXP (op, 0)) == SImode
-       && register_operand (XEXP (op, 0), SImode))
-     return 1;
- 
-   return register_operand (op, mode);
- }
- 
- /* Like reg_or_0_operand, but when in 64 bit mode also accept a sign
-    extend of a 32 bit register, since the value is known to be already
-    sign extended.  */
- 
- int
- se_reg_or_0_operand (op, mode)
-      rtx op;
-      enum machine_mode mode;
- {
-   if (TARGET_64BIT
-       && mode == DImode
-       && GET_CODE (op) == SIGN_EXTEND
-       && GET_MODE (op) == DImode
-       && GET_MODE (XEXP (op, 0)) == SImode
-       && register_operand (XEXP (op, 0), SImode))
-     return 1;
- 
-   return reg_or_0_operand (op, mode);
- }
- 
- /* Like uns_arith_operand, but when in 64 bit mode also accept a sign
-    extend of a 32 bit register, since the value is known to be already
-    sign extended.  */
- 
- int
- se_uns_arith_operand (op, mode)
-      rtx op;
-      enum machine_mode mode;
- {
-   if (TARGET_64BIT
-       && mode == DImode
-       && GET_CODE (op) == SIGN_EXTEND
-       && GET_MODE (op) == DImode
-       && GET_MODE (XEXP (op, 0)) == SImode
-       && register_operand (XEXP (op, 0), SImode))
-     return 1;
- 
-   return uns_arith_operand (op, mode);
- }
- 
- /* Like arith_operand, but when in 64 bit mode also accept a sign
-    extend of a 32 bit register, since the value is known to be already
-    sign extended.  */
- 
- int
- se_arith_operand (op, mode)
-      rtx op;
-      enum machine_mode mode;
- {
-   if (TARGET_64BIT
-       && mode == DImode
-       && GET_CODE (op) == SIGN_EXTEND
-       && GET_MODE (op) == DImode
-       && GET_MODE (XEXP (op, 0)) == SImode
-       && register_operand (XEXP (op, 0), SImode))
-     return 1;
- 
-   return arith_operand (op, mode);
- }
- 
- /* Like nonmemory_operand, but when in 64 bit mode also accept a sign
-    extend of a 32 bit register, since the value is known to be already
-    sign extended.  */
- 
- int
- se_nonmemory_operand (op, mode)
-      rtx op;
-      enum machine_mode mode;
- {
-   if (TARGET_64BIT
-       && mode == DImode
-       && GET_CODE (op) == SIGN_EXTEND
-       && GET_MODE (op) == DImode
-       && GET_MODE (XEXP (op, 0)) == SImode
-       && register_operand (XEXP (op, 0), SImode))
-     return 1;
- 
-   return nonmemory_operand (op, mode);
- }
- 
- /* Like nonimmediate_operand, but when in 64 bit mode also accept a
-    sign extend of a 32 bit register, since the value is known to be
-    already sign extended.  */
- 
- int
- se_nonimmediate_operand (op, mode)
-      rtx op;
-      enum machine_mode mode;
- {
-   if (TARGET_64BIT
-       && mode == DImode
-       && GET_CODE (op) == SIGN_EXTEND
-       && GET_MODE (op) == DImode
-       && GET_MODE (XEXP (op, 0)) == SImode
-       && register_operand (XEXP (op, 0), SImode))
-     return 1;
- 
-   return nonimmediate_operand (op, mode);
- }
- 
  /* Accept any operand that can appear in a mips16 constant table
     instruction.  We can't use any of the standard operand functions
     because for these instructions we accept values that are not
--- 1189,1194 ----
*************** mips_move_2words (operands, insn)
*** 2474,2485 ****
        code0 = GET_CODE (op0);
      }
  
-   if (code1 == SIGN_EXTEND)
-     {
-       op1 = XEXP (op1, 0);
-       code1 = GET_CODE (op1);
-     }
- 
    while (code1 == SUBREG)
      {
        subreg_offset1 += subreg_regno_offset (REGNO (SUBREG_REG (op1)),
--- 2326,2331 ----
*************** mips_move_2words (operands, insn)
*** 2490,2506 ****
        code1 = GET_CODE (op1);
      }
  
-   /* Sanity check.  */
-   if (GET_CODE (operands[1]) == SIGN_EXTEND
-       && code1 != REG
-       && code1 != CONST_INT
-       /* The following three can happen as the result of a questionable
- 	 cast.  */
-       && code1 != LABEL_REF
-       && code1 != SYMBOL_REF
-       && code1 != CONST)
-     abort ();
- 
    if (code0 == REG)
      {
        int regno0 = REGNO (op0) + subreg_offset0;
--- 2336,2341 ----
*************** mips_move_2words (operands, insn)
*** 2724,2731 ****
  		  else if (INTVAL (op1) < 0 && INTVAL (op1) >= -0xffff)
  		    ret = "li\t%0,%n1\n\tneg\t%0";
  		}
- 	      else if (GET_CODE (operands[1]) == SIGN_EXTEND)
- 		ret = "li\t%0,%1\t\t# %X1";
  	      else if (HOST_BITS_PER_WIDE_INT < 64)
  		/* We can't use 'X' for negative numbers, because then we won't
  		   get the right value for the upper 32 bits.  */
--- 2559,2564 ----
*************** mips_move_2words (operands, insn)
*** 2833,2846 ****
  	  if (TARGET_STATS)
  	    mips_count_memory_refs (op1, 2);
  
! 	  if (GET_CODE (operands[1]) == SIGN_EXTEND)
! 	    /* We deliberately remove the 'a' from '%1', so that we don't
! 	       have to add SIGN_EXTEND support to print_operand_address.
! 	       print_operand will just call print_operand_address in this
! 	       case, so there is no problem.  */
! 	    ret = "la\t%0,%1";
! 	  else
! 	    ret = "dla\t%0,%a1";
  	}
        else if (code1 == SYMBOL_REF || code1 == CONST)
  	{
--- 2666,2672 ----
  	  if (TARGET_STATS)
  	    mips_count_memory_refs (op1, 2);
  
! 	  ret = "dla\t%0,%a1";
  	}
        else if (code1 == SYMBOL_REF || code1 == CONST)
  	{
*************** mips_move_2words (operands, insn)
*** 2870,2883 ****
  	      if (TARGET_STATS)
  		mips_count_memory_refs (op1, 2);
  
! 	      if (GET_CODE (operands[1]) == SIGN_EXTEND)
! 		/* We deliberately remove the 'a' from '%1', so that we don't
! 		   have to add SIGN_EXTEND support to print_operand_address.
! 		   print_operand will just call print_operand_address in this
! 		   case, so there is no problem.  */
! 		ret = "la\t%0,%1";
! 	      else
! 		ret = "dla\t%0,%a1";
  	    }
  	}
      }
--- 2696,2702 ----
  	      if (TARGET_STATS)
  		mips_count_memory_refs (op1, 2);
  
! 	      ret = "dla\t%0,%a1";
  	    }
  	}
      }
*************** print_operand (file, op, letter)
*** 5742,5750 ****
  
    code = GET_CODE (op);
  
-   if (code == SIGN_EXTEND)
-     op = XEXP (op, 0), code = GET_CODE (op);
- 
    if (letter == 'C')
      switch (code)
        {
--- 5561,5566 ----
*************** mips_secondary_reload_class (class, mode
*** 8292,8324 ****
    int regno = -1;
    int gp_reg_p;
  
!   if (GET_CODE (x) == SIGN_EXTEND)
!     {
!       int off = 0;
! 
!       x = XEXP (x, 0);
! 
!       /* We may be called with reg_renumber NULL from regclass.
! 	 ??? This is probably a bug.  */
!       if (reg_renumber)
! 	regno = true_regnum (x);
!       else
! 	{
! 	  while (GET_CODE (x) == SUBREG)
! 	    {
! 	      off += subreg_regno_offset (REGNO (SUBREG_REG (x)),
! 					  GET_MODE (SUBREG_REG (x)),
! 					  SUBREG_BYTE (x),
! 					  GET_MODE (x));
! 	      x = SUBREG_REG (x);
! 	    }
! 
! 	  if (GET_CODE (x) == REG)
! 	    regno = REGNO (x) + off;
! 	}
!     }
! 
!   else if (GET_CODE (x) == REG || GET_CODE (x) == SUBREG)
      regno = true_regnum (x);
  
    gp_reg_p = TARGET_MIPS16 ? M16_REG_P (regno) : GP_REG_P (regno);
--- 8108,8114 ----
    int regno = -1;
    int gp_reg_p;
  
!   if (GET_CODE (x) == REG || GET_CODE (x) == SUBREG)
      regno = true_regnum (x);
  
    gp_reg_p = TARGET_MIPS16 ? M16_REG_P (regno) : GP_REG_P (regno);
Index: config/mips/mips.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.md,v
retrieving revision 1.128
diff -c -d -p -r1.128 mips.md
*** config/mips/mips.md	13 May 2002 04:50:14 -0000	1.128
--- config/mips/mips.md	22 May 2002 14:59:05 -0000
***************
*** 786,793 ****
  
  (define_expand "adddi3"
    [(parallel [(set (match_operand:DI 0 "register_operand" "")
! 		   (plus:DI (match_operand:DI 1 "se_register_operand" "")
! 			    (match_operand:DI 2 "se_arith_operand" "")))
  	      (clobber (match_dup 3))])]
    "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
    "
--- 786,793 ----
  
  (define_expand "adddi3"
    [(parallel [(set (match_operand:DI 0 "register_operand" "")
! 		   (plus:DI (match_operand:DI 1 "register_operand" "")
! 			    (match_operand:DI 2 "arith_operand" "")))
  	      (clobber (match_dup 3))])]
    "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
    "
***************
*** 976,983 ****
  
  (define_insn "adddi3_internal_3"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(plus:DI (match_operand:DI 1 "se_reg_or_0_operand" "dJ")
! 		 (match_operand:DI 2 "se_arith_operand" "dI")))]
    "TARGET_64BIT
     && !TARGET_MIPS16
     && (TARGET_GAS
--- 976,983 ----
  
  (define_insn "adddi3_internal_3"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(plus:DI (match_operand:DI 1 "reg_or_0_operand" "dJ")
! 		 (match_operand:DI 2 "arith_operand" "dI")))]
    "TARGET_64BIT
     && !TARGET_MIPS16
     && (TARGET_GAS
***************
*** 1341,1348 ****
  
  (define_expand "subdi3"
    [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
! 		   (minus:DI (match_operand:DI 1 "se_register_operand" "d")
! 			     (match_operand:DI 2 "se_register_operand" "d")))
  	      (clobber (match_dup 3))])]
    "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
    "
--- 1341,1348 ----
  
  (define_expand "subdi3"
    [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
! 		   (minus:DI (match_operand:DI 1 "register_operand" "d")
! 			     (match_operand:DI 2 "register_operand" "d")))
  	      (clobber (match_dup 3))])]
    "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
    "
***************
*** 1489,1496 ****
  
  (define_insn "subdi3_internal_3"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(minus:DI (match_operand:DI 1 "se_reg_or_0_operand" "dJ")
! 		  (match_operand:DI 2 "se_arith_operand" "dI")))]
    "TARGET_64BIT && !TARGET_MIPS16
     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
    "*
--- 1489,1496 ----
  
  (define_insn "subdi3_internal_3"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(minus:DI (match_operand:DI 1 "reg_or_0_operand" "dJ")
! 		  (match_operand:DI 2 "arith_operand" "dI")))]
    "TARGET_64BIT && !TARGET_MIPS16
     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
    "*
***************
*** 2001,2069 ****
     (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 7)))]
    "")
  
! (define_expand "muldi3"
!   [(set (match_operand:DI 0 "register_operand" "=l")
! 	(mult:DI (match_operand:DI 1 "se_register_operand" "d")
! 		 (match_operand:DI 2 "register_operand" "d")))
!    (clobber (match_scratch:DI 3 "=h"))
!    (clobber (match_scratch:DI 4 "=a"))]
!   "TARGET_64BIT"
! 
!   "
! {
!   if (GENERATE_MULT3_DI || TARGET_MIPS4000 || TARGET_MIPS16)
!     emit_insn (gen_muldi3_internal2 (operands[0], operands[1], operands[2]));
!   else
!     emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2]));
!   DONE;
! }")
! 
! ;; Don't accept both operands using se_register_operand, because if
! ;; both operands are sign extended we would prefer to use mult in the
! ;; mulsidi3 pattern.  Commutativity should permit either operand to be
! ;; sign extended.
! 
! (define_insn "muldi3_internal"
!   [(set (match_operand:DI 0 "register_operand" "=l")
! 	(mult:DI (match_operand:DI 1 "se_register_operand" "d")
! 		 (match_operand:DI 2 "register_operand" "d")))
!    (clobber (match_scratch:DI 3 "=h"))
!    (clobber (match_scratch:DI 4 "=a"))]
!   "TARGET_64BIT && !TARGET_MIPS4000 && !TARGET_MIPS16"
!   "dmult\\t%1,%2"
!   [(set_attr "type"	"imul")
!    (set_attr "mode"	"DI")])
! 
! (define_insn "muldi3_internal2"
!   [(set (match_operand:DI 0 "register_operand" "=d")
! 	(mult:DI (match_operand:DI 1 "se_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"))]
!   "TARGET_64BIT && (GENERATE_MULT3_DI || TARGET_MIPS4000 || TARGET_MIPS16)"
!   "*
! {
!   if (GENERATE_MULT3_DI)
!     output_asm_insn (\"dmult\\t%0,%1,%2\", operands);
!   else
!     {
!       rtx xoperands[10];
! 
!       xoperands[0] = operands[0];
!       xoperands[1] = gen_rtx_REG (DImode, LO_REGNUM);
! 
!       output_asm_insn (\"dmult\\t%1,%2\", operands);
!       output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
!     }
!   return \"\";
! }"
!   [(set_attr "type"	"imul")
!    (set_attr "mode"	"DI")
!    (set (attr "length")
! 	(if_then_else (ne (symbol_ref "GENERATE_MULT3_DI") (const_int 0))
! 		       (const_int 4)
! 		       (const_int 12)))]) 	;; mult + mflo + delay
  
  ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
  
--- 2001,2012 ----
     (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 7)))]
    "")
  
! ;; Define mulsidi3 before muldi3, since both match:
! ;;
! ;;	(mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
! ;;		 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
! ;;
! ;; on 64-bit machines, and we'd prefer to use mulsidi3 where possible.
  
  ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
  
***************
*** 2136,2141 ****
--- 2079,2143 ----
    [(set_attr "type"	"imul")
     (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"))]
+   "TARGET_64BIT"
+ 
+   "
+ {
+   if (GENERATE_MULT3_DI || TARGET_MIPS4000 || TARGET_MIPS16)
+     emit_insn (gen_muldi3_internal2 (operands[0], operands[1], operands[2]));
+   else
+     emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2]));
+   DONE;
+ }")
+ 
+ (define_insn "muldi3_internal"
+   [(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"))]
+   "TARGET_64BIT && !TARGET_MIPS4000 && !TARGET_MIPS16"
+   "dmult\\t%1,%2"
+   [(set_attr "type"	"imul")
+    (set_attr "mode"	"DI")])
+ 
+ (define_insn "muldi3_internal2"
+   [(set (match_operand:DI 0 "register_operand" "=d")
+ 	(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"))]
+   "TARGET_64BIT && (GENERATE_MULT3_DI || TARGET_MIPS4000 || TARGET_MIPS16)"
+   "*
+ {
+   if (GENERATE_MULT3_DI)
+     output_asm_insn (\"dmult\\t%0,%1,%2\", operands);
+   else
+     {
+       rtx xoperands[10];
+ 
+       xoperands[0] = operands[0];
+       xoperands[1] = gen_rtx_REG (DImode, LO_REGNUM);
+ 
+       output_asm_insn (\"dmult\\t%1,%2\", operands);
+       output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
+     }
+   return \"\";
+ }"
+   [(set_attr "type"	"imul")
+    (set_attr "mode"	"DI")
+    (set (attr "length")
+ 	(if_then_else (ne (symbol_ref "GENERATE_MULT3_DI") (const_int 0))
+ 		       (const_int 4)
+ 		       (const_int 12)))]) 	;; mult + mflo + delay
+ 
  ;; _highpart patterns
  (define_expand "smulsi3_highpart"
    [(set (match_operand:SI 0 "register_operand" "=h")
***************
*** 2206,2213 ****
  (define_insn "smuldi3_highpart"
    [(set (match_operand:DI 0 "register_operand" "=h")
  	(truncate:DI
! 	 (lshiftrt:TI (mult:TI (sign_extend:TI (match_operand:DI 1 "se_register_operand" "d"))
! 			       (sign_extend:TI (match_operand:DI 2 "se_register_operand" "d")))
  		      (const_int 64))))
     (clobber (match_scratch:DI 3 "=l"))
     (clobber (match_scratch:DI 4 "=a"))]
--- 2208,2215 ----
  (define_insn "smuldi3_highpart"
    [(set (match_operand:DI 0 "register_operand" "=h")
  	(truncate:DI
! 	 (lshiftrt:TI (mult:TI (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"))]
***************
*** 2219,2226 ****
  (define_insn "umuldi3_highpart"
    [(set (match_operand:DI 0 "register_operand" "=h")
  	(truncate:DI
! 	 (lshiftrt:TI (mult:TI (zero_extend:TI (match_operand:DI 1 "se_register_operand" "d"))
! 			       (zero_extend:TI (match_operand:DI 2 "se_register_operand" "d")))
  		      (const_int 64))))
     (clobber (match_scratch:DI 3 "=l"))
     (clobber (match_scratch:DI 4 "=a"))]
--- 2221,2228 ----
  (define_insn "umuldi3_highpart"
    [(set (match_operand:DI 0 "register_operand" "=h")
  	(truncate:DI
! 	 (lshiftrt:TI (mult:TI (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"))]
***************
*** 2479,2486 ****
  
  (define_expand "divmoddi4"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(div:DI (match_operand:DI 1 "se_register_operand" "d")
! 		(match_operand:DI 2 "se_register_operand" "d")))
     (set (match_operand:DI 3 "register_operand" "=d")
  	(mod:DI (match_dup 1)
  		(match_dup 2)))
--- 2481,2488 ----
  
  (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")
  	(mod:DI (match_dup 1)
  		(match_dup 2)))
***************
*** 2514,2521 ****
  
  (define_insn "divmoddi4_internal"
    [(set (match_operand:DI 0 "register_operand" "=l")
! 	(div:DI (match_operand:DI 1 "se_register_operand" "d")
! 		(match_operand:DI 2 "se_register_operand" "d")))
     (set (match_operand:DI 3 "register_operand" "=h")
  	(mod:DI (match_dup 1)
  		(match_dup 2)))
--- 2516,2523 ----
  
  (define_insn "divmoddi4_internal"
    [(set (match_operand:DI 0 "register_operand" "=l")
! 	(div:DI (match_operand:DI 1 "register_operand" "d")
! 		(match_operand:DI 2 "register_operand" "d")))
     (set (match_operand:DI 3 "register_operand" "=h")
  	(mod:DI (match_dup 1)
  		(match_dup 2)))
***************
*** 2565,2572 ****
  
  (define_expand "udivmoddi4"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(udiv:DI (match_operand:DI 1 "se_register_operand" "d")
! 		 (match_operand:DI 2 "se_register_operand" "d")))
     (set (match_operand:DI 3 "register_operand" "=d")
  	(umod:DI (match_dup 1)
  		 (match_dup 2)))
--- 2567,2574 ----
  
  (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")
  	(umod:DI (match_dup 1)
  		 (match_dup 2)))
***************
*** 2590,2597 ****
  
  (define_insn "udivmoddi4_internal"
    [(set (match_operand:DI 0 "register_operand" "=l")
! 	(udiv:DI (match_operand:DI 1 "se_register_operand" "d")
! 		 (match_operand:DI 2 "se_register_operand" "d")))
     (set (match_operand:DI 3 "register_operand" "=h")
  	(umod:DI (match_dup 1)
  		 (match_dup 2)))
--- 2592,2599 ----
  
  (define_insn "udivmoddi4_internal"
    [(set (match_operand:DI 0 "register_operand" "=l")
! 	(udiv:DI (match_operand:DI 1 "register_operand" "d")
! 		 (match_operand:DI 2 "register_operand" "d")))
     (set (match_operand:DI 3 "register_operand" "=h")
  	(umod:DI (match_dup 1)
  		 (match_dup 2)))
***************
*** 2739,2746 ****
  
  (define_expand "divdi3"
    [(set (match_operand:DI 0 "register_operand" "=l")
! 	(div:DI (match_operand:DI 1 "se_register_operand" "d")
! 		(match_operand:DI 2 "se_register_operand" "d")))
     (clobber (match_scratch:DI 3 "=h"))
     (clobber (match_scratch:DI 4 "=a"))]
    "TARGET_64BIT && !optimize"
--- 2741,2748 ----
  
  (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"))]
    "TARGET_64BIT && !optimize"
***************
*** 2769,2776 ****
  
  (define_insn "divdi3_internal"
    [(set (match_operand:DI 0 "register_operand" "=l")
! 	(div:DI (match_operand:DI 1 "se_register_operand" "d")
! 		(match_operand:DI 2 "se_nonmemory_operand" "di")))
     (clobber (match_scratch:SI 3 "=h"))
     (clobber (match_scratch:SI 4 "=a"))]
    "TARGET_64BIT && !optimize"
--- 2771,2778 ----
  
  (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"))]
    "TARGET_64BIT && !optimize"
***************
*** 2823,2830 ****
  
  (define_expand "moddi3"
    [(set (match_operand:DI 0 "register_operand" "=h")
! 	(mod:DI (match_operand:DI 1 "se_register_operand" "d")
! 		(match_operand:DI 2 "se_register_operand" "d")))
     (clobber (match_scratch:DI 3 "=l"))
     (clobber (match_scratch:DI 4 "=a"))]
    "TARGET_64BIT && !optimize"
--- 2825,2832 ----
  
  (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"))]
    "TARGET_64BIT && !optimize"
***************
*** 2853,2860 ****
  
  (define_insn "moddi3_internal"
    [(set (match_operand:DI 0 "register_operand" "=h")
! 	(mod:DI (match_operand:DI 1 "se_register_operand" "d")
! 		(match_operand:DI 2 "se_nonmemory_operand" "di")))
     (clobber (match_scratch:SI 3 "=l"))
     (clobber (match_scratch:SI 4 "=a"))]
    "TARGET_64BIT && !optimize"
--- 2855,2862 ----
  
  (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"))]
    "TARGET_64BIT && !optimize"
***************
*** 2895,2902 ****
  
  (define_expand "udivdi3"
    [(set (match_operand:DI 0 "register_operand" "=l")
! 	(udiv:DI (match_operand:DI 1 "se_register_operand" "d")
! 		 (match_operand:DI 2 "se_register_operand" "di")))
     (clobber (match_scratch:DI 3 "=h"))
     (clobber (match_scratch:DI 4 "=a"))]
    "TARGET_64BIT && !optimize"
--- 2897,2904 ----
  
  (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"))]
    "TARGET_64BIT && !optimize"
***************
*** 2915,2922 ****
  
  (define_insn "udivdi3_internal"
    [(set (match_operand:DI 0 "register_operand" "=l")
! 	(udiv:DI (match_operand:DI 1 "se_register_operand" "d")
! 		 (match_operand:DI 2 "se_nonmemory_operand" "di")))
     (clobber (match_scratch:SI 3 "=h"))
     (clobber (match_scratch:SI 4 "=a"))]
    "TARGET_64BIT && !optimize"
--- 2917,2924 ----
  
  (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"))]
    "TARGET_64BIT && !optimize"
***************
*** 2957,2964 ****
  
  (define_expand "umoddi3"
    [(set (match_operand:DI 0 "register_operand" "=h")
! 	(umod:DI (match_operand:DI 1 "se_register_operand" "d")
! 		 (match_operand:DI 2 "se_register_operand" "di")))
     (clobber (match_scratch:DI 3 "=l"))
     (clobber (match_scratch:DI 4 "=a"))]
    "TARGET_64BIT && !optimize"
--- 2959,2966 ----
  
  (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"))]
    "TARGET_64BIT && !optimize"
***************
*** 2977,2984 ****
  
  (define_insn "umoddi3_internal"
    [(set (match_operand:DI 0 "register_operand" "=h")
! 	(umod:DI (match_operand:DI 1 "se_register_operand" "d")
! 		 (match_operand:DI 2 "se_nonmemory_operand" "di")))
     (clobber (match_scratch:SI 3 "=l"))
     (clobber (match_scratch:SI 4 "=a"))]
    "TARGET_64BIT && !optimize"
--- 2979,2986 ----
  
  (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"))]
    "TARGET_64BIT && !optimize"
***************
*** 3064,3070 ****
  
  (define_insn "absdi2"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(abs:DI (match_operand:DI 1 "se_register_operand" "d")))]
    "TARGET_64BIT && !TARGET_MIPS16"
    "*
  {
--- 3066,3072 ----
  
  (define_insn "absdi2"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(abs:DI (match_operand:DI 1 "register_operand" "d")))]
    "TARGET_64BIT && !TARGET_MIPS16"
    "*
  {
*************** move\\t%0,%z4\\n\\
*** 3150,3156 ****
  
  (define_insn "ffsdi2"
    [(set (match_operand:DI 0 "register_operand" "=&d")
! 	(ffs:DI (match_operand:DI 1 "se_register_operand" "d")))
     (clobber (match_scratch:DI 2 "=&d"))
     (clobber (match_scratch:DI 3 "=&d"))]
    "TARGET_64BIT && !TARGET_MIPS16"
--- 3152,3158 ----
  
  (define_insn "ffsdi2"
    [(set (match_operand:DI 0 "register_operand" "=&d")
! 	(ffs:DI (match_operand:DI 1 "register_operand" "d")))
     (clobber (match_scratch:DI 2 "=&d"))
     (clobber (match_scratch:DI 3 "=&d"))]
    "TARGET_64BIT && !TARGET_MIPS16"
*************** move\\t%0,%z4\\n\\
*** 3208,3214 ****
  
  (define_expand "negdi2"
    [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
! 		   (neg:DI (match_operand:DI 1 "se_register_operand" "d")))
  	      (clobber (match_dup 2))])]
    "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
    "
--- 3210,3216 ----
  
  (define_expand "negdi2"
    [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
! 		   (neg:DI (match_operand:DI 1 "register_operand" "d")))
  	      (clobber (match_dup 2))])]
    "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
    "
*************** move\\t%0,%z4\\n\\
*** 3238,3244 ****
  
  (define_insn "negdi2_internal_2"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(neg:DI (match_operand:DI 1 "se_register_operand" "d")))]
    "TARGET_64BIT && !TARGET_MIPS16"
    "*
  {
--- 3240,3246 ----
  
  (define_insn "negdi2_internal_2"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(neg:DI (match_operand:DI 1 "register_operand" "d")))]
    "TARGET_64BIT && !TARGET_MIPS16"
    "*
  {
*************** move\\t%0,%z4\\n\\
*** 3280,3286 ****
  
  (define_insn "one_cmpldi2"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(not:DI (match_operand:DI 1 "se_register_operand" "d")))]
    ""
    "*
  {
--- 3282,3288 ----
  
  (define_insn "one_cmpldi2"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(not:DI (match_operand:DI 1 "register_operand" "d")))]
    ""
    "*
  {
*************** move\\t%0,%z4\\n\\
*** 3362,3369 ****
  
  (define_expand "anddi3"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(and:DI (match_operand:DI 1 "se_register_operand" "d")
! 		(match_operand:DI 2 "se_register_operand" "d")))]
    "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
    "
  {
--- 3364,3371 ----
  
  (define_expand "anddi3"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(and:DI (match_operand:DI 1 "register_operand" "d")
! 		(match_operand:DI 2 "register_operand" "d")))]
    "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
    "
  {
*************** move\\t%0,%z4\\n\\
*** 3376,3383 ****
  
  (define_insn ""
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(and:DI (match_operand:DI 1 "se_register_operand" "d")
! 		(match_operand:DI 2 "se_register_operand" "d")))]
    "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
    "*
  {
--- 3378,3385 ----
  
  (define_insn ""
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(and:DI (match_operand:DI 1 "register_operand" "d")
! 		(match_operand:DI 2 "register_operand" "d")))]
    "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
    "*
  {
*************** move\\t%0,%z4\\n\\
*** 3394,3401 ****
  
  (define_insn ""
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(and:DI (match_operand:DI 1 "se_register_operand" "0")
! 		(match_operand:DI 2 "se_register_operand" "d")))]
    "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && TARGET_MIPS16"
    "*
  {
--- 3396,3403 ----
  
  (define_insn ""
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(and:DI (match_operand:DI 1 "register_operand" "0")
! 		(match_operand:DI 2 "register_operand" "d")))]
    "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && TARGET_MIPS16"
    "*
  {
*************** move\\t%0,%z4\\n\\
*** 3426,3433 ****
  
  (define_insn "anddi3_internal1"
    [(set (match_operand:DI 0 "register_operand" "=d,d")
! 	(and:DI (match_operand:DI 1 "se_register_operand" "%d,d")
! 		(match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
    "TARGET_64BIT && !TARGET_MIPS16"
    "@
     and\\t%0,%1,%2
--- 3428,3435 ----
  
  (define_insn "anddi3_internal1"
    [(set (match_operand:DI 0 "register_operand" "=d,d")
! 	(and:DI (match_operand:DI 1 "register_operand" "%d,d")
! 		(match_operand:DI 2 "uns_arith_operand" "d,K")))]
    "TARGET_64BIT && !TARGET_MIPS16"
    "@
     and\\t%0,%1,%2
*************** move\\t%0,%z4\\n\\
*** 3474,3488 ****
  
  (define_expand "iordi3"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(ior:DI (match_operand:DI 1 "se_register_operand" "d")
! 		(match_operand:DI 2 "se_register_operand" "d")))]
    "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
    "")
  
  (define_insn ""
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(ior:DI (match_operand:DI 1 "se_register_operand" "d")
! 		(match_operand:DI 2 "se_register_operand" "d")))]
    "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
    "*
  {
--- 3476,3490 ----
  
  (define_expand "iordi3"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(ior:DI (match_operand:DI 1 "register_operand" "d")
! 		(match_operand:DI 2 "register_operand" "d")))]
    "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
    "")
  
  (define_insn ""
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(ior:DI (match_operand:DI 1 "register_operand" "d")
! 		(match_operand:DI 2 "register_operand" "d")))]
    "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
    "*
  {
*************** move\\t%0,%z4\\n\\
*** 3499,3506 ****
  
  (define_insn ""
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(ior:DI (match_operand:DI 1 "se_register_operand" "0")
! 		(match_operand:DI 2 "se_register_operand" "d")))]
    "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && TARGET_MIPS16"
    "*
  {
--- 3501,3508 ----
  
  (define_insn ""
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(ior:DI (match_operand:DI 1 "register_operand" "0")
! 		(match_operand:DI 2 "register_operand" "d")))]
    "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && TARGET_MIPS16"
    "*
  {
*************** move\\t%0,%z4\\n\\
*** 3569,3583 ****
  ;; the following xordi3_internal pattern.
  (define_expand "xordi3"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(xor:DI (match_operand:DI 1 "se_register_operand" "d")
! 		(match_operand:DI 2 "se_register_operand" "d")))]
    "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
    "")
  
  (define_insn ""
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(xor:DI (match_operand:DI 1 "se_register_operand" "d")
! 		(match_operand:DI 2 "se_register_operand" "d")))]
    "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
    "*
  {
--- 3571,3585 ----
  ;; the following xordi3_internal pattern.
  (define_expand "xordi3"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(xor:DI (match_operand:DI 1 "register_operand" "d")
! 		(match_operand:DI 2 "register_operand" "d")))]
    "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
    "")
  
  (define_insn ""
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(xor:DI (match_operand:DI 1 "register_operand" "d")
! 		(match_operand:DI 2 "register_operand" "d")))]
    "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
    "*
  {
*************** move\\t%0,%z4\\n\\
*** 3594,3601 ****
  
  (define_insn ""
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(xor:DI (match_operand:DI 1 "se_register_operand" "0")
! 		(match_operand:DI 2 "se_register_operand" "d")))]
    "!TARGET_64BIT && TARGET_MIPS16"
    "xor\\t%M0,%M2\;xor\\t%L0,%L2"
    [(set_attr "type"	"darith")
--- 3596,3603 ----
  
  (define_insn ""
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(xor:DI (match_operand:DI 1 "register_operand" "0")
! 		(match_operand:DI 2 "register_operand" "d")))]
    "!TARGET_64BIT && TARGET_MIPS16"
    "xor\\t%M0,%M2\;xor\\t%L0,%L2"
    [(set_attr "type"	"darith")
*************** move\\t%0,%z4\\n\\
*** 3604,3611 ****
  
  (define_insn ""
    [(set (match_operand:DI 0 "register_operand" "=d,t,t")
! 	(xor:DI (match_operand:DI 1 "se_register_operand" "%0,d,d")
! 		(match_operand:DI 2 "se_uns_arith_operand" "d,K,d")))]
    "TARGET_64BIT && TARGET_MIPS16"
    "@
     xor\\t%0,%2
--- 3606,3613 ----
  
  (define_insn ""
    [(set (match_operand:DI 0 "register_operand" "=d,t,t")
! 	(xor:DI (match_operand:DI 1 "register_operand" "%0,d,d")
! 		(match_operand:DI 2 "uns_arith_operand" "d,K,d")))]
    "TARGET_64BIT && TARGET_MIPS16"
    "@
     xor\\t%0,%2
*************** move\\t%0,%z4\\n\\
*** 3636,3643 ****
  
  (define_insn "xordi3_immed"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(xor:DI (match_operand:DI 1 "se_register_operand" "d")
! 		(match_operand:DI 2 "se_uns_arith_operand" "K")))]
    "TARGET_64BIT && !TARGET_MIPS16"
    "xori\\t%0,%1,%x2"
    [(set_attr "type"	"arith")
--- 3638,3645 ----
  
  (define_insn "xordi3_immed"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(xor:DI (match_operand:DI 1 "register_operand" "d")
! 		(match_operand:DI 2 "uns_arith_operand" "K")))]
    "TARGET_64BIT && !TARGET_MIPS16"
    "xori\\t%0,%1,%x2"
    [(set_attr "type"	"arith")
*************** move\\t%0,%z4\\n\\
*** 3654,3661 ****
  
  (define_insn "*nordi3"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(and:DI (not:DI (match_operand:DI 1 "se_register_operand" "d"))
! 		(not:DI (match_operand:DI 2 "se_register_operand" "d"))))]
    "!TARGET_MIPS16"
    "*
  {
--- 3656,3663 ----
  
  (define_insn "*nordi3"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(and:DI (not:DI (match_operand:DI 1 "register_operand" "d"))
! 		(not:DI (match_operand:DI 2 "register_operand" "d"))))]
    "!TARGET_MIPS16"
    "*
  {
*************** move\\t%0,%z4\\n\\
*** 3701,3707 ****
  
  (define_insn "truncdisi2"
    [(set (match_operand:SI 0 "register_operand" "=d")
! 	(truncate:SI (match_operand:DI 1 "se_register_operand" "d")))]
    "TARGET_64BIT"
    "*
  {
--- 3703,3709 ----
  
  (define_insn "truncdisi2"
    [(set (match_operand:SI 0 "register_operand" "=d")
! 	(truncate:SI (match_operand:DI 1 "register_operand" "d")))]
    "TARGET_64BIT"
    "*
  {
*************** move\\t%0,%z4\\n\\
*** 3717,3723 ****
  
  (define_insn "truncdihi2"
    [(set (match_operand:HI 0 "register_operand" "=d")
! 	(truncate:HI (match_operand:DI 1 "se_register_operand" "d")))]
    "TARGET_64BIT"
    "*
  {
--- 3719,3725 ----
  
  (define_insn "truncdihi2"
    [(set (match_operand:HI 0 "register_operand" "=d")
! 	(truncate:HI (match_operand:DI 1 "register_operand" "d")))]
    "TARGET_64BIT"
    "*
  {
*************** move\\t%0,%z4\\n\\
*** 3732,3738 ****
  				      (const_int 16)))])
  (define_insn "truncdiqi2"
    [(set (match_operand:QI 0 "register_operand" "=d")
! 	(truncate:QI (match_operand:DI 1 "se_register_operand" "d")))]
    "TARGET_64BIT"
    "*
  {
--- 3734,3740 ----
  				      (const_int 16)))])
  (define_insn "truncdiqi2"
    [(set (match_operand:QI 0 "register_operand" "=d")
! 	(truncate:QI (match_operand:DI 1 "register_operand" "d")))]
    "TARGET_64BIT"
    "*
  {
*************** move\\t%0,%z4\\n\\
*** 3749,3755 ****
  ;; Combiner patterns to optimize shift/truncate combinations.
  (define_insn ""
    [(set (match_operand:SI 0 "register_operand" "=d")
! 	(truncate:SI (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
  				  (match_operand:DI 2 "small_int" "I"))))]
    "TARGET_64BIT && !TARGET_MIPS16"
    "*
--- 3751,3757 ----
  ;; Combiner patterns to optimize shift/truncate combinations.
  (define_insn ""
    [(set (match_operand:SI 0 "register_operand" "=d")
! 	(truncate:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
  				  (match_operand:DI 2 "small_int" "I"))))]
    "TARGET_64BIT && !TARGET_MIPS16"
    "*
*************** move\\t%0,%z4\\n\\
*** 3773,3779 ****
  
  (define_insn ""
    [(set (match_operand:SI 0 "register_operand" "=d")
! 	(truncate:SI (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
  				  (match_operand:DI 2 "small_int" "I"))))]
    "TARGET_64BIT && !TARGET_MIPS16"
    "*
--- 3775,3781 ----
  
  (define_insn ""
    [(set (match_operand:SI 0 "register_operand" "=d")
! 	(truncate:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
  				  (match_operand:DI 2 "small_int" "I"))))]
    "TARGET_64BIT && !TARGET_MIPS16"
    "*
*************** move\\t%0,%z4\\n\\
*** 3799,3805 ****
  
  (define_insn ""
    [(set (match_operand:SI 0 "register_operand" "=d")
! 	(truncate:SI (ashift:DI (match_operand:DI 1 "se_register_operand" "d")
  				(match_operand:DI 2 "small_int" "I"))))]
    "TARGET_64BIT"
    "*
--- 3801,3807 ----
  
  (define_insn ""
    [(set (match_operand:SI 0 "register_operand" "=d")
! 	(truncate:SI (ashift:DI (match_operand:DI 1 "register_operand" "d")
  				(match_operand:DI 2 "small_int" "I"))))]
    "TARGET_64BIT"
    "*
*************** move\\t%0,%z4\\n\\
*** 3825,3831 ****
  (define_insn ""
    [(set (match_operand:SI 0 "register_operand" "=d")
  	(zero_extend:SI (truncate:HI
! 			 (match_operand:DI 1 "se_register_operand" "d"))))]
    "TARGET_64BIT && !TARGET_MIPS16"
    "andi\\t%0,%1,0xffff"
    [(set_attr "type"	"darith")
--- 3827,3833 ----
  (define_insn ""
    [(set (match_operand:SI 0 "register_operand" "=d")
  	(zero_extend:SI (truncate:HI
! 			 (match_operand:DI 1 "register_operand" "d"))))]
    "TARGET_64BIT && !TARGET_MIPS16"
    "andi\\t%0,%1,0xffff"
    [(set_attr "type"	"darith")
*************** move\\t%0,%z4\\n\\
*** 3834,3840 ****
  (define_insn ""
    [(set (match_operand:SI 0 "register_operand" "=d")
  	(zero_extend:SI (truncate:QI
! 			 (match_operand:DI 1 "se_register_operand" "d"))))]
    "TARGET_64BIT && !TARGET_MIPS16"
    "andi\\t%0,%1,0xff"
    [(set_attr "type"	"darith")
--- 3836,3842 ----
  (define_insn ""
    [(set (match_operand:SI 0 "register_operand" "=d")
  	(zero_extend:SI (truncate:QI
! 			 (match_operand:DI 1 "register_operand" "d"))))]
    "TARGET_64BIT && !TARGET_MIPS16"
    "andi\\t%0,%1,0xff"
    [(set_attr "type"	"darith")
*************** move\\t%0,%z4\\n\\
*** 3843,3849 ****
  (define_insn ""
    [(set (match_operand:HI 0 "register_operand" "=d")
  	(zero_extend:HI (truncate:QI
! 			 (match_operand:DI 1 "se_register_operand" "d"))))]
    "TARGET_64BIT && !TARGET_MIPS16"
    "andi\\t%0,%1,0xff"
    [(set_attr "type"	"darith")
--- 3845,3851 ----
  (define_insn ""
    [(set (match_operand:HI 0 "register_operand" "=d")
  	(zero_extend:HI (truncate:QI
! 			 (match_operand:DI 1 "register_operand" "d"))))]
    "TARGET_64BIT && !TARGET_MIPS16"
    "andi\\t%0,%1,0xff"
    [(set_attr "type"	"darith")
*************** move\\t%0,%z4\\n\\
*** 4081,4104 ****
     (set_attr "mode"	"DI")
     (set_attr "length"	"4,4,8")])
  
- ;; These can be created when a paradoxical subreg operand with an implicit
- ;; sign_extend operator is reloaded.  Because of the subreg, this is really
- ;; a zero extend.
- ;; ??? It might be possible to eliminate the need for these patterns by adding
- ;; more support to reload for implicit sign_extend operators.
- (define_insn "*paradoxical_extendhidi2"
-   [(set (match_operand:DI 0 "register_operand" "=d,d")
- 	(sign_extend:DI
- 	 (subreg:SI (match_operand:HI 1 "memory_operand" "R,m") 0)))]
-   "TARGET_64BIT"
-   "*
- {
-   return mips_move_1word (operands, insn, TRUE);
- }"
-   [(set_attr "type"	"load,load")
-    (set_attr "mode"	"DI")
-    (set_attr "length"	"4,8")])
- 
  (define_insn ""
    [(set (match_operand:DI 0 "register_operand" "=d,d")
  	(zero_extend:DI (match_operand:QI 1 "memory_operand" "R,m")))]
--- 4083,4088 ----
*************** move\\t%0,%z4\\n\\
*** 4445,4451 ****
  
  (define_insn "floatdidf2"
    [(set (match_operand:DF 0 "register_operand" "=f,f,f")
! 	(float:DF (match_operand:DI 1 "se_nonimmediate_operand" "d,R,m")))]
    "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
    "*
  {
--- 4429,4435 ----
  
  (define_insn "floatdidf2"
    [(set (match_operand:DF 0 "register_operand" "=f,f,f")
! 	(float:DF (match_operand:DI 1 "nonimmediate_operand" "d,R,m")))]
    "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
    "*
  {
*************** move\\t%0,%z4\\n\\
*** 4479,4485 ****
  
  (define_insn "floatdisf2"
    [(set (match_operand:SF 0 "register_operand" "=f,f,f")
! 	(float:SF (match_operand:DI 1 "se_nonimmediate_operand" "d,R,m")))]
    "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
    "*
  {
--- 4463,4469 ----
  
  (define_insn "floatdisf2"
    [(set (match_operand:SF 0 "register_operand" "=f,f,f")
! 	(float:SF (match_operand:DI 1 "nonimmediate_operand" "d,R,m")))]
    "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
    "*
  {
*************** move\\t%0,%z4\\n\\
*** 5130,5141 ****
     (set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 4))]
    "")
  
  (define_insn "movdi_internal2"
    [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*x,*d,*x,*a,*B*C*D,*B*C*D,*B*C*D,*d,*m,*R")
! 	(match_operand:DI 1 "movdi_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,J,*x,*d,*J,*d,*m,*R,*B*C*D,*B*C*D,*B*C*D"))]
    "TARGET_64BIT && !TARGET_MIPS16
     && (register_operand (operands[0], DImode)
!        || se_register_operand (operands[1], DImode)
         || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
         || operands[1] == CONST0_RTX (DImode))"
    "* return mips_move_2words (operands, insn); "
--- 5114,5127 ----
     (set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 4))]
    "")
  
+ ;; This pattern also matches sign extensions of (reg:SI) to (mem:DI).
+ 
  (define_insn "movdi_internal2"
    [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*x,*d,*x,*a,*B*C*D,*B*C*D,*B*C*D,*d,*m,*R")
! 	(match_operand:DI 1 "move_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,J,*x,*d,*J,*d,*m,*R,*B*C*D,*B*C*D,*B*C*D"))]
    "TARGET_64BIT && !TARGET_MIPS16
     && (register_operand (operands[0], DImode)
!        || register_operand (operands[1], VOIDmode)
         || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
         || operands[1] == CONST0_RTX (DImode))"
    "* return mips_move_2words (operands, insn); "
*************** move\\t%0,%z4\\n\\
*** 5145,5154 ****
  
  (define_insn ""
    [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,R,m,*d")
! 	(match_operand:DI 1 "movdi_operand" "d,d,y,K,N,s,R,m,d,d,*x"))]
    "TARGET_64BIT && TARGET_MIPS16
     && (register_operand (operands[0], DImode)
!        || se_register_operand (operands[1], DImode))"
    "* return mips_move_2words (operands, insn);"
    [(set_attr "type"	"move,move,move,arith,arith,arith,load,load,store,store,hilo")
     (set_attr "mode"	"DI")
--- 5131,5140 ----
  
  (define_insn ""
    [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,R,m,*d")
! 	(match_operand:DI 1 "move_operand" "d,d,y,K,N,s,R,m,d,d,*x"))]
    "TARGET_64BIT && TARGET_MIPS16
     && (register_operand (operands[0], DImode)
!        || register_operand (operands[1], VOIDmode))"
    "* return mips_move_2words (operands, insn);"
    [(set_attr "type"	"move,move,move,arith,arith,arith,load,load,store,store,hilo")
     (set_attr "mode"	"DI")
*************** move\\t%0,%z4\\n\\
*** 5299,5305 ****
  
  (define_expand "reload_outdi"
    [(set (match_operand:DI 0 "general_operand" "=b")
! 	(match_operand:DI 1 "se_register_operand" "b"))
     (clobber (match_operand:TI 2 "register_operand" "=&d"))]
    "TARGET_64BIT"
    "
--- 5285,5291 ----
  
  (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"
    "
*************** move\\t%0,%z4\\n\\
*** 5943,5950 ****
  
  (define_insn ""
    [(set (match_operand:SF 0 "register_operand" "=f")
! 	(mem:SF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
! 			 (match_operand:DI 2 "se_register_operand" "d"))))]
    "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
    "lwxc1\\t%0,%1(%2)"
    [(set_attr "type"	"load")
--- 5929,5936 ----
  
  (define_insn ""
    [(set (match_operand:SF 0 "register_operand" "=f")
! 	(mem:SF (plus:DI (match_operand:DI 1 "register_operand" "d")
! 			 (match_operand:DI 2 "register_operand" "d"))))]
    "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
    "lwxc1\\t%0,%1(%2)"
    [(set_attr "type"	"load")
*************** move\\t%0,%z4\\n\\
*** 5961,5968 ****
  
  (define_insn ""
    [(set (match_operand:DF 0 "register_operand" "=f")
! 	(mem:DF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
! 			 (match_operand:DI 2 "se_register_operand" "d"))))]
    "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
    "ldxc1\\t%0,%1(%2)"
    [(set_attr "type"	"load")
--- 5947,5954 ----
  
  (define_insn ""
    [(set (match_operand:DF 0 "register_operand" "=f")
! 	(mem:DF (plus:DI (match_operand:DI 1 "register_operand" "d")
! 			 (match_operand:DI 2 "register_operand" "d"))))]
    "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
    "ldxc1\\t%0,%1(%2)"
    [(set_attr "type"	"load")
*************** move\\t%0,%z4\\n\\
*** 5978,5985 ****
     (set_attr "mode"	"SF")])
  
  (define_insn ""
!   [(set (mem:SF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
! 			 (match_operand:DI 2 "se_register_operand" "d")))
  	(match_operand:SF 0 "register_operand" "f"))]
    "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
    "swxc1\\t%0,%1(%2)"
--- 5964,5971 ----
     (set_attr "mode"	"SF")])
  
  (define_insn ""
!   [(set (mem:SF (plus:DI (match_operand:DI 1 "register_operand" "d")
! 			 (match_operand:DI 2 "register_operand" "d")))
  	(match_operand:SF 0 "register_operand" "f"))]
    "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
    "swxc1\\t%0,%1(%2)"
*************** move\\t%0,%z4\\n\\
*** 5996,6003 ****
     (set_attr "mode"	"DF")])
  
  (define_insn ""
!   [(set (mem:DF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
! 			 (match_operand:DI 2 "se_register_operand" "d")))
  	(match_operand:DF 0 "register_operand" "f"))]
    "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
    "sdxc1\\t%0,%1(%2)"
--- 5982,5989 ----
     (set_attr "mode"	"DF")])
  
  (define_insn ""
!   [(set (mem:DF (plus:DI (match_operand:DI 1 "register_operand" "d")
! 			 (match_operand:DI 2 "register_operand" "d")))
  	(match_operand:DF 0 "register_operand" "f"))]
    "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
    "sdxc1\\t%0,%1(%2)"
*************** move\\t%0,%z4\\n\\
*** 6645,6651 ****
  
  (define_expand "ashldi3"
    [(parallel [(set (match_operand:DI 0 "register_operand" "")
! 		   (ashift:DI (match_operand:DI 1 "se_register_operand" "")
  			      (match_operand:SI 2 "arith_operand" "")))
  	      (clobber (match_dup  3))])]
    "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
--- 6631,6637 ----
  
  (define_expand "ashldi3"
    [(parallel [(set (match_operand:DI 0 "register_operand" "")
! 		   (ashift:DI (match_operand:DI 1 "register_operand" "")
  			      (match_operand:SI 2 "arith_operand" "")))
  	      (clobber (match_dup  3))])]
    "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
*************** move\\t%0,%z4\\n\\
*** 6866,6872 ****
  
  (define_insn "ashldi3_internal4"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(ashift:DI (match_operand:DI 1 "se_register_operand" "d")
  		   (match_operand:SI 2 "arith_operand" "dI")))]
    "TARGET_64BIT && !TARGET_MIPS16"
    "*
--- 6852,6858 ----
  
  (define_insn "ashldi3_internal4"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(ashift:DI (match_operand:DI 1 "register_operand" "d")
  		   (match_operand:SI 2 "arith_operand" "dI")))]
    "TARGET_64BIT && !TARGET_MIPS16"
    "*
*************** move\\t%0,%z4\\n\\
*** 6881,6887 ****
  
  (define_insn ""
    [(set (match_operand:DI 0 "register_operand" "=d,d")
! 	(ashift:DI (match_operand:DI 1 "se_register_operand" "0,d")
  		   (match_operand:SI 2 "arith_operand" "d,I")))]
    "TARGET_64BIT && TARGET_MIPS16"
    "*
--- 6867,6873 ----
  
  (define_insn ""
    [(set (match_operand:DI 0 "register_operand" "=d,d")
! 	(ashift:DI (match_operand:DI 1 "register_operand" "0,d")
  		   (match_operand:SI 2 "arith_operand" "d,I")))]
    "TARGET_64BIT && TARGET_MIPS16"
    "*
*************** move\\t%0,%z4\\n\\
*** 7006,7012 ****
  
  (define_expand "ashrdi3"
    [(parallel [(set (match_operand:DI 0 "register_operand" "")
! 		   (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "")
  				(match_operand:SI 2 "arith_operand" "")))
  	      (clobber (match_dup  3))])]
    "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
--- 6992,6998 ----
  
  (define_expand "ashrdi3"
    [(parallel [(set (match_operand:DI 0 "register_operand" "")
! 		   (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
  				(match_operand:SI 2 "arith_operand" "")))
  	      (clobber (match_dup  3))])]
    "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
*************** move\\t%0,%z4\\n\\
*** 7220,7226 ****
  
  (define_insn "ashrdi3_internal4"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(ashiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
  		     (match_operand:SI 2 "arith_operand" "dI")))]
    "TARGET_64BIT && !TARGET_MIPS16"
    "*
--- 7206,7212 ----
  
  (define_insn "ashrdi3_internal4"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
  		     (match_operand:SI 2 "arith_operand" "dI")))]
    "TARGET_64BIT && !TARGET_MIPS16"
    "*
*************** move\\t%0,%z4\\n\\
*** 7235,7241 ****
  
  (define_insn ""
    [(set (match_operand:DI 0 "register_operand" "=d,d")
! 	(ashiftrt:DI (match_operand:DI 1 "se_register_operand" "0,0")
  		     (match_operand:SI 2 "arith_operand" "d,I")))]
    "TARGET_64BIT && TARGET_MIPS16"
    "*
--- 7221,7227 ----
  
  (define_insn ""
    [(set (match_operand:DI 0 "register_operand" "=d,d")
! 	(ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
  		     (match_operand:SI 2 "arith_operand" "d,I")))]
    "TARGET_64BIT && TARGET_MIPS16"
    "*
*************** move\\t%0,%z4\\n\\
*** 7388,7394 ****
  
  (define_expand "lshrdi3"
    [(parallel [(set (match_operand:DI 0 "register_operand" "")
! 		   (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "")
  				(match_operand:SI 2 "arith_operand" "")))
  	      (clobber (match_dup  3))])]
    "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
--- 7374,7380 ----
  
  (define_expand "lshrdi3"
    [(parallel [(set (match_operand:DI 0 "register_operand" "")
! 		   (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
  				(match_operand:SI 2 "arith_operand" "")))
  	      (clobber (match_dup  3))])]
    "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
*************** move\\t%0,%z4\\n\\
*** 7604,7610 ****
  
  (define_insn "lshrdi3_internal4"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(lshiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
  		     (match_operand:SI 2 "arith_operand" "dI")))]
    "TARGET_64BIT && !TARGET_MIPS16"
    "*
--- 7590,7596 ----
  
  (define_insn "lshrdi3_internal4"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
  		     (match_operand:SI 2 "arith_operand" "dI")))]
    "TARGET_64BIT && !TARGET_MIPS16"
    "*
*************** move\\t%0,%z4\\n\\
*** 7619,7625 ****
  
  (define_insn ""
    [(set (match_operand:DI 0 "register_operand" "=d,d")
! 	(lshiftrt:DI (match_operand:DI 1 "se_register_operand" "0,0")
  		     (match_operand:SI 2 "arith_operand" "d,I")))]
    "TARGET_64BIT && TARGET_MIPS16"
    "*
--- 7605,7611 ----
  
  (define_insn ""
    [(set (match_operand:DI 0 "register_operand" "=d,d")
! 	(lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
  		     (match_operand:SI 2 "arith_operand" "d,I")))]
    "TARGET_64BIT && TARGET_MIPS16"
    "*
*************** move\\t%0,%z4\\n\\
*** 7711,7718 ****
  
  (define_expand "cmpdi"
    [(set (cc0)
! 	(compare:CC (match_operand:DI 0 "se_register_operand" "")
! 		    (match_operand:DI 1 "se_arith_operand" "")))]
    "TARGET_64BIT"
    "
  {
--- 7697,7704 ----
  
  (define_expand "cmpdi"
    [(set (cc0)
! 	(compare:CC (match_operand:DI 0 "register_operand" "")
! 		    (match_operand:DI 1 "arith_operand" "")))]
    "TARGET_64BIT"
    "
  {
*************** move\\t%0,%z4\\n\\
*** 7727,7733 ****
  
  (define_expand "tstdi"
    [(set (cc0)
! 	(match_operand:DI 0 "se_register_operand" ""))]
    "TARGET_64BIT"
    "
  {
--- 7713,7719 ----
  
  (define_expand "tstdi"
    [(set (cc0)
! 	(match_operand:DI 0 "register_operand" ""))]
    "TARGET_64BIT"
    "
  {
*************** move\\t%0,%z4\\n\\
*** 7872,7878 ****
    [(set (pc)
  	(if_then_else
           (match_operator:DI 0 "cmp_op"
! 		            [(match_operand:DI 2 "se_register_operand" "d")
  			     (const_int 0)])
          (label_ref (match_operand 1 "" ""))
          (pc)))]
--- 7858,7864 ----
    [(set (pc)
  	(if_then_else
           (match_operator:DI 0 "cmp_op"
! 		            [(match_operand:DI 2 "register_operand" "d")
  			     (const_int 0)])
          (label_ref (match_operand 1 "" ""))
          (pc)))]
*************** move\\t%0,%z4\\n\\
*** 7893,7899 ****
    [(set (pc)
  	(if_then_else
           (match_operator:DI 0 "cmp_op"
! 			    [(match_operand:DI 2 "se_register_operand" "d")
  			     (const_int 0)])
          (pc)
          (label_ref (match_operand 1 "" ""))))]
--- 7879,7885 ----
    [(set (pc)
  	(if_then_else
           (match_operator:DI 0 "cmp_op"
! 			    [(match_operand:DI 2 "register_operand" "d")
  			     (const_int 0)])
          (pc)
          (label_ref (match_operand 1 "" ""))))]
*************** move\\t%0,%z4\\n\\
*** 7937,7944 ****
    [(set (pc)
  	(if_then_else
           (match_operator:DI 0 "equality_op"
! 			    [(match_operand:DI 2 "se_register_operand" "d")
! 			     (match_operand:DI 3 "se_register_operand" "d")])
          (label_ref (match_operand 1 "" ""))
          (pc)))]
    "!TARGET_MIPS16"
--- 7923,7930 ----
    [(set (pc)
  	(if_then_else
           (match_operator:DI 0 "equality_op"
! 			    [(match_operand:DI 2 "register_operand" "d")
! 			     (match_operand:DI 3 "register_operand" "d")])
          (label_ref (match_operand 1 "" ""))
          (pc)))]
    "!TARGET_MIPS16"
*************** move\\t%0,%z4\\n\\
*** 7979,7986 ****
    [(set (pc)
  	(if_then_else
           (match_operator:DI 0 "equality_op"
! 			    [(match_operand:DI 2 "se_register_operand" "d")
! 			     (match_operand:DI 3 "se_register_operand" "d")])
          (pc)
          (label_ref (match_operand 1 "" ""))))]
    "!TARGET_MIPS16"
--- 7965,7972 ----
    [(set (pc)
  	(if_then_else
           (match_operator:DI 0 "equality_op"
! 			    [(match_operand:DI 2 "register_operand" "d")
! 			     (match_operand:DI 3 "register_operand" "d")])
          (pc)
          (label_ref (match_operand 1 "" ""))))]
    "!TARGET_MIPS16"
*************** move\\t%0,%z4\\n\\
*** 8030,8036 ****
  (define_insn ""
    [(set (pc)
  	(if_then_else (match_operator:DI 0 "equality_op"
! 					 [(match_operand:DI 1 "se_register_operand" "d,t")
  					  (const_int 0)])
  	(match_operand 2 "pc_or_label_operand" "")
  	(match_operand 3 "pc_or_label_operand" "")))]
--- 8016,8022 ----
  (define_insn ""
    [(set (pc)
  	(if_then_else (match_operator:DI 0 "equality_op"
! 					 [(match_operand:DI 1 "register_operand" "d,t")
  					  (const_int 0)])
  	(match_operand 2 "pc_or_label_operand" "")
  	(match_operand 3 "pc_or_label_operand" "")))]
*************** move\\t%0,%z4\\n\\
*** 8272,8278 ****
  
  (define_insn "seq_di_zero"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(eq:DI (match_operand:DI 1 "se_register_operand" "d")
  	       (const_int 0)))]
    "TARGET_64BIT && !TARGET_MIPS16"
    "sltu\\t%0,%1,1"
--- 8258,8264 ----
  
  (define_insn "seq_di_zero"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(eq:DI (match_operand:DI 1 "register_operand" "d")
  	       (const_int 0)))]
    "TARGET_64BIT && !TARGET_MIPS16"
    "sltu\\t%0,%1,1"
*************** move\\t%0,%z4\\n\\
*** 8281,8287 ****
  
  (define_insn ""
    [(set (match_operand:DI 0 "register_operand" "=t")
! 	(eq:DI (match_operand:DI 1 "se_register_operand" "d")
  	       (const_int 0)))]
    "TARGET_64BIT && TARGET_MIPS16"
    "sltu\\t%1,1"
--- 8267,8273 ----
  
  (define_insn ""
    [(set (match_operand:DI 0 "register_operand" "=t")
! 	(eq:DI (match_operand:DI 1 "register_operand" "d")
  	       (const_int 0)))]
    "TARGET_64BIT && TARGET_MIPS16"
    "sltu\\t%1,1"
*************** move\\t%0,%z4\\n\\
*** 8316,8323 ****
  
  (define_insn "seq_di"
    [(set (match_operand:DI 0 "register_operand" "=d,d")
! 	(eq:DI (match_operand:DI 1 "se_register_operand" "%d,d")
! 	       (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
    "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
    "@
     xor\\t%0,%1,%2\;sltu\\t%0,%0,1
--- 8302,8309 ----
  
  (define_insn "seq_di"
    [(set (match_operand:DI 0 "register_operand" "=d,d")
! 	(eq:DI (match_operand:DI 1 "register_operand" "%d,d")
! 	       (match_operand:DI 2 "uns_arith_operand" "d,K")))]
    "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
    "@
     xor\\t%0,%1,%2\;sltu\\t%0,%0,1
*************** move\\t%0,%z4\\n\\
*** 8328,8335 ****
  
  (define_split
    [(set (match_operand:DI 0 "register_operand" "")
! 	(eq:DI (match_operand:DI 1 "se_register_operand" "")
! 	       (match_operand:DI 2 "se_uns_arith_operand" "")))]
    "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
      && !TARGET_MIPS16
      && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
--- 8314,8321 ----
  
  (define_split
    [(set (match_operand:DI 0 "register_operand" "")
! 	(eq:DI (match_operand:DI 1 "register_operand" "")
! 	       (match_operand:DI 2 "uns_arith_operand" "")))]
    "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
      && !TARGET_MIPS16
      && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
*************** move\\t%0,%z4\\n\\
*** 8380,8386 ****
  
  (define_insn "sne_di_zero"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(ne:DI (match_operand:DI 1 "se_register_operand" "d")
  	       (const_int 0)))]
    "TARGET_64BIT && !TARGET_MIPS16"
    "sltu\\t%0,%.,%1"
--- 8366,8372 ----
  
  (define_insn "sne_di_zero"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(ne:DI (match_operand:DI 1 "register_operand" "d")
  	       (const_int 0)))]
    "TARGET_64BIT && !TARGET_MIPS16"
    "sltu\\t%0,%.,%1"
*************** move\\t%0,%z4\\n\\
*** 8415,8422 ****
  
  (define_insn "sne_di"
    [(set (match_operand:DI 0 "register_operand" "=d,d")
! 	(ne:DI (match_operand:DI 1 "se_register_operand" "%d,d")
! 	       (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
    "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
    "@
      xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
--- 8401,8408 ----
  
  (define_insn "sne_di"
    [(set (match_operand:DI 0 "register_operand" "=d,d")
! 	(ne:DI (match_operand:DI 1 "register_operand" "%d,d")
! 	       (match_operand:DI 2 "uns_arith_operand" "d,K")))]
    "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
    "@
      xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
*************** move\\t%0,%z4\\n\\
*** 8427,8434 ****
  
  (define_split
    [(set (match_operand:DI 0 "register_operand" "")
! 	(ne:DI (match_operand:DI 1 "se_register_operand" "")
! 	       (match_operand:DI 2 "se_uns_arith_operand" "")))]
    "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
      && !TARGET_MIPS16
      && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
--- 8413,8420 ----
  
  (define_split
    [(set (match_operand:DI 0 "register_operand" "")
! 	(ne:DI (match_operand:DI 1 "register_operand" "")
! 	       (match_operand:DI 2 "uns_arith_operand" "")))]
    "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
      && !TARGET_MIPS16
      && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
*************** move\\t%0,%z4\\n\\
*** 8486,8493 ****
  
  (define_insn "sgt_di"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(gt:DI (match_operand:DI 1 "se_register_operand" "d")
! 	       (match_operand:DI 2 "se_reg_or_0_operand" "dJ")))]
    "TARGET_64BIT && !TARGET_MIPS16"
    "slt\\t%0,%z2,%1"
    [(set_attr "type"	"arith")
--- 8472,8479 ----
  
  (define_insn "sgt_di"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(gt:DI (match_operand:DI 1 "register_operand" "d")
! 	       (match_operand:DI 2 "reg_or_0_operand" "dJ")))]
    "TARGET_64BIT && !TARGET_MIPS16"
    "slt\\t%0,%z2,%1"
    [(set_attr "type"	"arith")
*************** move\\t%0,%z4\\n\\
*** 8495,8502 ****
  
  (define_insn ""
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(gt:DI (match_operand:DI 1 "se_register_operand" "d")
! 	       (match_operand:DI 2 "se_register_operand" "d")))]
    "TARGET_64BIT && TARGET_MIPS16"
    "slt\\t%2,%1"
    [(set_attr "type"	"arith")
--- 8481,8488 ----
  
  (define_insn ""
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(gt:DI (match_operand:DI 1 "register_operand" "d")
! 	       (match_operand:DI 2 "register_operand" "d")))]
    "TARGET_64BIT && TARGET_MIPS16"
    "slt\\t%2,%1"
    [(set_attr "type"	"arith")
*************** move\\t%0,%z4\\n\\
*** 8550,8557 ****
  
  (define_insn "sge_di"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(ge:DI (match_operand:DI 1 "se_register_operand" "d")
! 	       (match_operand:DI 2 "se_arith_operand" "dI")))]
    "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
    "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
    [(set_attr "type"	"arith")
--- 8536,8543 ----
  
  (define_insn "sge_di"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(ge:DI (match_operand:DI 1 "register_operand" "d")
! 	       (match_operand:DI 2 "arith_operand" "dI")))]
    "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
    "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
    [(set_attr "type"	"arith")
*************** move\\t%0,%z4\\n\\
*** 8560,8567 ****
  
  (define_split
    [(set (match_operand:DI 0 "register_operand" "")
! 	(ge:DI (match_operand:DI 1 "se_register_operand" "")
! 	       (match_operand:DI 2 "se_arith_operand" "")))]
    "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
     && !TARGET_MIPS16"
    [(set (match_dup 0)
--- 8546,8553 ----
  
  (define_split
    [(set (match_operand:DI 0 "register_operand" "")
! 	(ge:DI (match_operand:DI 1 "register_operand" "")
! 	       (match_operand:DI 2 "arith_operand" "")))]
    "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
     && !TARGET_MIPS16"
    [(set (match_dup 0)
*************** move\\t%0,%z4\\n\\
*** 8620,8627 ****
  
  (define_insn "slt_di"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(lt:DI (match_operand:DI 1 "se_register_operand" "d")
! 	       (match_operand:DI 2 "se_arith_operand" "dI")))]
    "TARGET_64BIT && !TARGET_MIPS16"
    "slt\\t%0,%1,%2"
    [(set_attr "type"	"arith")
--- 8606,8613 ----
  
  (define_insn "slt_di"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(lt:DI (match_operand:DI 1 "register_operand" "d")
! 	       (match_operand:DI 2 "arith_operand" "dI")))]
    "TARGET_64BIT && !TARGET_MIPS16"
    "slt\\t%0,%1,%2"
    [(set_attr "type"	"arith")
*************** move\\t%0,%z4\\n\\
*** 8629,8636 ****
  
  (define_insn ""
    [(set (match_operand:DI 0 "register_operand" "=t,t")
! 	(lt:DI (match_operand:DI 1 "se_register_operand" "d,d")
! 	       (match_operand:DI 2 "se_arith_operand" "d,I")))]
    "TARGET_64BIT && TARGET_MIPS16"
    "slt\\t%1,%2"
    [(set_attr "type"	"arith")
--- 8615,8622 ----
  
  (define_insn ""
    [(set (match_operand:DI 0 "register_operand" "=t,t")
! 	(lt:DI (match_operand:DI 1 "register_operand" "d,d")
! 	       (match_operand:DI 2 "arith_operand" "d,I")))]
    "TARGET_64BIT && TARGET_MIPS16"
    "slt\\t%1,%2"
    [(set_attr "type"	"arith")
*************** move\\t%0,%z4\\n\\
*** 8698,8704 ****
  
  (define_insn "sle_di_const"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(le:DI (match_operand:DI 1 "se_register_operand" "d")
  	       (match_operand:DI 2 "small_int" "I")))]
    "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
    "*
--- 8684,8690 ----
  
  (define_insn "sle_di_const"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(le:DI (match_operand:DI 1 "register_operand" "d")
  	       (match_operand:DI 2 "small_int" "I")))]
    "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
    "*
*************** move\\t%0,%z4\\n\\
*** 8711,8717 ****
  
  (define_insn ""
    [(set (match_operand:DI 0 "register_operand" "=t")
! 	(le:DI (match_operand:DI 1 "se_register_operand" "d")
  	       (match_operand:DI 2 "small_int" "I")))]
    "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
    "*
--- 8697,8703 ----
  
  (define_insn ""
    [(set (match_operand:DI 0 "register_operand" "=t")
! 	(le:DI (match_operand:DI 1 "register_operand" "d")
  	       (match_operand:DI 2 "small_int" "I")))]
    "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
    "*
*************** move\\t%0,%z4\\n\\
*** 8750,8757 ****
  
  (define_insn "sle_di_reg"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(le:DI (match_operand:DI 1 "se_register_operand" "d")
! 	       (match_operand:DI 2 "se_register_operand" "d")))]
    "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
    "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
    [(set_attr "type"	"arith")
--- 8736,8743 ----
  
  (define_insn "sle_di_reg"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(le:DI (match_operand:DI 1 "register_operand" "d")
! 	       (match_operand:DI 2 "register_operand" "d")))]
    "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
    "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
    [(set_attr "type"	"arith")
*************** move\\t%0,%z4\\n\\
*** 8760,8767 ****
  
  (define_split
    [(set (match_operand:DI 0 "register_operand" "")
! 	(le:DI (match_operand:DI 1 "se_register_operand" "")
! 	       (match_operand:DI 2 "se_register_operand" "")))]
    "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
     && !TARGET_MIPS16"
    [(set (match_dup 0)
--- 8746,8753 ----
  
  (define_split
    [(set (match_operand:DI 0 "register_operand" "")
! 	(le:DI (match_operand:DI 1 "register_operand" "")
! 	       (match_operand:DI 2 "register_operand" "")))]
    "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
     && !TARGET_MIPS16"
    [(set (match_dup 0)
*************** move\\t%0,%z4\\n\\
*** 8818,8825 ****
  
  (define_insn "sgtu_di"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(gtu:DI (match_operand:DI 1 "se_register_operand" "d")
! 		(match_operand:DI 2 "se_reg_or_0_operand" "dJ")))]
    "TARGET_64BIT"
    "sltu\\t%0,%z2,%1"
    [(set_attr "type"	"arith")
--- 8804,8811 ----
  
  (define_insn "sgtu_di"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(gtu:DI (match_operand:DI 1 "register_operand" "d")
! 		(match_operand:DI 2 "reg_or_0_operand" "dJ")))]
    "TARGET_64BIT"
    "sltu\\t%0,%z2,%1"
    [(set_attr "type"	"arith")
*************** move\\t%0,%z4\\n\\
*** 8827,8834 ****
  
  (define_insn ""
    [(set (match_operand:DI 0 "register_operand" "=t")
! 	(gtu:DI (match_operand:DI 1 "se_register_operand" "d")
! 		(match_operand:DI 2 "se_register_operand" "d")))]
    "TARGET_64BIT"
    "sltu\\t%2,%1"
    [(set_attr "type"	"arith")
--- 8813,8820 ----
  
  (define_insn ""
    [(set (match_operand:DI 0 "register_operand" "=t")
! 	(gtu:DI (match_operand:DI 1 "register_operand" "d")
! 		(match_operand:DI 2 "register_operand" "d")))]
    "TARGET_64BIT"
    "sltu\\t%2,%1"
    [(set_attr "type"	"arith")
*************** move\\t%0,%z4\\n\\
*** 8882,8889 ****
  
  (define_insn "sgeu_di"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(geu:DI (match_operand:DI 1 "se_register_operand" "d")
! 		(match_operand:DI 2 "se_arith_operand" "dI")))]
    "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
    "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
    [(set_attr "type"	"arith")
--- 8868,8875 ----
  
  (define_insn "sgeu_di"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(geu:DI (match_operand:DI 1 "register_operand" "d")
! 		(match_operand:DI 2 "arith_operand" "dI")))]
    "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
    "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
    [(set_attr "type"	"arith")
*************** move\\t%0,%z4\\n\\
*** 8892,8899 ****
  
  (define_split
    [(set (match_operand:DI 0 "register_operand" "")
! 	(geu:DI (match_operand:DI 1 "se_register_operand" "")
! 		(match_operand:DI 2 "se_arith_operand" "")))]
    "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
     && !TARGET_MIPS16"
    [(set (match_dup 0)
--- 8878,8885 ----
  
  (define_split
    [(set (match_operand:DI 0 "register_operand" "")
! 	(geu:DI (match_operand:DI 1 "register_operand" "")
! 		(match_operand:DI 2 "arith_operand" "")))]
    "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
     && !TARGET_MIPS16"
    [(set (match_dup 0)
*************** move\\t%0,%z4\\n\\
*** 8952,8959 ****
  
  (define_insn "sltu_di"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(ltu:DI (match_operand:DI 1 "se_register_operand" "d")
! 		(match_operand:DI 2 "se_arith_operand" "dI")))]
    "TARGET_64BIT && !TARGET_MIPS16"
    "sltu\\t%0,%1,%2"
    [(set_attr "type"	"arith")
--- 8938,8945 ----
  
  (define_insn "sltu_di"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(ltu:DI (match_operand:DI 1 "register_operand" "d")
! 		(match_operand:DI 2 "arith_operand" "dI")))]
    "TARGET_64BIT && !TARGET_MIPS16"
    "sltu\\t%0,%1,%2"
    [(set_attr "type"	"arith")
*************** move\\t%0,%z4\\n\\
*** 8961,8968 ****
  
  (define_insn ""
    [(set (match_operand:DI 0 "register_operand" "=t,t")
! 	(ltu:DI (match_operand:DI 1 "se_register_operand" "d,d")
! 		(match_operand:DI 2 "se_arith_operand" "d,I")))]
    "TARGET_64BIT && TARGET_MIPS16"
    "sltu\\t%1,%2"
    [(set_attr "type"	"arith")
--- 8947,8954 ----
  
  (define_insn ""
    [(set (match_operand:DI 0 "register_operand" "=t,t")
! 	(ltu:DI (match_operand:DI 1 "register_operand" "d,d")
! 		(match_operand:DI 2 "arith_operand" "d,I")))]
    "TARGET_64BIT && TARGET_MIPS16"
    "sltu\\t%1,%2"
    [(set_attr "type"	"arith")
*************** move\\t%0,%z4\\n\\
*** 9030,9036 ****
  
  (define_insn "sleu_di_const"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(leu:DI (match_operand:DI 1 "se_register_operand" "d")
  		(match_operand:DI 2 "small_int" "I")))]
    "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
    "*
--- 9016,9022 ----
  
  (define_insn "sleu_di_const"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(leu:DI (match_operand:DI 1 "register_operand" "d")
  		(match_operand:DI 2 "small_int" "I")))]
    "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
    "*
*************** move\\t%0,%z4\\n\\
*** 9043,9049 ****
  
  (define_insn ""
    [(set (match_operand:DI 0 "register_operand" "=t")
! 	(leu:DI (match_operand:DI 1 "se_register_operand" "d")
  		(match_operand:DI 2 "small_int" "I")))]
    "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
    "*
--- 9029,9035 ----
  
  (define_insn ""
    [(set (match_operand:DI 0 "register_operand" "=t")
! 	(leu:DI (match_operand:DI 1 "register_operand" "d")
  		(match_operand:DI 2 "small_int" "I")))]
    "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
    "*
*************** move\\t%0,%z4\\n\\
*** 9082,9089 ****
  
  (define_insn "sleu_di_reg"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(leu:DI (match_operand:DI 1 "se_register_operand" "d")
! 		(match_operand:DI 2 "se_register_operand" "d")))]
    "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
    "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
    [(set_attr "type"	"arith")
--- 9068,9075 ----
  
  (define_insn "sleu_di_reg"
    [(set (match_operand:DI 0 "register_operand" "=d")
! 	(leu:DI (match_operand:DI 1 "register_operand" "d")
! 		(match_operand:DI 2 "register_operand" "d")))]
    "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
    "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
    [(set_attr "type"	"arith")
*************** move\\t%0,%z4\\n\\
*** 9092,9099 ****
  
  (define_split
    [(set (match_operand:DI 0 "register_operand" "")
! 	(leu:DI (match_operand:DI 1 "se_register_operand" "")
! 		(match_operand:DI 2 "se_register_operand" "")))]
    "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
     && !TARGET_MIPS16"
    [(set (match_dup 0)
--- 9078,9085 ----
  
  (define_split
    [(set (match_operand:DI 0 "register_operand" "")
! 	(leu:DI (match_operand:DI 1 "register_operand" "")
! 		(match_operand:DI 2 "register_operand" "")))]
    "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
     && !TARGET_MIPS16"
    [(set (match_dup 0)
*************** move\\t%0,%z4\\n\\
*** 9303,9309 ****
     (set_attr "mode"	"none")])
  
  (define_insn "indirect_jump_internal2"
!   [(set (pc) (match_operand:DI 0 "se_register_operand" "d"))]
    "Pmode == DImode"
    "%*j\\t%0"
    [(set_attr "type"	"jump")
--- 9289,9295 ----
     (set_attr "mode"	"none")])
  
  (define_insn "indirect_jump_internal2"
!   [(set (pc) (match_operand:DI 0 "register_operand" "d"))]
    "Pmode == DImode"
    "%*j\\t%0"
    [(set_attr "type"	"jump")
*************** move\\t%0,%z4\\n\\
*** 9362,9368 ****
  
  (define_insn "tablejump_internal2"
    [(set (pc)
! 	(match_operand:DI 0 "se_register_operand" "d"))
     (use (label_ref (match_operand 1 "" "")))]
    "Pmode == DImode"
    "%*j\\t%0"
--- 9348,9354 ----
  
  (define_insn "tablejump_internal2"
    [(set (pc)
! 	(match_operand:DI 0 "register_operand" "d"))
     (use (label_ref (match_operand 1 "" "")))]
    "Pmode == DImode"
    "%*j\\t%0"
*************** move\\t%0,%z4\\n\\
*** 9449,9455 ****
  
  (define_expand "tablejump_internal4"
    [(parallel [(set (pc)
! 		   (plus:DI (match_operand:DI 0 "se_register_operand" "d")
  			    (label_ref:DI (match_operand 1 "" ""))))
  	      (use (label_ref:DI (match_dup 1)))])]
    ""
--- 9435,9441 ----
  
  (define_expand "tablejump_internal4"
    [(parallel [(set (pc)
! 		   (plus:DI (match_operand:DI 0 "register_operand" "d")
  			    (label_ref:DI (match_operand 1 "" ""))))
  	      (use (label_ref:DI (match_dup 1)))])]
    ""
*************** move\\t%0,%z4\\n\\
*** 9461,9467 ****
  
  (define_insn ""
    [(set (pc)
! 	(plus:DI (match_operand:DI 0 "se_register_operand" "d")
  		 (label_ref:DI (match_operand 1 "" ""))))
     (use (label_ref:DI (match_dup 1)))]
    "Pmode == DImode && next_active_insn (insn) != 0
--- 9447,9453 ----
  
  (define_insn ""
    [(set (pc)
! 	(plus:DI (match_operand:DI 0 "register_operand" "d")
  		 (label_ref:DI (match_operand 1 "" ""))))
     (use (label_ref:DI (match_dup 1)))]
    "Pmode == DImode && next_active_insn (insn) != 0
*************** ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n
*** 9928,9934 ****
     (set_attr "mode"	"none")])
  
  (define_insn "call_internal3b"
!   [(call (mem:DI (match_operand:DI 0 "se_register_operand" "r"))
  	 (match_operand 1 "" "i"))
     (clobber (match_operand:SI 2 "register_operand" "=d"))]
    "!TARGET_MIPS16
--- 9914,9920 ----
     (set_attr "mode"	"none")])
  
  (define_insn "call_internal3b"
!   [(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
  	 (match_operand 1 "" "i"))
     (clobber (match_operand:SI 2 "register_operand" "=d"))]
    "!TARGET_MIPS16
*************** ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n
*** 9965,9971 ****
     (set_attr "length"	"8")])
  
  (define_insn "call_internal4b"
!   [(call (mem:DI (match_operand:DI 0 "se_register_operand" "r"))
  	 (match_operand 1 "" "i"))
     (clobber (match_operand:SI 2 "register_operand" "=d"))]
    "Pmode == DImode && TARGET_ABICALLS && TARGET_LONG_CALLS"
--- 9951,9957 ----
     (set_attr "length"	"8")])
  
  (define_insn "call_internal4b"
!   [(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
  	 (match_operand 1 "" "i"))
     (clobber (match_operand:SI 2 "register_operand" "=d"))]
    "Pmode == DImode && TARGET_ABICALLS && TARGET_LONG_CALLS"
*************** ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n
*** 10138,10144 ****
  
  (define_insn "call_value_internal3b"
    [(set (match_operand 0 "register_operand" "=df")
!         (call (mem:DI (match_operand:DI 1 "se_register_operand" "r"))
  	      (match_operand 2 "" "i")))
     (clobber (match_operand:SI 3 "register_operand" "=d"))]
    "!TARGET_MIPS16
--- 10124,10130 ----
  
  (define_insn "call_value_internal3b"
    [(set (match_operand 0 "register_operand" "=df")
!         (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
  	      (match_operand 2 "" "i")))
     (clobber (match_operand:SI 3 "register_operand" "=d"))]
    "!TARGET_MIPS16
*************** ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n
*** 10177,10183 ****
  
  (define_insn "call_value_internal4b"
    [(set (match_operand 0 "register_operand" "=df")
!         (call (mem:DI (match_operand:DI 1 "se_register_operand" "r"))
  	      (match_operand 2 "" "i")))
     (clobber (match_operand:SI 3 "register_operand" "=d"))]
    "Pmode == DImode && TARGET_ABICALLS && TARGET_LONG_CALLS"
--- 10163,10169 ----
  
  (define_insn "call_value_internal4b"
    [(set (match_operand 0 "register_operand" "=df")
!         (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
  	      (match_operand 2 "" "i")))
     (clobber (match_operand:SI 3 "register_operand" "=d"))]
    "Pmode == DImode && TARGET_ABICALLS && TARGET_LONG_CALLS"
*************** ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n
*** 10341,10347 ****
    [(set (match_operand:SI 0 "register_operand" "=d,d")
  	(if_then_else:SI
  	 (match_operator 4 "equality_op"
! 			 [(match_operand:DI 1 "se_register_operand" "d,d")
  			  (const_int 0)])
  	 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
  	 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
--- 10327,10333 ----
    [(set (match_operand:SI 0 "register_operand" "=d,d")
  	(if_then_else:SI
  	 (match_operator 4 "equality_op"
! 			 [(match_operand:DI 1 "register_operand" "d,d")
  			  (const_int 0)])
  	 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
  	 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
*************** ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n
*** 10374,10381 ****
  	 (match_operator 4 "equality_op"
  			 [(match_operand:SI 1 "register_operand" "d,d")
  			  (const_int 0)])
! 	 (match_operand:DI 2 "se_reg_or_0_operand" "dJ,0")
! 	 (match_operand:DI 3 "se_reg_or_0_operand" "0,dJ")))]
    "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
    "@
      mov%B4\\t%0,%z2,%1
--- 10360,10367 ----
  	 (match_operator 4 "equality_op"
  			 [(match_operand:SI 1 "register_operand" "d,d")
  			  (const_int 0)])
! 	 (match_operand:DI 2 "reg_or_0_operand" "dJ,0")
! 	 (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))]
    "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
    "@
      mov%B4\\t%0,%z2,%1
*************** ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n
*** 10387,10396 ****
    [(set (match_operand:DI 0 "register_operand" "=d,d")
  	(if_then_else:DI
  	 (match_operator 4 "equality_op"
! 			 [(match_operand:DI 1 "se_register_operand" "d,d")
  			  (const_int 0)])
! 	 (match_operand:DI 2 "se_reg_or_0_operand" "dJ,0")
! 	 (match_operand:DI 3 "se_reg_or_0_operand" "0,dJ")))]
    "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
    "@
      mov%B4\\t%0,%z2,%1
--- 10373,10382 ----
    [(set (match_operand:DI 0 "register_operand" "=d,d")
  	(if_then_else:DI
  	 (match_operator 4 "equality_op"
! 			 [(match_operand:DI 1 "register_operand" "d,d")
  			  (const_int 0)])
! 	 (match_operand:DI 2 "reg_or_0_operand" "dJ,0")
! 	 (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))]
    "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
    "@
      mov%B4\\t%0,%z2,%1
*************** ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n
*** 10405,10412 ****
  							    "register_operand"
  							    "z,z")
  					  (const_int 0)])
! 	 (match_operand:DI 1 "se_reg_or_0_operand" "dJ,0")
! 	 (match_operand:DI 2 "se_reg_or_0_operand" "0,dJ")))]
    "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_64BIT"
    "@
      mov%T3\\t%0,%z1,%4
--- 10391,10398 ----
  							    "register_operand"
  							    "z,z")
  					  (const_int 0)])
! 	 (match_operand:DI 1 "reg_or_0_operand" "dJ,0")
! 	 (match_operand:DI 2 "reg_or_0_operand" "0,dJ")))]
    "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_64BIT"
    "@
      mov%T3\\t%0,%z1,%4
*************** ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n
*** 10433,10439 ****
    [(set (match_operand:SF 0 "register_operand" "=f,f")
  	(if_then_else:SF
  	 (match_operator 4 "equality_op"
! 			 [(match_operand:DI 1 "se_register_operand" "d,d")
  			  (const_int 0)])
  	 (match_operand:SF 2 "register_operand" "f,0")
  	 (match_operand:SF 3 "register_operand" "0,f")))]
--- 10419,10425 ----
    [(set (match_operand:SF 0 "register_operand" "=f,f")
  	(if_then_else:SF
  	 (match_operator 4 "equality_op"
! 			 [(match_operand:DI 1 "register_operand" "d,d")
  			  (const_int 0)])
  	 (match_operand:SF 2 "register_operand" "f,0")
  	 (match_operand:SF 3 "register_operand" "0,f")))]
*************** ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n
*** 10479,10485 ****
    [(set (match_operand:DF 0 "register_operand" "=f,f")
  	(if_then_else:DF
  	 (match_operator 4 "equality_op"
! 			 [(match_operand:DI 1 "se_register_operand" "d,d")
  			  (const_int 0)])
  	 (match_operand:DF 2 "register_operand" "f,0")
  	 (match_operand:DF 3 "register_operand" "0,f")))]
--- 10465,10471 ----
    [(set (match_operand:DF 0 "register_operand" "=f,f")
  	(if_then_else:DF
  	 (match_operator 4 "equality_op"
! 			 [(match_operand:DI 1 "register_operand" "d,d")
  			  (const_int 0)])
  	 (match_operand:DF 2 "register_operand" "f,0")
  	 (match_operand:DF 3 "register_operand" "0,f")))]
*************** ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n
*** 10525,10532 ****
    [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
     (set (match_operand:DI 0 "register_operand" "")
  	(if_then_else:DI (match_dup 5)
! 			 (match_operand:DI 2 "se_reg_or_0_operand" "")
! 			 (match_operand:DI 3 "se_reg_or_0_operand" "")))]
    "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
    "
  {
--- 10511,10518 ----
    [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
     (set (match_operand:DI 0 "register_operand" "")
  	(if_then_else:DI (match_dup 5)
! 			 (match_operand:DI 2 "reg_or_0_operand" "")
! 			 (match_operand:DI 3 "reg_or_0_operand" "")))]
    "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
    "
  {



More information about the Gcc-patches mailing list