Mips instruction hazards (parts 3&4/4)

Richard Sandiford rsandifo@redhat.com
Sat Jun 28 19:03:00 GMT 2003


Richard Sandiford <rsandifo@redhat.com> writes:
> This patch adds a hazard-avoidance pass to the mips port.

Here's a revised version.  As per the mdr2 thread, it calls
dbr_schedule from within mips_reorg rather than using a second
target hook.

Tested on mips-sgi-irix6.5, mips64vrel-elf, mipsisa64-elf
and mipsel-linux-gnu.  OK to install?

Richard


	* config/mips/mips.c (machine_function): Add new fields:
	ignore_hazard_length_p and all_noreorder_p.
	(mips_flag_delayed_branch): New variable.
	(override_options): Treat '/' as an operand punctuation character.
	Set up mips_flag_delayed_branch.
	(print_operand): Handle '/'.
	(mips_output_function_prologue): Put the whole function in
	.set noreorder and .set nomacro if all_noreorder_p is true.
	(mips_output_function_epilogue): End the noreorder/nomacro sequence.
	(mips16_optimize_gp): Remove "first insn" parameter.
	(mips16_lay_out_constants): New function, split out from mips_reorg.
	(mips_avoid_hazard, mips_avoid_hazards): New functions.
	(mips_reorg): For mips16 code, call mips16_lay_out_constant
	and (optionally) mips16_optimize.  If TARGET_EXPLICIT_RELOCS,
	do delayed-branch scheduling followed by hazard detection.
	(mips_adjust_insn_length): Only account for hazards if
	!ignore_hazard_length_p.
	(mips_output_load_label): Add a nop to the o32 sequence if
	the target suffers from load delays.
	(mips_output_conditional_branch): Add %/ to the end of branches.
	(mips_output_division): Fill the branch delay slot with %#.
	* config/mips/mips.md: Remove redundant '%*' from mips16 branch
	instructions.  End all other %* branches with %/.
	(ffssi2, ffsdi2): Fix lengths.
	(truncdisi2, truncdihi2, truncdiqi2): Add store attributes.
	(fix_truncdfsi2_macro): Turn off .set nomacro if appropriate.
	(fix_truncsfsi2_macro): Likewise.
	(mov_lwl): Set hazard to "none".
	(ashldi3_internal): Fill the branch delay slot with %#.
	(ashrdi3_internal, lshrdi3_internal): Likewise.
	(exception_receiver): Explicitly set $28.
	(hazard_nop): New pattern.

Index: config/mips/mips.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.c,v
retrieving revision 1.283
diff -u -d -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.283 mips.c
--- config/mips/mips.c	19 Jun 2003 21:47:16 -0000	1.283
+++ config/mips/mips.c	27 Jun 2003 19:22:11 -0000
@@ -243,13 +243,17 @@ static void save_restore_insns			PARAMS 
 static void mips_gp_insn			PARAMS ((rtx, rtx));
 static void mips16_fp_args			PARAMS ((FILE *, int, int));
 static void build_mips16_function_stub		PARAMS ((FILE *));
-static void mips16_optimize_gp			PARAMS ((rtx));
+static void mips16_optimize_gp			PARAMS ((void));
 static rtx add_constant				PARAMS ((struct constant **,
 							rtx,
 							enum machine_mode));
 static void dump_constants			PARAMS ((struct constant *,
 							rtx));
 static rtx mips_find_symbol			PARAMS ((rtx));
+static void mips16_lay_out_constants		PARAMS ((void));
+static void mips_avoid_hazard			PARAMS ((rtx, rtx, int *,
+							 rtx *, rtx));
+static void mips_avoid_hazards			PARAMS ((void));
 static void mips_reorg				PARAMS ((void));
 static void abort_with_insn			PARAMS ((rtx, const char *))
   ATTRIBUTE_NORETURN;
@@ -335,6 +339,14 @@ struct machine_function GTY(()) {
 
   /* The register to use as the global pointer within this function.  */
   unsigned int global_pointer;
+
+  /* True if mips_adjust_insn_length should ignore an instruction's
+     hazard attribute.  */
+  bool ignore_hazard_length_p;
+
+  /* True if the whole function is suitable for .set noreorder and
+     .set nomacro.  */
+  bool all_noreorder_p;
 };
 
 /* Information about a single argument.  */
