This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Mips instruction hazards (parts 3&4/4)


This patch adds a hazard-avoidance pass to the mips port.  It was
originally going to be two separate patches, but it probably makes
more sense as one.

Although the pass is really just doing what the assembler normally does,
there are some advantages to doing it in gcc:

  - We will know what alignment an instruction has and be able optimise
    appropriately.  For example, some targets prefer branches to be 8-byte
    aligned.  Some (like the vr4131) can only dual-issue instructions if
    the first one is 8-byte aligned.

    This is the main benefit, but I should mention that I'm not planning
    to do any optimisations like this at the moment.

  - We won't be so pessimistic about when long branches are needed.

  - It makes the asm output look nicer (IMO).

The patch also sees whether a function contains inline asm: if it
doesn't, the whole thing can go into .set noreorder/.set nomacro.

I went through the insn patterns looking for those that include
branches.  There were four cases:

  - branches with a fixed delay slot insn.
      Left unchanged.

  - branches with an implicit nop in their delay slots
      Added %# after the branch instruction.

  - branches with a delay slot that can be filled by dbr_schedule
      Added %/ after the branch instruction.  %/ effectively
      closes the %* that appears at the start of these insns.

  - branches with no delay slot (mips16)
      Made sure there wasn't a spurious %*.  These extra %*s were
      harmless, but after the change above, it would be confusing
      to have some patterns with %* and not %/.

While going through the patterns, I noticed a couple of bogus
lengths and attributes, also fixed below.

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

Richard


	* config/mips/mips.c (machine_function): Add new fields:
	ignore_hazard_length_p and all_noreorder_p.
	(TARGET_MACHINE_DEPENDENT_REORG2): Define.
	(override_options): Treat '/' as an operand punctuation character.
	(print_operand): Handle it here.
	(mips_output_function_prologue): Put the whole function in
	.set noreorder/.set nomacro if all_noreorder_p is true.
	(mips_output_function_epilogue): End the noreorder sequence here.
	(mips_avoid_hazard, mips_reorg2): New functions.
	(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.279
diff -u -d -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.279 mips.c
--- config/mips/mips.c	17 Jun 2003 06:44:45 -0000	1.279
+++ config/mips/mips.c	22 Jun 2003 13:31:16 -0000
@@ -251,6 +251,9 @@ static void dump_constants			PARAMS ((st
 							rtx));
 static rtx mips_find_symbol			PARAMS ((rtx));
 static void mips_reorg				PARAMS ((void));
+static void mips_avoid_hazard			PARAMS ((rtx, rtx, int *,
+							 rtx *, rtx));
+static void mips_reorg2				PARAMS ((void));
 static void abort_with_insn			PARAMS ((rtx, const char *))
   ATTRIBUTE_NORETURN;
 static int symbolic_expression_p                PARAMS ((rtx));
@@ -333,6 +336,13 @@ 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.  */
+  bool all_noreorder_p;
 };
 
 /* Information about a single argument.  */
@@ -872,6 +882,8 @@ #define TARGET_ENCODE_SECTION_INFO mips_
 
 #undef TARGET_MACHINE_DEPENDENT_REORG
 #define TARGET_MACHINE_DEPENDENT_REORG mips_reorg
+#undef TARGET_MACHINE_DEPENDENT_REORG2
+#define TARGET_MACHINE_DEPENDENT_REORG2 mips_reorg2
 
 #undef TARGET_ASM_FILE_END
 #ifdef TARGET_IRIX6
@@ -5146,6 +5158,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;
@@ -5461,6 +5474,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).
@@ -5534,6 +5548,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);
@@ -7059,10 +7081,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
@@ -7473,6 +7501,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)
     {
@@ -9422,6 +9458,126 @@ mips_reorg ()
      constant table, but we have no way to prevent that.  */
 }
 
+
+/* Subroutine of mips_reorg2.  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;
+      }
+}
+
+
+/* If using explicit relocs, go through the instruction stream and
+   insert nops where necessary.  See if the whole function can then
+   be put into .set noreorder.  */
+
+static void
+mips_reorg2 ()
+{
+  rtx insn, last_insn, lo_reg, delayed_reg;
+  int hilo_delay, i;
+
+  if (!TARGET_EXPLICIT_RELOCS)
+    return;
+
+  /* Recalculate instruction lengths without taking nops into account.  */
+  cfun->machine->ignore_hazard_length_p = true;
+  shorten_branches (get_insns ());
+
+  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;
+      }
+}
+
+
 /* 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
@@ -9537,7 +9693,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:
@@ -9576,6 +9732,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
@@ -9695,10 +9853,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,
@@ -9916,7 +10074,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.175
diff -u -d -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.175 mips.md
--- config/mips/mips.md	17 Jun 2003 06:44:46 -0000	1.175
+++ config/mips/mips.md	22 Jun 2003 13:31:17 -0000
@@ -3039,7 +3039,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")
@@ -3073,7 +3073,7 @@ move\\t%0,%z4\\n\\
 }"
   [(set_attr "type"	"multi")
    (set_attr "mode"	"DI")
-   (set_attr "length"	"24")])
+   (set_attr "length"	"28")])
 
 
 
@@ -3488,7 +3488,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,*")])
 
@@ -3499,7 +3499,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,*")])
 
@@ -3510,7 +3510,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,*")])
 
@@ -4074,7 +4074,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")])
@@ -4105,7 +4109,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")])
@@ -4436,7 +4444,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")
@@ -5635,7 +5644,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\\
@@ -5990,7 +5999,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\\
@@ -6368,7 +6377,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\\
@@ -6987,16 +6996,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")
@@ -7016,16 +7025,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")
@@ -8388,15 +8397,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")
@@ -8449,14 +8458,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")])
 
@@ -8500,7 +8509,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")])
 
@@ -8509,7 +8518,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")])
 
@@ -8625,7 +8634,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")])
@@ -8642,7 +8651,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")])
@@ -8750,7 +8759,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")])
 
@@ -8760,10 +8769,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")])
 
@@ -8826,7 +8832,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")
@@ -8866,8 +8873,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"
@@ -8888,8 +8895,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"
@@ -8901,8 +8908,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"
@@ -8921,7 +8928,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)]
   {
@@ -8938,7 +8945,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"
@@ -8959,7 +8966,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)]
   {
@@ -8978,7 +8985,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"
@@ -8990,7 +8997,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)]
   {
@@ -9012,7 +9019,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.
@@ -9099,6 +9106,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"
@@ -9508,9 +9527,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")
@@ -9533,9 +9552,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")
@@ -9562,9 +9581,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")
@@ -9587,9 +9606,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")


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]