mips.c (machine_function): Add new fields: ignore_hazard_length_p and all_noreorder_p.

* 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.

From-SVN: r68821
This commit is contained in:
Richard Sandiford 2003-07-02 07:34:27 +00:00 committed by Richard Sandiford
parent 0184bd46b0
commit 6f2993e58b
3 changed files with 308 additions and 76 deletions

View File

@ -1,3 +1,38 @@
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

View File

@ -243,13 +243,17 @@ static void save_restore_insns PARAMS ((int, rtx, long));
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
@ -5153,6 +5168,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
@ -5163,6 +5186,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;
@ -5478,6 +5502,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).
@ -5551,6 +5576,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);
@ -7073,10 +7106,16 @@ mips_output_function_prologue (file, size)
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
@ -7487,6 +7526,14 @@ mips_output_function_epilogue (file, size)
{
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)
{
@ -8893,8 +8940,7 @@ build_mips16_call_stub (retval, fn, arg_size, fp_code)
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;
@ -8907,7 +8953,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;
@ -8990,7 +9036,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;
@ -9059,7 +9105,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;
@ -9236,22 +9282,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
@ -9436,6 +9474,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
@ -9551,7 +9727,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:
@ -9590,6 +9766,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
@ -9709,10 +9887,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,
@ -9930,7 +10108,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;
}

View File

@ -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 @@ move\\t%0,%z4\\n\\
"@
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 @@ move\\t%0,%z4\\n\\
"@
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 @@ move\\t%0,%z4\\n\\
"@
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 @@ move\\t%0,%z4\\n\\
(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 @@ move\\t%0,%z4\\n\\
(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 @@ move\\t%0,%z4\\n\\
"!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 @@ move\\t%0,%z4\\n\\
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 @@ move\\t%0,%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\\
@ -6369,7 +6378,7 @@ move\\t%0,%z4\\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\\
@ -6988,16 +6997,16 @@ move\\t%0,%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")
@ -7017,16 +7026,16 @@ move\\t%0,%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")
@ -8389,15 +8398,15 @@ move\\t%0,%z4\\n\\
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 @@ move\\t%0,%z4\\n\\
(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 @@ move\\t%0,%z4\\n\\
(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 @@ move\\t%0,%z4\\n\\
(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 @@ move\\t%0,%z4\\n\\
(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 @@ lw\\t%2,%1-%S1(%2)\;addu\\t%2,%2,$31\\n\\t%*j\\t%2"
(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 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2"
(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 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2"
[(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 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2"
}")
(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 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2"
(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 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2"
(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 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2"
(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 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2"
(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 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2"
(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 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2"
(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 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2"
(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 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2"
(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 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2"
(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 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2"
[(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 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2"
"*
{
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 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2"
"*
{
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 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2"
"*
{
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 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2"
"*
{
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")