@@ -585,6 +597,9 @@ int mips_dbx_regno[FIRST_PSEUDO_REGISTER
 /* An alias set for the GOT.  */
 static int mips_got_alias_set;
 
+/* A copy of the original flag_delayed_branch: see override_options.  */
+static int mips_flag_delayed_branch;
+
 static GTY (()) int mips_output_filename_first_time = 1;
 
 /* Hardware names for the registers.  If -mrnames is used, this
@@ -5145,6 +5160,14 @@ override_options ()
   else
     mips16 = 0;
 
+  /* When using explicit relocs, we call dbr_schedule from within
+     mips_reorg.  */
+  if (TARGET_EXPLICIT_RELOCS)
+    {
+      mips_flag_delayed_branch = flag_delayed_branch;
+      flag_delayed_branch = 0;
+    }
+
   real_format_for_mode[SFmode - QFmode] = &mips_single_format;
   real_format_for_mode[DFmode - QFmode] = &mips_double_format;
 #ifdef MIPS_TFMODE_FORMAT
@@ -5155,6 +5178,7 @@ override_options ()
 
   mips_print_operand_punct['?'] = 1;
   mips_print_operand_punct['#'] = 1;
+  mips_print_operand_punct['/'] = 1;
   mips_print_operand_punct['&'] = 1;
   mips_print_operand_punct['!'] = 1;
   mips_print_operand_punct['*'] = 1;
@@ -5470,6 +5494,7 @@ mips_debugger_offset (addr, offset)
    '*'	Turn on both .set noreorder and .set nomacro if filling delay slots
    '!'	Turn on .set nomacro if filling delay slots
    '#'	Print nop if in a .set noreorder section.
+   '/'	Like '#', but does nothing within a delayed branch sequence
    '?'	Print 'l' if we are to use a branch likely instead of normal branch.
    '@'	Print the name of the assembler temporary register (at or $1).
    '.'	Print the name of the register with a hard-wired zero (zero or $0).
@@ -5543,6 +5568,14 @@ print_operand (file, op, letter)
 	    fputs ("\n\tnop", file);
 	  break;
 
+	case '/':
+	  /* Print an extra newline so that the delayed insn is separated
+	     from the following ones.  This looks neater and is consistent
+	     with non-nop delayed sequences.  */
+	  if (set_noreorder != 0 && final_sequence == 0)
+	    fputs ("\n\tnop\n", file);
+	  break;
+
 	case '(':
 	  if (set_noreorder++ == 0)
 	    fputs (".set\tnoreorder\n\t", file);
@@ -7065,10 +7098,16 @@ mips_output_function_prologue (file, siz
       fprintf (file, "\n");
     }
 
-  /* Handle the initialization of $gp for SVR4 PIC.  */
   if (TARGET_ABICALLS && !TARGET_NEWABI && cfun->machine->global_pointer > 0)
-    fprintf (file, "\t.set\tnoreorder\n\t.cpload\t%s\n\t.set\treorder\n",
-	     reg_names[PIC_FUNCTION_ADDR_REGNUM]);
+    {
+      /* Handle the initialization of $gp for SVR4 PIC.  */
+      if (!cfun->machine->all_noreorder_p)
+	output_asm_insn ("%(.cpload\t%^%)", 0);
+      else
+	output_asm_insn ("%(.cpload\t%^\n\t%<", 0);
+    }
+  else if (cfun->machine->all_noreorder_p)
+    output_asm_insn ("%(%<", 0);
 }
 
 /* Emit an instruction to move SRC into DEST.  When generating
@@ -7479,6 +7518,14 @@ mips_output_function_epilogue (file, siz
 {
   rtx string;
 
+  if (cfun->machine->all_noreorder_p)
+    {
+      /* Avoid using %>%) since it adds excess whitespace.  */
+      output_asm_insn (".set\tmacro", 0);
+      output_asm_insn (".set\treorder", 0);
+      set_noreorder = set_nomacro = 0;
+    }
+
 #ifndef FUNCTION_NAME_ALREADY_DECLARED
   if (!flag_inhibit_size_directive)
     {
@@ -8885,8 +8932,7 @@ build_mips16_call_stub (retval, fn, arg_
    generated is correct, so we do not need to catch all cases.  */
 
 static void
-mips16_optimize_gp (first)
-     rtx first;
+mips16_optimize_gp ()
 {
   rtx gpcopy, slot, insn;
 
@@ -8899,7 +8945,7 @@ mips16_optimize_gp (first)
 
   gpcopy = NULL_RTX;
   slot = NULL_RTX;
-  for (insn = first; insn != NULL_RTX; insn = next_active_insn (insn))
+  for (insn = get_insns (); insn != NULL_RTX; insn = next_active_insn (insn))
     {
       rtx set;
 
@@ -8982,7 +9028,7 @@ mips16_optimize_gp (first)
 
 #if 0
   /* ??? FIXME.  Rewrite for new UNSPEC_RELOC stuff.  */
-      for (insn = first; insn != NULL_RTX; insn = next)
+      for (insn = get_insns (); insn != NULL_RTX; insn = next)
 	{
 	  rtx set1, set2;
 
@@ -9051,7 +9097,7 @@ mips16_optimize_gp (first)
      replace all assignments from SLOT to GPCOPY with assignments from
      $28.  */
 
-  for (insn = first; insn != NULL_RTX; insn = next_active_insn (insn))
+  for (insn = get_insns (); insn != NULL_RTX; insn = next_active_insn (insn))
     {
       rtx set;
 
@@ -9228,22 +9274,14 @@ mips_find_symbol (addr)
    PC relative loads that are out of range.  */
 
 static void
-mips_reorg ()
+mips16_lay_out_constants ()
 {
   int insns_len, max_internal_pool_size, pool_size, addr, first_constant_ref;
   rtx first, insn;
   struct constant *constants;
 
-  if (! TARGET_MIPS16)
-    return;
-
   first = get_insns ();
 
-  /* If $gp is used, try to remove stores, and replace loads with
-     copies from $gp.  */
-  if (optimize)
-    mips16_optimize_gp (first);
-
   /* Scan the function looking for PC relative loads which may be out
      of range.  All such loads will either be from the constant table,
      or be getting the address of a constant string.  If the size of
@@ -9428,6 +9466,144 @@ mips_reorg ()
      constant table, but we have no way to prevent that.  */
 }
 
+
+/* Subroutine of mips_reorg.  If there is a hazard between INSN
+   and a previous instruction, avoid it by inserting nops after
+   instruction AFTER.
+
+   *DELAYED_REG and *HILO_DELAY describe the hazards that apply at
+   this point.  If *DELAYED_REG is non-null, INSN must wait a cycle
+   before using the value of that register.  *HILO_DELAY counts the
+   number of instructions since the last hilo hazard (that is,
+   the number of instructions since the last mflo or mfhi).
+
+   After inserting nops for INSN, update *DELAYED_REG and *HILO_DELAY
+   for the next instruction.
+
+   LO_REG is an rtx for the LO register, used in dependence checking.  */
+
+static void
+mips_avoid_hazard (after, insn, hilo_delay, delayed_reg, lo_reg)
+     rtx after, insn, *delayed_reg, lo_reg;
+     int *hilo_delay;
+{
+  rtx pattern, set;
+  int nops, ninsns;
+
+  if (!INSN_P (insn))
+    return;
+
+  pattern = PATTERN (insn);
+
+  /* Do not put the whole function in .set noreorder if it contains
+     an asm statement.  We don't know whether there will be hazards
+     between the asm statement and the gcc-generated code.  */
+  if (GET_CODE (pattern) == ASM_INPUT || asm_noperands (pattern) >= 0)
+    cfun->machine->all_noreorder_p = false;
+
+  /* Ignore zero-length instructions (barriers and the like).  */
+  ninsns = get_attr_length (insn) / 4;
+  if (ninsns == 0)
+    return;
+
+  /* Work out how many nops are needed.  Note that we only care about
+     registers that are explicitly mentioned in the instruction's pattern.
+     It doesn't matter that calls use the argument registers or that they
+     clobber hi and lo.  */
+  if (*hilo_delay < 2 && reg_set_p (lo_reg, pattern))
+    nops = 2 - *hilo_delay;
+  else if (*delayed_reg != 0 && reg_referenced_p (*delayed_reg, pattern))
+    nops = 1;
+  else
+    nops = 0;
+
+  /* Insert the nops between this instruction and the previous one.
+     Each new nop takes us further from the last hilo hazard.  */
+  *hilo_delay += nops;
+  while (nops-- > 0)
+    emit_insn_after (gen_hazard_nop (), after);
+
+  /* Set up the state for the next instruction.  */
+  *hilo_delay += ninsns;
+  *delayed_reg = 0;
+  if (INSN_CODE (insn) >= 0)
+    switch (get_attr_hazard (insn))
+      {
+      case HAZARD_NONE:
+	break;
+
+      case HAZARD_HILO:
+	*hilo_delay = 0;
+	break;
+
+      case HAZARD_DELAY:
+	set = single_set (insn);
+	if (set == 0)
+	  abort ();
+	*delayed_reg = SET_DEST (set);
+	break;
+      }
+}
+
+
+/* Go through the instruction stream and insert nops where necessary.
+   See if the whole function can then be put into .set noreorder &
+   .set nomacro.  */
+
+static void
+mips_avoid_hazards ()
+{
+  rtx insn, last_insn, lo_reg, delayed_reg;
+  int hilo_delay, i;
+
+  /* Recalculate instruction lengths without taking nops into account.  */
+  cfun->machine->ignore_hazard_length_p = true;
+  shorten_branches (get_insns ());
+
+  /* The profiler code uses assembler macros.  */
+  cfun->machine->all_noreorder_p = !current_function_profile;
+
+  last_insn = 0;
+  hilo_delay = 2;
+  delayed_reg = 0;
+  lo_reg = gen_rtx_REG (SImode, LO_REGNUM);
+
+  for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
+    if (INSN_P (insn))
+      {
+	if (GET_CODE (PATTERN (insn)) == SEQUENCE)
+	  for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
+	    mips_avoid_hazard (last_insn, XVECEXP (PATTERN (insn), 0, i),
+			       &hilo_delay, &delayed_reg, lo_reg);
+	else
+	  mips_avoid_hazard (last_insn, insn, &hilo_delay,
+			     &delayed_reg, lo_reg);
+
+	last_insn = insn;
+      }
+}
+
+
+/* Implement TARGET_MACHINE_DEPENDENT_REORG.  */
+
+static void
+mips_reorg ()
+{
+  if (TARGET_MIPS16)
+    {
+      if (optimize)
+	mips16_optimize_gp ();
+      mips16_lay_out_constants ();
+    }
+  else if (TARGET_EXPLICIT_RELOCS)
+    {
+      if (mips_flag_delayed_branch)
+	dbr_schedule (get_insns (), rtl_dump_file);
+      mips_avoid_hazards ();
+    }
+}
+
+
 /* Return a number assessing the cost of moving a register in class
    FROM to class TO.  The classes are expressed using the enumeration
    values such as `GENERAL_REGS'.  A value of 2 is the default; other
@@ -9543,7 +9719,7 @@ mips_adjust_insn_length (insn, length)
     length += 4;
 
   /* See how many nops might be needed to avoid hardware hazards.  */
-  if (INSN_CODE (insn) >= 0)
+  if (!cfun->machine->ignore_hazard_length_p && INSN_CODE (insn) >= 0)
     switch (get_attr_hazard (insn))
       {
       case HAZARD_NONE:
@@ -9582,6 +9758,8 @@ mips_output_load_label ()
 	return "%[ld\t%@,%%got_page(%0)(%+)\n\tdaddiu\t%@,%@,%%got_ofst(%0)";
 
       default:
+	if (ISA_HAS_LOAD_DELAY)
+	  return "%[lw\t%@,%%got(%0)(%+)%#\n\taddiu\t%@,%@,%%lo(%0)";
 	return "%[lw\t%@,%%got(%0)(%+)\n\taddiu\t%@,%@,%%lo(%0)";
       }
   else
@@ -9701,10 +9879,10 @@ mips_output_conditional_branch (insn,
     case 8:
       /* Just a simple conditional branch.  */
       if (float_p)
-	sprintf (buffer, "%%*b%s%%?\t%%Z2%%1",
+	sprintf (buffer, "%%*b%s%%?\t%%Z2%%1%%/",
 		 inverted_p ? inverted_comp : comp);
       else
-	sprintf (buffer, "%%*b%s%s%%?\t%s%s,%%1",
+	sprintf (buffer, "%%*b%s%s%%?\t%s%s,%%1%%/",
 		 inverted_p ? inverted_comp : comp,
 		 need_z_p ? "z" : "",
 		 op1,
@@ -9922,7 +10100,7 @@ mips_output_division (division, operands
       if (TARGET_MIPS16)
 	return "bnez\t%2,1f\n\tbreak\t7\n1:";
       else
-	return "bne\t%2,%.,1f\n\t%#break\t7\n1:";
+	return "bne\t%2,%.,1f%#\n\tbreak\t7\n1:";
     }
   return division;
 }
Index: config/mips/mips.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.md,v
retrieving revision 1.177
diff -u -d -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.177 mips.md
--- config/mips/mips.md	17 Jun 2003 20:50:41 -0000	1.177
+++ config/mips/mips.md	27 Jun 2003 19:22:12 -0000
@@ -3040,7 +3040,7 @@ move\\t%0,%z4\\n\\
 }"
   [(set_attr "type"	"multi")
    (set_attr "mode"	"SI")
-   (set_attr "length"	"12")])
+   (set_attr "length"	"28")])
 
 (define_insn "ffsdi2"
   [(set (match_operand:DI 0 "register_operand" "=&d")
@@ -3074,7 +3074,7 @@ move\\t%0,%z4\\n\\
 }"
   [(set_attr "type"	"multi")
    (set_attr "mode"	"DI")
-   (set_attr "length"	"24")])
+   (set_attr "length"	"28")])
 
 
 
@@ -3489,7 +3489,7 @@ (define_insn "truncdisi2"
   "@
     sll\t%0,%1,0
     sw\t%1,%0"
-  [(set_attr "type" "darith")
+  [(set_attr "type" "darith,store")
    (set_attr "mode" "SI")
    (set_attr "extended_mips16" "yes,*")])
 
@@ -3500,7 +3500,7 @@ (define_insn "truncdihi2"
   "@
     sll\t%0,%1,0
     sh\t%1,%0"
-  [(set_attr "type" "darith")
+  [(set_attr "type" "darith,store")
    (set_attr "mode" "SI")
    (set_attr "extended_mips16" "yes,*")])
 
@@ -3511,7 +3511,7 @@ (define_insn "truncdiqi2"
   "@
     sll\t%0,%1,0
     sb\t%1,%0"
-  [(set_attr "type" "darith")
+  [(set_attr "type" "darith,store")
    (set_attr "mode" "SI")
    (set_attr "extended_mips16" "yes,*")])
 
@@ -4075,7 +4075,11 @@ (define_insn "fix_truncdfsi2_macro"
 	(fix:SI (match_operand:DF 1 "register_operand" "f")))
    (clobber (match_scratch:DF 2 "=d"))]
   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
-  "trunc.w.d %0,%1,%2"
+  {
+    if (set_nomacro)
+      return ".set\tmacro\n\ttrunc.w.d %0,%1,%2\n\t.set\tmacro";
+    return "trunc.w.d %0,%1,%2";
+  }
   [(set_attr "type"	"fcvt")
    (set_attr "mode"	"DF")
    (set_attr "length"	"36")])
@@ -4106,7 +4110,11 @@ (define_insn "fix_truncsfsi2_macro"
 	(fix:SI (match_operand:SF 1 "register_operand" "f")))
    (clobber (match_scratch:SF 2 "=d"))]
   "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
-  "trunc.w.s %0,%1,%2"
+  {
+    if (set_nomacro)
+      return ".set\tmacro\n\ttrunc.w.s %0,%1,%2\n\t.set\tmacro";
+    return "trunc.w.s %0,%1,%2";
+  }
   [(set_attr "type"	"fcvt")
    (set_attr "mode"	"DF")
    (set_attr "length"	"36")])
@@ -4437,7 +4445,8 @@ (define_insn "mov_lwl"
   "!TARGET_MIPS16"
   "lwl\t%0,%2"
   [(set_attr "type" "load")
-   (set_attr "mode" "SI")])
+   (set_attr "mode" "SI")
+   (set_attr "hazard" "none")])
 
 (define_insn "mov_lwr"
   [(set (match_operand:SI 0 "register_operand" "=d")
@@ -5636,7 +5645,7 @@ (define_insn "ashldi3_internal"
   operands[4] = const0_rtx;
 
   return \"sll\\t%3,%2,26\\n\\
-\\tbgez\\t%3,1f\\n\\
+\\tbgez\\t%3,1f%#\\n\\
 \\tsll\\t%M0,%L1,%2\\n\\
 \\t%(b\\t3f\\n\\
 \\tmove\\t%L0,%z4%)\\n\\
@@ -5991,7 +6000,7 @@ (define_insn "ashrdi3_internal"
   operands[4] = const0_rtx;
 
   return \"sll\\t%3,%2,26\\n\\
-\\tbgez\\t%3,1f\\n\\
+\\tbgez\\t%3,1f%#\\n\\
 \\tsra\\t%L0,%M1,%2\\n\\
 \\t%(b\\t3f\\n\\
 \\tsra\\t%M0,%M1,31%)\\n\\
@@ -6369,7 +6378,7 @@ (define_insn "lshrdi3_internal"
   operands[4] = const0_rtx;
 
   return \"sll\\t%3,%2,26\\n\\
-\\tbgez\\t%3,1f\\n\\
+\\tbgez\\t%3,1f%#\\n\\
 \\tsrl\\t%L0,%M1,%2\\n\\
 \\t%(b\\t3f\\n\\
 \\tmove\\t%M0,%z4%)\\n\\
@@ -6988,16 +6997,16 @@ (define_insn ""
   if (operands[2] != pc_rtx)
     {
       if (which_alternative == 0)
-	return \"%*b%C0z\\t%1,%2\";
+	return \"b%C0z\\t%1,%2\";
       else
-	return \"%*bt%C0z\\t%2\";
+	return \"bt%C0z\\t%2\";
     }
   else
     {
       if (which_alternative == 0)
-	return \"%*b%N0z\\t%1,%3\";
+	return \"b%N0z\\t%1,%3\";
       else
-	return \"%*bt%N0z\\t%3\";
+	return \"bt%N0z\\t%3\";
     }
 }"
   [(set_attr "type"	"branch")
@@ -7017,16 +7026,16 @@ (define_insn ""
   if (operands[2] != pc_rtx)
     {
       if (which_alternative == 0)
-	return \"%*b%C0z\\t%1,%2\";
+	return \"b%C0z\\t%1,%2\";
       else
-	return \"%*bt%C0z\\t%2\";
+	return \"bt%C0z\\t%2\";
     }
   else
     {
       if (which_alternative == 0)
-	return \"%*b%N0z\\t%1,%3\";
+	return \"b%N0z\\t%1,%3\";
       else
-	return \"%*bt%N0z\\t%3\";
+	return \"bt%N0z\\t%3\";
     }
 }"
   [(set_attr "type"	"branch")
@@ -8389,15 +8398,15 @@ (define_insn "jump"
   if (flag_pic && ! TARGET_EMBEDDED_PIC)
     {
       if (get_attr_length (insn) <= 8)
-	return \"%*b\\t%l0\";
+	return \"%*b\\t%l0%/\";
       else
 	{
 	  output_asm_insn (mips_output_load_label (), operands);
-	  return \"%*jr\\t%@%]\";
+	  return \"%*jr\\t%@%/%]\";
 	}
     }
   else
-    return \"%*j\\t%l0\";
+    return \"%*j\\t%l0%/\";
 }"
   [(set_attr "type"	"jump")
    (set_attr "mode"	"none")
@@ -8450,14 +8459,14 @@ (define_expand "indirect_jump"
 (define_insn "indirect_jump_internal1"
   [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
   "!(Pmode == DImode)"
-  "%*j\\t%0"
+  "%*j\t%0%/"
   [(set_attr "type"	"jump")
    (set_attr "mode"	"none")])
 
 (define_insn "indirect_jump_internal2"
   [(set (pc) (match_operand:DI 0 "register_operand" "d"))]
   "Pmode == DImode"
-  "%*j\\t%0"
+  "%*j\t%0%/"
   [(set_attr "type"	"jump")
    (set_attr "mode"	"none")])
 
@@ -8501,7 +8510,7 @@ (define_insn "tablejump_internal1"
 	(match_operand:SI 0 "register_operand" "d"))
    (use (label_ref (match_operand 1 "" "")))]
   ""
-  "%*j\\t%0"
+  "%*j\t%0%/"
   [(set_attr "type"	"jump")
    (set_attr "mode"	"none")])
 
@@ -8510,7 +8519,7 @@ (define_insn "tablejump_internal2"
 	(match_operand:DI 0 "register_operand" "d"))
    (use (label_ref (match_operand 1 "" "")))]
   "TARGET_64BIT"
-  "%*j\\t%0"
+  "%*j\t%0%/"
   [(set_attr "type"	"jump")
    (set_attr "mode"	"none")])
 
@@ -8626,7 +8635,7 @@ (define_insn "casesi_internal"
    (clobber (reg:SI 31))]
   "TARGET_EMBEDDED_PIC"
   "%(bal\\t%S1\;sll\\t%2,%0,2\\n%~%S1:\;addu\\t%2,%2,$31%)\;\\
-lw\\t%2,%1-%S1(%2)\;addu\\t%2,%2,$31\\n\\t%*j\\t%2"
+lw\\t%2,%1-%S1(%2)\;addu\\t%2,%2,$31\\n\\t%*j\\t%2%/"
   [(set_attr "type"	"jump")
    (set_attr "mode"	"none")
    (set_attr "length"	"24")])
@@ -8643,7 +8652,7 @@ (define_insn "casesi_internal_di"
    (clobber (reg:DI 31))]
   "TARGET_EMBEDDED_PIC"
   "%(bal\\t%S1\;sll\\t%2,%0,3\\n%~%S1:\;daddu\\t%2,%2,$31%)\;\\
-ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2"
+ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2%/"
   [(set_attr "type"	"jump")
    (set_attr "mode"	"none")
    (set_attr "length"	"24")])
@@ -8751,7 +8760,7 @@ (define_expand "sibcall_epilogue"
 (define_insn "return"
   [(return)]
   "mips_can_use_return_insn ()"
-  "%*j\\t$31"
+  "%*j\t$31%/"
   [(set_attr "type"	"jump")
    (set_attr "mode"	"none")])
 
@@ -8761,10 +8770,7 @@ (define_insn "return_internal"
   [(use (match_operand 0 "pmode_register_operand" ""))
    (return)]
   ""
-  "*
-{
-  return \"%*j\\t%0\";
-}"
+  "%*j\t%0%/"
   [(set_attr "type"	"jump")
    (set_attr "mode"	"none")])
 
@@ -8827,7 +8833,8 @@ (define_split
 }")
 
 (define_insn "exception_receiver"
-  [(unspec_volatile [(const_int 0)] UNSPEC_EH_RECEIVER)]
+  [(set (reg:SI 28)
+	(unspec_volatile [(const_int 0)] UNSPEC_EH_RECEIVER))]
   "TARGET_ABICALLS && (mips_abi == ABI_32 || mips_abi == ABI_O64)"
   { return mips_restore_gp (operands); }
   [(set_attr "type"   "load")
@@ -8867,8 +8874,8 @@ (define_insn "sibcall_internal"
 	 (match_operand 1 "" ""))]
   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
   "@
-    %*jr\\t%0
-    %*j\\t%0"
+    %*jr\t%0%/
+    %*j\t%0%/"
   [(set_attr "type" "call")])
 
 (define_expand "sibcall_value"
@@ -8889,8 +8896,8 @@ (define_insn "sibcall_value_internal"
               (match_operand 2 "" "")))]
   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
   "@
-    %*jr\\t%1
-    %*j\\t%1"
+    %*jr\t%1%/
+    %*j\t%1%/"
   [(set_attr "type" "call")])
 
 (define_insn "sibcall_value_multiple_internal"
@@ -8902,8 +8909,8 @@ (define_insn "sibcall_value_multiple_int
 	      (match_dup 2)))]
   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
   "@
-    %*jr\\t%1
-    %*j\\t%1"
+    %*jr\t%1%/
+    %*j\t%1%/"
   [(set_attr "type" "call")])
 
 (define_expand "call"
@@ -8922,7 +8929,7 @@ (define_insn_and_split "call_internal"
 	 (match_operand 1 "" ""))
    (clobber (reg:SI 31))]
   ""
-  "%*jal\\t%0"
+  "%*jal\t%0%/"
   "reload_completed && TARGET_SPLIT_CALLS"
   [(const_int 0)]
   {
@@ -8939,7 +8946,7 @@ (define_insn "call_split"
    (clobber (reg:SI 31))
    (const_int 1)]
   "TARGET_SPLIT_CALLS"
-  "%*jalr\\t%0"
+  "%*jalr\t%0%/"
   [(set_attr "type" "call")])
 
 (define_expand "call_value"
@@ -8960,7 +8967,7 @@ (define_insn_and_split "call_value_inter
               (match_operand 2 "" "")))
    (clobber (reg:SI 31))]
   ""
-  "%*jal\\t%1"
+  "%*jal\t%1%/"
   "reload_completed && TARGET_SPLIT_CALLS"
   [(const_int 0)]
   {
@@ -8979,7 +8986,7 @@ (define_insn "call_value_split"
    (clobber (reg:SI 31))
    (const_int 1)]
   "TARGET_SPLIT_CALLS"
-  "%*jalr\\t%1"
+  "%*jalr\t%1%/"
   [(set_attr "type" "call")])
 
 (define_insn_and_split "call_value_multiple_internal"
@@ -8991,7 +8998,7 @@ (define_insn_and_split "call_value_multi
 	      (match_dup 2)))
    (clobber (reg:SI 31))]
   ""
-  "%*jal\\t%1"
+  "%*jal\t%1%/"
   "reload_completed && TARGET_SPLIT_CALLS"
   [(const_int 0)]
   {
@@ -9013,7 +9020,7 @@ (define_insn "call_value_multiple_split"
    (clobber (reg:SI 31))
    (const_int 1)]
   "TARGET_SPLIT_CALLS"
-  "%*jalr\\t%1"
+  "%*jalr\t%1%/"
   [(set_attr "type" "call")])
 
 ;; Call subroutine returning any type.
@@ -9100,6 +9107,18 @@ (define_insn "nop"
   [(set_attr "type"	"nop")
    (set_attr "mode"	"none")])
 
+;; Like nop, but commented out when outside a .set noreorder block.
+(define_insn "hazard_nop"
+  [(const_int 1)]
+  ""
+  {
+    if (set_noreorder)
+      return "nop";
+    else
+      return "#nop";
+  }
+  [(set_attr "type"	"arith")])
+
 ;; The MIPS chip does not seem to require stack probes.
 ;;
 ;; (define_expand "probe"
@@ -9509,9 +9528,9 @@ (define_peephole
   "*
 {
   if (operands[3] != pc_rtx)
-    return \"%*b%C2z\\t%1,%3\";
+    return \"b%C2z\\t%1,%3\";
   else
-    return \"%*b%N2z\\t%1,%4\";
+    return \"b%N2z\\t%1,%4\";
 }"
   [(set_attr "type"	"branch")
    (set_attr "mode"	"none")
@@ -9534,9 +9553,9 @@ (define_peephole
   "*
 {
   if (operands[3] != pc_rtx)
-    return \"%*b%C2z\\t%1,%3\";
+    return \"b%C2z\\t%1,%3\";
   else
-    return \"%*b%N2z\\t%1,%4\";
+    return \"b%N2z\\t%1,%4\";
 }"
   [(set_attr "type"	"branch")
    (set_attr "mode"	"none")
@@ -9563,9 +9582,9 @@ (define_peephole
   "*
 {
   if (operands[3] != pc_rtx)
-    return \"%*bt%C2z\\t%3\";
+    return \"bt%C2z\\t%3\";
   else
-    return \"%*bt%N2z\\t%4\";
+    return \"bt%N2z\\t%4\";
 }"
   [(set_attr "type"	"branch")
    (set_attr "mode"	"none")
@@ -9588,9 +9607,9 @@ (define_peephole
   "*
 {
   if (operands[3] != pc_rtx)
-    return \"%*bt%C2z\\t%3\";
+    return \"bt%C2z\\t%3\";
   else
-    return \"%*bt%N2z\\t%4\";
+    return \"bt%N2z\\t%4\";
 }"
   [(set_attr "type"	"branch")
    (set_attr "mode"	"none")



More information about the Gcc-patches mailing list