+2003-07-02 Richard Sandiford <rsandifo@redhat.com>
+
+ * 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.
+
Wed Jul 2 08:12:36 CEST 2003 Jan Hubicka <jh@suse.cz>
* cgraphunit.c (cgraph_finalize_unit): Set current_function_decl
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;
/* 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. */
/* 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
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
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;
'*' 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).
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);
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);
}
\f
/* Emit an instruction to move SRC into DEST. When generating
{
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)
{
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;
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;
#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;
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;
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
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
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:
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
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,
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;
}
}"
[(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")
}"
[(set_attr "type" "multi")
(set_attr "mode" "DI")
- (set_attr "length" "24")])
+ (set_attr "length" "28")])
\f
"@
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,*")])
"@
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,*")])
"@
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,*")])
(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")])
(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")])
"!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")
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\\
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\\
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\\
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")
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")
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")
(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")])
(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")])
(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")])
(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")])
(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")])
(define_insn "return"
[(return)]
"mips_can_use_return_insn ()"
- "%*j\\t$31"
+ "%*j\t$31%/"
[(set_attr "type" "jump")
(set_attr "mode" "none")])
[(use (match_operand 0 "pmode_register_operand" ""))
(return)]
""
- "*
-{
- return \"%*j\\t%0\";
-}"
+ "%*j\t%0%/"
[(set_attr "type" "jump")
(set_attr "mode" "none")])
}")
(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")
(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"
(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"
(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"
(match_operand 1 "" ""))
(clobber (reg:SI 31))]
""
- "%*jal\\t%0"
+ "%*jal\t%0%/"
"reload_completed && TARGET_SPLIT_CALLS"
[(const_int 0)]
{
(clobber (reg:SI 31))
(const_int 1)]
"TARGET_SPLIT_CALLS"
- "%*jalr\\t%0"
+ "%*jalr\t%0%/"
[(set_attr "type" "call")])
(define_expand "call_value"
(match_operand 2 "" "")))
(clobber (reg:SI 31))]
""
- "%*jal\\t%1"
+ "%*jal\t%1%/"
"reload_completed && TARGET_SPLIT_CALLS"
[(const_int 0)]
{
(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"
(match_dup 2)))
(clobber (reg:SI 31))]
""
- "%*jal\\t%1"
+ "%*jal\t%1%/"
"reload_completed && TARGET_SPLIT_CALLS"
[(const_int 0)]
{
(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.
[(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"
"*
{
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")
"*
{
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")
"*
{
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")
"*
{
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")