mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-22 07:49:19 +08:00
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:
parent
0184bd46b0
commit
6f2993e58b
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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")
|
||||
|
Loading…
Reference in New Issue
Block a user