mirror of git://gcc.gnu.org/git/gcc.git
MIPS compact branch support
gcc/ * config/mips/mips-opts.h (mips_cb_setting): New enum. * config/mips/mips-protos.h: Add definitions for mips_output_jump and mips_output_equal_conditional_branch * gcc/config/mips/mips.c (MIPS_JR): Change to support the JIC instruction. (mips_emit_compare): Add support for the MIPS R6 conditional compact branches. (mips_process_sync_loop): Likewise. (mips_output_order_conditional_branch): Likewise. (mips16_build_call_stub): Change MIPS_CALL to mips_output_jump. (mips_print_operand_punctuation): Update 's' case to only apply to micromips r2. (mips_adjust_insn_length): Add support for forbidden slot hazards. (mips_avoid_hazard): Likewise. (mips_reorg_process_insns): Likewise. (mips_output_jump): New function. (mips_output_equal_conditional_branch): Likewise. (mips_output_conditional_branch): Use jrc/bc if compact branch support is enabled. Ensure the forbidden slots between the two branch instructions is filled with a nop. (mips_option_override): Add support to process the compact branch option and set the correct defaults. Prevent non-explict relocs being using for MIPS R6. (mips_trampoline_init): Add compact branch support. (mips_mult_zero_zero_cost): Allow zero initialisation of accumulators with TARGET_DSP. * gcc/config/mips/mips.h (TARGET_CB_NEVER): New define. (TARGET_CB_MAYBE): New define. (TARGET_CB_ALWAYS): New define. (ISA_HAS_DELAY_SLOTS): New define. (ISA_HAS_COMPACT_BRANCHES): New define. (ISA_HAS_JRC): New define. (MIPS_BRANCH_C): New define. (MIPS_CALL): Removed. (MICROMIPS_J): Removed. * config/mips/mips.md (compact_form): New attr. (hazard): Add support for forbidden slots. (define_delay): Add support for compact branches. (*branch_order<mode>): Likewise. (*branch_order<mode>_inverted): Likewise. (*branch_equality<mode>): Likewise. (*branch_equality<mode>_inverted): Likewise. (*jump_absolute): Likewise. (*jump_pic): Likewise. (indirect_jump): Use mips_output_jump to produce assembly output. (tablejump_<mode>"): Likewise. (*<optab>"): Likewise. (<optab>_internal): Likewise. (sibcall_internal): Likewise. (sibcall_value_internal): Likewise. (sibcall_value_multiple_internal): Likewise. (call_internal): Likewise. (call_split): Likewise. (call_internal_direct): Likewise. (call_direct_split): Likewise. (call_value_internal): Likewise. (call_value_split): Likewise. (call_value_internal_direct): Likewise. (call_value_direct_split): Likewise. (call_value_multiple_internal): Likewise. (call_value_multiple_split): Likewise. (mips_get_fcsr_mips16_<mode>): Likewise. (mips_set_fcsr_mips16_<mode>): Likewise. (tls_get_tp_mips16_<mode>): Likewise. * config/mips/mips.opt: Add -mcompact-branches option. * config/mips/predicates.md (order_operator): Ensure the conditional compact branches are only used if the ISA them. * doc/invoke.texi: Document -mcompact-branches option. gcc/testsuite/ * gcc.target/mips/mips.exp (mips-dg-options): Handle the dependencies between ISA level and compact-branches. * gcc.target/mips/branch-10.c: Update expected output to allow compact forms of b/bal. * gcc.target/mips/branch-11.c: Likewise. * gcc.target/mips/branch-12.c: Likewise. * gcc.target/mips/branch-13.c: Likewise. * gcc.target/mips/branch-3.c: Likewise. * gcc.target/mips/branch-4.c: Likewise. * gcc.target/mips/branch-5.c: Likewise. * gcc.target/mips/branch-6.c: Likewise. * gcc.target/mips/branch-7.c: Likewise. * gcc.target/mips/branch-8.c: Likewise. * gcc.target/mips/branch-9.c: Likewise. * gcc.target/mips/branch-cost-1.c: Likewise. * gcc.target/mips/call-1.c: Likewise. * gcc.target/mips/call-2.c: Likewise. * gcc.target/mips/call-3.c: Likewise. * gcc.target/mips/call-4.c: Likewise. * gcc.target/mips/call-5.c: Likewise. * gcc.target/mips/call-6.c: Likewise. * gcc.target/mips/lazy-binding-1.c: Likewise. * gcc.target/mips/near-far-1.c: Likewise. * gcc.target/mips/near-far-2.c: Likewise. * gcc.target/mips/near-far-3.c: Likewise. * gcc.target/mips/near-far-4.c: Likewise. * gcc.target/mips/umips-branch-3.c: Ensure the test is run with compact branches allowed. * gcc.target/mips/compact-branches-1.c: New file. * gcc.target/mips/compact-branches-2.c: Likewise. * gcc.target/mips/compact-branches-3.c: Likewise. * gcc.target/mips/compact-branches-4.c: Likewise. * gcc.target/mips/compact-branches-5.c: Likewise. * gcc.target/mips/compact-branches-6.c: Likewise. * gcc.target/mips/compact-branches-7.c: Likewise. Co-Authored-By: Andrew Bennett <andrew.bennett@imgtec.com> From-SVN: r227385
This commit is contained in:
parent
2503fd9e07
commit
22219d9b1a
|
|
@ -1,3 +1,77 @@
|
||||||
|
2015-09-01 Matthew Fortune <matthew.fortune@imgtec.com>
|
||||||
|
Andrew Bennett <andrew.bennett@imgtec.com>
|
||||||
|
|
||||||
|
* config/mips/mips-opts.h (mips_cb_setting): New enum.
|
||||||
|
* config/mips/mips-protos.h: Add definitions for
|
||||||
|
mips_output_jump and mips_output_equal_conditional_branch
|
||||||
|
* gcc/config/mips/mips.c (MIPS_JR): Change to support the
|
||||||
|
JIC instruction.
|
||||||
|
(mips_emit_compare): Add support for the MIPS R6 conditional
|
||||||
|
compact branches.
|
||||||
|
(mips_process_sync_loop): Likewise.
|
||||||
|
(mips_output_order_conditional_branch): Likewise.
|
||||||
|
(mips16_build_call_stub): Change MIPS_CALL to
|
||||||
|
mips_output_jump.
|
||||||
|
(mips_print_operand_punctuation): Update 's' case to only
|
||||||
|
apply to micromips r2.
|
||||||
|
(mips_adjust_insn_length): Add support for forbidden slot
|
||||||
|
hazards.
|
||||||
|
(mips_avoid_hazard): Likewise.
|
||||||
|
(mips_reorg_process_insns): Likewise.
|
||||||
|
(mips_output_jump): New function.
|
||||||
|
(mips_output_equal_conditional_branch): Likewise.
|
||||||
|
(mips_output_conditional_branch): Use jrc/bc if compact
|
||||||
|
branch support is enabled. Ensure the forbidden slots
|
||||||
|
between the two branch instructions is filled with a nop.
|
||||||
|
(mips_option_override): Add support to process the compact
|
||||||
|
branch option and set the correct defaults. Prevent
|
||||||
|
non-explict relocs being using for MIPS R6.
|
||||||
|
(mips_trampoline_init): Add compact branch support.
|
||||||
|
(mips_mult_zero_zero_cost): Allow zero initialisation of
|
||||||
|
accumulators with TARGET_DSP.
|
||||||
|
* gcc/config/mips/mips.h (TARGET_CB_NEVER): New define.
|
||||||
|
(TARGET_CB_MAYBE): New define.
|
||||||
|
(TARGET_CB_ALWAYS): New define.
|
||||||
|
(ISA_HAS_DELAY_SLOTS): New define.
|
||||||
|
(ISA_HAS_COMPACT_BRANCHES): New define.
|
||||||
|
(ISA_HAS_JRC): New define.
|
||||||
|
(MIPS_BRANCH_C): New define.
|
||||||
|
(MIPS_CALL): Removed.
|
||||||
|
(MICROMIPS_J): Removed.
|
||||||
|
* config/mips/mips.md (compact_form): New attr.
|
||||||
|
(hazard): Add support for forbidden slots.
|
||||||
|
(define_delay): Add support for compact branches.
|
||||||
|
(*branch_order<mode>): Likewise.
|
||||||
|
(*branch_order<mode>_inverted): Likewise.
|
||||||
|
(*branch_equality<mode>): Likewise.
|
||||||
|
(*branch_equality<mode>_inverted): Likewise.
|
||||||
|
(*jump_absolute): Likewise.
|
||||||
|
(*jump_pic): Likewise.
|
||||||
|
(indirect_jump): Use mips_output_jump to produce assembly output.
|
||||||
|
(tablejump_<mode>"): Likewise.
|
||||||
|
(*<optab>"): Likewise.
|
||||||
|
(<optab>_internal): Likewise.
|
||||||
|
(sibcall_internal): Likewise.
|
||||||
|
(sibcall_value_internal): Likewise.
|
||||||
|
(sibcall_value_multiple_internal): Likewise.
|
||||||
|
(call_internal): Likewise.
|
||||||
|
(call_split): Likewise.
|
||||||
|
(call_internal_direct): Likewise.
|
||||||
|
(call_direct_split): Likewise.
|
||||||
|
(call_value_internal): Likewise.
|
||||||
|
(call_value_split): Likewise.
|
||||||
|
(call_value_internal_direct): Likewise.
|
||||||
|
(call_value_direct_split): Likewise.
|
||||||
|
(call_value_multiple_internal): Likewise.
|
||||||
|
(call_value_multiple_split): Likewise.
|
||||||
|
(mips_get_fcsr_mips16_<mode>): Likewise.
|
||||||
|
(mips_set_fcsr_mips16_<mode>): Likewise.
|
||||||
|
(tls_get_tp_mips16_<mode>): Likewise.
|
||||||
|
* config/mips/mips.opt: Add -mcompact-branches option.
|
||||||
|
* config/mips/predicates.md (order_operator): Ensure the
|
||||||
|
conditional compact branches are only used if the ISA them.
|
||||||
|
* doc/invoke.texi: Document -mcompact-branches option.
|
||||||
|
|
||||||
2015-09-01 Vladimir Makarov <vmakarov@redhat.com>
|
2015-09-01 Vladimir Makarov <vmakarov@redhat.com>
|
||||||
|
|
||||||
PR target/61578
|
PR target/61578
|
||||||
|
|
|
||||||
|
|
@ -47,4 +47,10 @@ enum mips_r10k_cache_barrier_setting {
|
||||||
#define MIPS_ARCH_OPTION_FROM_ABI -1
|
#define MIPS_ARCH_OPTION_FROM_ABI -1
|
||||||
#define MIPS_ARCH_OPTION_NATIVE -2
|
#define MIPS_ARCH_OPTION_NATIVE -2
|
||||||
|
|
||||||
|
/* Enumerates the setting of the -mcompact-branches= option. */
|
||||||
|
enum mips_cb_setting {
|
||||||
|
MIPS_CB_NEVER,
|
||||||
|
MIPS_CB_OPTIMAL,
|
||||||
|
MIPS_CB_ALWAYS
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -298,6 +298,9 @@ extern const char *mips_output_conditional_branch (rtx_insn *, rtx *,
|
||||||
const char *, const char *);
|
const char *, const char *);
|
||||||
extern const char *mips_output_order_conditional_branch (rtx_insn *, rtx *,
|
extern const char *mips_output_order_conditional_branch (rtx_insn *, rtx *,
|
||||||
bool);
|
bool);
|
||||||
|
extern const char *mips_output_equal_conditional_branch (rtx_insn *, rtx *,
|
||||||
|
bool);
|
||||||
|
extern const char *mips_output_jump (rtx *, int, int, bool);
|
||||||
extern const char *mips_output_sync (void);
|
extern const char *mips_output_sync (void);
|
||||||
extern const char *mips_output_sync_loop (rtx_insn *, rtx *);
|
extern const char *mips_output_sync_loop (rtx_insn *, rtx *);
|
||||||
extern unsigned int mips_sync_loop_insns (rtx_insn *, rtx *);
|
extern unsigned int mips_sync_loop_insns (rtx_insn *, rtx *);
|
||||||
|
|
|
||||||
|
|
@ -176,7 +176,8 @@ along with GCC; see the file COPYING3. If not see
|
||||||
/* Return the opcode to jump to register DEST. When the JR opcode is not
|
/* Return the opcode to jump to register DEST. When the JR opcode is not
|
||||||
available use JALR $0, DEST. */
|
available use JALR $0, DEST. */
|
||||||
#define MIPS_JR(DEST) \
|
#define MIPS_JR(DEST) \
|
||||||
(((DEST) << 21) | (ISA_HAS_JR ? 0x8 : 0x9))
|
(TARGET_CB_ALWAYS ? ((0x1b << 27) | ((DEST) << 16)) \
|
||||||
|
: (((DEST) << 21) | (ISA_HAS_JR ? 0x8 : 0x9)))
|
||||||
|
|
||||||
/* Return the opcode for:
|
/* Return the opcode for:
|
||||||
|
|
||||||
|
|
@ -5181,7 +5182,8 @@ mips_allocate_fcc (machine_mode mode)
|
||||||
conditions are:
|
conditions are:
|
||||||
|
|
||||||
- EQ or NE between two registers.
|
- EQ or NE between two registers.
|
||||||
- any comparison between a register and zero. */
|
- any comparison between a register and zero.
|
||||||
|
- if compact branches are available then any condition is valid. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mips_emit_compare (enum rtx_code *code, rtx *op0, rtx *op1, bool need_eq_ne_p)
|
mips_emit_compare (enum rtx_code *code, rtx *op0, rtx *op1, bool need_eq_ne_p)
|
||||||
|
|
@ -5203,6 +5205,44 @@ mips_emit_compare (enum rtx_code *code, rtx *op0, rtx *op1, bool need_eq_ne_p)
|
||||||
else
|
else
|
||||||
*op1 = force_reg (GET_MODE (cmp_op0), cmp_op1);
|
*op1 = force_reg (GET_MODE (cmp_op0), cmp_op1);
|
||||||
}
|
}
|
||||||
|
else if (!need_eq_ne_p && TARGET_CB_MAYBE)
|
||||||
|
{
|
||||||
|
bool swap = false;
|
||||||
|
switch (*code)
|
||||||
|
{
|
||||||
|
case LE:
|
||||||
|
swap = true;
|
||||||
|
*code = GE;
|
||||||
|
break;
|
||||||
|
case GT:
|
||||||
|
swap = true;
|
||||||
|
*code = LT;
|
||||||
|
break;
|
||||||
|
case LEU:
|
||||||
|
swap = true;
|
||||||
|
*code = GEU;
|
||||||
|
break;
|
||||||
|
case GTU:
|
||||||
|
swap = true;
|
||||||
|
*code = LTU;
|
||||||
|
break;
|
||||||
|
case GE:
|
||||||
|
case LT:
|
||||||
|
case GEU:
|
||||||
|
case LTU:
|
||||||
|
/* Do nothing. */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
gcc_unreachable ();
|
||||||
|
}
|
||||||
|
*op1 = force_reg (GET_MODE (cmp_op0), cmp_op1);
|
||||||
|
if (swap)
|
||||||
|
{
|
||||||
|
rtx tmp = *op1;
|
||||||
|
*op1 = *op0;
|
||||||
|
*op0 = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* The comparison needs a separate scc instruction. Store the
|
/* The comparison needs a separate scc instruction. Store the
|
||||||
|
|
@ -7260,7 +7300,7 @@ mips16_build_call_stub (rtx retval, rtx *fn_ptr, rtx args_size, int fp_code)
|
||||||
if (fp_ret_p)
|
if (fp_ret_p)
|
||||||
{
|
{
|
||||||
/* Now call the non-MIPS16 function. */
|
/* Now call the non-MIPS16 function. */
|
||||||
output_asm_insn (MIPS_CALL ("jal", &fn, 0, -1), &fn);
|
output_asm_insn (mips_output_jump (&fn, 0, -1, true), &fn);
|
||||||
fprintf (asm_out_file, "\t.cfi_register 31,18\n");
|
fprintf (asm_out_file, "\t.cfi_register 31,18\n");
|
||||||
|
|
||||||
/* Move the result from floating-point registers to
|
/* Move the result from floating-point registers to
|
||||||
|
|
@ -8378,7 +8418,7 @@ mips_pop_asm_switch (struct mips_asm_switch *asm_switch)
|
||||||
'!' Print "s" to use the short version if the delay slot contains a
|
'!' Print "s" to use the short version if the delay slot contains a
|
||||||
16-bit instruction.
|
16-bit instruction.
|
||||||
|
|
||||||
See also mips_init_print_operand_pucnt. */
|
See also mips_init_print_operand_punct. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mips_print_operand_punctuation (FILE *file, int ch)
|
mips_print_operand_punctuation (FILE *file, int ch)
|
||||||
|
|
@ -8462,7 +8502,8 @@ mips_print_operand_punctuation (FILE *file, int ch)
|
||||||
|
|
||||||
case ':':
|
case ':':
|
||||||
/* When final_sequence is 0, the delay slot will be a nop. We can
|
/* When final_sequence is 0, the delay slot will be a nop. We can
|
||||||
use the compact version for microMIPS. */
|
use the compact version where available. The %: formatter will
|
||||||
|
only be present if a compact form of the branch is available. */
|
||||||
if (final_sequence == 0)
|
if (final_sequence == 0)
|
||||||
putc ('c', file);
|
putc ('c', file);
|
||||||
break;
|
break;
|
||||||
|
|
@ -8470,8 +8511,9 @@ mips_print_operand_punctuation (FILE *file, int ch)
|
||||||
case '!':
|
case '!':
|
||||||
/* If the delay slot instruction is short, then use the
|
/* If the delay slot instruction is short, then use the
|
||||||
compact version. */
|
compact version. */
|
||||||
if (final_sequence == 0
|
if (TARGET_MICROMIPS && !TARGET_INTERLINK_COMPRESSED && mips_isa_rev <= 5
|
||||||
|| get_attr_length (final_sequence->insn (1)) == 2)
|
&& (final_sequence == 0
|
||||||
|
|| get_attr_length (final_sequence->insn (1)) == 2))
|
||||||
putc ('s', file);
|
putc ('s', file);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -12969,6 +13011,7 @@ mips_adjust_insn_length (rtx_insn *insn, int length)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HAZARD_DELAY:
|
case HAZARD_DELAY:
|
||||||
|
case HAZARD_FORBIDDEN_SLOT:
|
||||||
length += NOP_INSN_LENGTH;
|
length += NOP_INSN_LENGTH;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -12980,6 +13023,78 @@ mips_adjust_insn_length (rtx_insn *insn, int length)
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return the asm template for a call. OPERANDS are the operands, TARGET_OPNO
|
||||||
|
is the operand number of the target. SIZE_OPNO is the operand number of
|
||||||
|
the argument size operand that can optionally hold the call attributes. If
|
||||||
|
SIZE_OPNO is not -1 and the call is indirect, use the function symbol from
|
||||||
|
the call attributes to attach a R_MIPS_JALR relocation to the call. LINK_P
|
||||||
|
indicates whether the jump is a call and needs to set the link register.
|
||||||
|
|
||||||
|
When generating GOT code without explicit relocation operators, all calls
|
||||||
|
should use assembly macros. Otherwise, all indirect calls should use "jr"
|
||||||
|
or "jalr"; we will arrange to restore $gp afterwards if necessary. Finally,
|
||||||
|
we can only generate direct calls for -mabicalls by temporarily switching
|
||||||
|
to non-PIC mode.
|
||||||
|
|
||||||
|
For microMIPS jal(r), we try to generate jal(r)s when a 16-bit
|
||||||
|
instruction is in the delay slot of jal(r).
|
||||||
|
|
||||||
|
Where compact branches are available, we try to use them if the delay slot
|
||||||
|
has a NOP (or equivalently delay slots were not enabled for the instruction
|
||||||
|
anyway). */
|
||||||
|
|
||||||
|
const char *
|
||||||
|
mips_output_jump (rtx *operands, int target_opno, int size_opno, bool link_p)
|
||||||
|
{
|
||||||
|
static char buffer[300];
|
||||||
|
char *s = buffer;
|
||||||
|
bool reg_p = REG_P (operands[target_opno]);
|
||||||
|
|
||||||
|
const char *and_link = link_p ? "al" : "";
|
||||||
|
const char *reg = reg_p ? "r" : "";
|
||||||
|
const char *compact = "";
|
||||||
|
const char *nop = "%/";
|
||||||
|
const char *short_delay = link_p ? "%!" : "";
|
||||||
|
const char *insn_name = TARGET_CB_NEVER || reg_p ? "j" : "b";
|
||||||
|
|
||||||
|
/* Compact branches can only be described when the ISA has support for them
|
||||||
|
as both the compact formatter '%:' and the delay slot NOP formatter '%/'
|
||||||
|
work as a mutually exclusive pair. I.e. a NOP is never required if a
|
||||||
|
compact form is available. */
|
||||||
|
if (!final_sequence
|
||||||
|
&& (TARGET_CB_MAYBE
|
||||||
|
|| (ISA_HAS_JRC && !link_p && reg_p)))
|
||||||
|
{
|
||||||
|
compact = "c";
|
||||||
|
nop = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TARGET_USE_GOT && !TARGET_EXPLICIT_RELOCS)
|
||||||
|
sprintf (s, "%%*%s%s\t%%%d%%/", insn_name, and_link, target_opno);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!reg_p && TARGET_ABICALLS_PIC2)
|
||||||
|
s += sprintf (s, ".option\tpic0\n\t");
|
||||||
|
|
||||||
|
if (reg_p && mips_get_pic_call_symbol (operands, size_opno))
|
||||||
|
{
|
||||||
|
s += sprintf (s, "%%*.reloc\t1f,R_MIPS_JALR,%%%d\n1:\t", size_opno);
|
||||||
|
/* Not sure why this shouldn't permit a short delay but it did not
|
||||||
|
allow it before so we still don't allow it. */
|
||||||
|
short_delay = "";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
s += sprintf (s, "%%*");
|
||||||
|
|
||||||
|
s += sprintf (s, "%s%s%s%s%s\t%%%d%s", insn_name, and_link, reg, compact, short_delay,
|
||||||
|
target_opno, nop);
|
||||||
|
|
||||||
|
if (!reg_p && TARGET_ABICALLS_PIC2)
|
||||||
|
s += sprintf (s, "\n\t.option\tpic2");
|
||||||
|
}
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
/* Return the assembly code for INSN, which has the operands given by
|
/* Return the assembly code for INSN, which has the operands given by
|
||||||
OPERANDS, and which branches to OPERANDS[0] if some condition is true.
|
OPERANDS, and which branches to OPERANDS[0] if some condition is true.
|
||||||
BRANCH_IF_TRUE is the asm template that should be used if OPERANDS[0]
|
BRANCH_IF_TRUE is the asm template that should be used if OPERANDS[0]
|
||||||
|
|
@ -13033,12 +13148,25 @@ mips_output_conditional_branch (rtx_insn *insn, rtx *operands,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Output the unconditional branch to TAKEN. */
|
/* Output the unconditional branch to TAKEN. */
|
||||||
if (TARGET_ABSOLUTE_JUMPS)
|
if (TARGET_ABSOLUTE_JUMPS && TARGET_CB_MAYBE)
|
||||||
|
{
|
||||||
|
/* Add a hazard nop. */
|
||||||
|
if (!final_sequence)
|
||||||
|
{
|
||||||
|
output_asm_insn ("nop\t\t# hazard nop", 0);
|
||||||
|
fprintf (asm_out_file, "\n");
|
||||||
|
}
|
||||||
|
output_asm_insn (MIPS_ABSOLUTE_JUMP ("bc\t%0"), &taken);
|
||||||
|
}
|
||||||
|
else if (TARGET_ABSOLUTE_JUMPS)
|
||||||
output_asm_insn (MIPS_ABSOLUTE_JUMP ("j\t%0%/"), &taken);
|
output_asm_insn (MIPS_ABSOLUTE_JUMP ("j\t%0%/"), &taken);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mips_output_load_label (taken);
|
mips_output_load_label (taken);
|
||||||
output_asm_insn ("jr\t%@%]%/", 0);
|
if (TARGET_CB_MAYBE)
|
||||||
|
output_asm_insn ("jrc\t%@%]", 0);
|
||||||
|
else
|
||||||
|
output_asm_insn ("jr\t%@%]%/", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now deal with its delay slot; see above. */
|
/* Now deal with its delay slot; see above. */
|
||||||
|
|
@ -13052,7 +13180,7 @@ mips_output_conditional_branch (rtx_insn *insn, rtx *operands,
|
||||||
asm_out_file, optimize, 1, NULL);
|
asm_out_file, optimize, 1, NULL);
|
||||||
final_sequence->insn (1)->set_deleted ();
|
final_sequence->insn (1)->set_deleted ();
|
||||||
}
|
}
|
||||||
else
|
else if (TARGET_CB_NEVER)
|
||||||
output_asm_insn ("nop", 0);
|
output_asm_insn ("nop", 0);
|
||||||
fprintf (asm_out_file, "\n");
|
fprintf (asm_out_file, "\n");
|
||||||
}
|
}
|
||||||
|
|
@ -13063,43 +13191,156 @@ mips_output_conditional_branch (rtx_insn *insn, rtx *operands,
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return the assembly code for INSN, which branches to OPERANDS[0]
|
||||||
|
if some equality condition is true. The condition is given by
|
||||||
|
OPERANDS[1] if !INVERTED_P, otherwise it is the inverse of
|
||||||
|
OPERANDS[1]. OPERANDS[2] is the comparison's first operand;
|
||||||
|
OPERANDS[3] is the second operand and may be zero or a register. */
|
||||||
|
|
||||||
|
const char *
|
||||||
|
mips_output_equal_conditional_branch (rtx_insn* insn, rtx *operands,
|
||||||
|
bool inverted_p)
|
||||||
|
{
|
||||||
|
const char *branch[2];
|
||||||
|
/* For a simple BNEZ or BEQZ microMIPSr3 branch. */
|
||||||
|
if (TARGET_MICROMIPS
|
||||||
|
&& mips_isa_rev <= 5
|
||||||
|
&& operands[3] == const0_rtx
|
||||||
|
&& get_attr_length (insn) <= 8)
|
||||||
|
{
|
||||||
|
if (mips_cb == MIPS_CB_OPTIMAL)
|
||||||
|
{
|
||||||
|
branch[!inverted_p] = "%*b%C1z%:\t%2,%0";
|
||||||
|
branch[inverted_p] = "%*b%N1z%:\t%2,%0";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
branch[!inverted_p] = "%*b%C1z\t%2,%0%/";
|
||||||
|
branch[inverted_p] = "%*b%N1z\t%2,%0%/";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (TARGET_CB_MAYBE)
|
||||||
|
{
|
||||||
|
if (operands[3] == const0_rtx)
|
||||||
|
{
|
||||||
|
branch[!inverted_p] = MIPS_BRANCH_C ("b%C1z", "%2,%0");
|
||||||
|
branch[inverted_p] = MIPS_BRANCH_C ("b%N1z", "%2,%0");
|
||||||
|
}
|
||||||
|
else if (REGNO (operands[2]) != REGNO (operands[3]))
|
||||||
|
{
|
||||||
|
branch[!inverted_p] = MIPS_BRANCH_C ("b%C1", "%2,%3,%0");
|
||||||
|
branch[inverted_p] = MIPS_BRANCH_C ("b%N1", "%2,%3,%0");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* This case is degenerate. It should not happen, but does. */
|
||||||
|
if (GET_CODE (operands[1]) == NE)
|
||||||
|
inverted_p = !inverted_p;
|
||||||
|
|
||||||
|
branch[!inverted_p] = MIPS_BRANCH_C ("b", "%0");
|
||||||
|
branch[inverted_p] = "%*\t\t# branch never";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
branch[!inverted_p] = MIPS_BRANCH ("b%C1", "%2,%z3,%0");
|
||||||
|
branch[inverted_p] = MIPS_BRANCH ("b%N1", "%2,%z3,%0");
|
||||||
|
}
|
||||||
|
|
||||||
|
return mips_output_conditional_branch (insn, operands, branch[1], branch[0]);
|
||||||
|
}
|
||||||
|
|
||||||
/* Return the assembly code for INSN, which branches to OPERANDS[0]
|
/* Return the assembly code for INSN, which branches to OPERANDS[0]
|
||||||
if some ordering condition is true. The condition is given by
|
if some ordering condition is true. The condition is given by
|
||||||
OPERANDS[1] if !INVERTED_P, otherwise it is the inverse of
|
OPERANDS[1] if !INVERTED_P, otherwise it is the inverse of
|
||||||
OPERANDS[1]. OPERANDS[2] is the comparison's first operand;
|
OPERANDS[1]. OPERANDS[2] is the comparison's first operand;
|
||||||
its second is always zero. */
|
OPERANDS[3] is the second operand and may be zero or a register. */
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
mips_output_order_conditional_branch (rtx_insn *insn, rtx *operands, bool inverted_p)
|
mips_output_order_conditional_branch (rtx_insn *insn, rtx *operands,
|
||||||
|
bool inverted_p)
|
||||||
{
|
{
|
||||||
const char *branch[2];
|
const char *branch[2];
|
||||||
|
|
||||||
/* Make BRANCH[1] branch to OPERANDS[0] when the condition is true.
|
/* Make BRANCH[1] branch to OPERANDS[0] when the condition is true.
|
||||||
Make BRANCH[0] branch on the inverse condition. */
|
Make BRANCH[0] branch on the inverse condition. */
|
||||||
switch (GET_CODE (operands[1]))
|
if (operands[3] != const0_rtx)
|
||||||
{
|
{
|
||||||
/* These cases are equivalent to comparisons against zero. */
|
/* Handle degenerate cases that should not, but do, occur. */
|
||||||
case LEU:
|
if (REGNO (operands[2]) == REGNO (operands[3]))
|
||||||
inverted_p = !inverted_p;
|
{
|
||||||
/* Fall through. */
|
switch (GET_CODE (operands[1]))
|
||||||
case GTU:
|
{
|
||||||
branch[!inverted_p] = MIPS_BRANCH ("bne", "%2,%.,%0");
|
case LT:
|
||||||
branch[inverted_p] = MIPS_BRANCH ("beq", "%2,%.,%0");
|
case LTU:
|
||||||
break;
|
inverted_p = !inverted_p;
|
||||||
|
/* Fall through. */
|
||||||
|
case GE:
|
||||||
|
case GEU:
|
||||||
|
branch[!inverted_p] = MIPS_BRANCH_C ("b", "%0");
|
||||||
|
branch[inverted_p] = "%*\t\t# branch never";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
gcc_unreachable ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
branch[!inverted_p] = MIPS_BRANCH_C ("b%C1", "%2,%3,%0");
|
||||||
|
branch[inverted_p] = MIPS_BRANCH_C ("b%N1", "%2,%3,%0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (GET_CODE (operands[1]))
|
||||||
|
{
|
||||||
|
/* These cases are equivalent to comparisons against zero. */
|
||||||
|
case LEU:
|
||||||
|
inverted_p = !inverted_p;
|
||||||
|
/* Fall through. */
|
||||||
|
case GTU:
|
||||||
|
if (TARGET_CB_MAYBE)
|
||||||
|
{
|
||||||
|
branch[!inverted_p] = MIPS_BRANCH_C ("bnez", "%2,%0");
|
||||||
|
branch[inverted_p] = MIPS_BRANCH_C ("beqz", "%2,%0");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
branch[!inverted_p] = MIPS_BRANCH ("bne", "%2,%.,%0");
|
||||||
|
branch[inverted_p] = MIPS_BRANCH ("beq", "%2,%.,%0");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
/* These cases are always true or always false. */
|
/* These cases are always true or always false. */
|
||||||
case LTU:
|
case LTU:
|
||||||
inverted_p = !inverted_p;
|
inverted_p = !inverted_p;
|
||||||
/* Fall through. */
|
/* Fall through. */
|
||||||
case GEU:
|
case GEU:
|
||||||
branch[!inverted_p] = MIPS_BRANCH ("beq", "%.,%.,%0");
|
if (TARGET_CB_MAYBE)
|
||||||
branch[inverted_p] = MIPS_BRANCH ("bne", "%.,%.,%0");
|
{
|
||||||
break;
|
branch[!inverted_p] = MIPS_BRANCH_C ("b", "%0");
|
||||||
|
branch[inverted_p] = "%*\t\t# branch never";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
branch[!inverted_p] = MIPS_BRANCH ("beq", "%.,%.,%0");
|
||||||
|
branch[inverted_p] = MIPS_BRANCH ("bne", "%.,%.,%0");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
branch[!inverted_p] = MIPS_BRANCH ("b%C1z", "%2,%0");
|
if (TARGET_CB_MAYBE)
|
||||||
branch[inverted_p] = MIPS_BRANCH ("b%N1z", "%2,%0");
|
{
|
||||||
break;
|
branch[!inverted_p] = MIPS_BRANCH_C ("b%C1z", "%2,%0");
|
||||||
|
branch[inverted_p] = MIPS_BRANCH_C ("b%N1z", "%2,%0");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
branch[!inverted_p] = MIPS_BRANCH ("b%C1z", "%2,%0");
|
||||||
|
branch[inverted_p] = MIPS_BRANCH ("b%N1z", "%2,%0");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return mips_output_conditional_branch (insn, operands, branch[1], branch[0]);
|
return mips_output_conditional_branch (insn, operands, branch[1], branch[0]);
|
||||||
}
|
}
|
||||||
|
|
@ -13302,11 +13543,18 @@ mips_process_sync_loop (rtx_insn *insn, rtx *operands)
|
||||||
at, oldval, inclusive_mask, NULL);
|
at, oldval, inclusive_mask, NULL);
|
||||||
tmp1 = at;
|
tmp1 = at;
|
||||||
}
|
}
|
||||||
mips_multi_add_insn ("bne\t%0,%z1,2f", tmp1, required_oldval, NULL);
|
if (TARGET_CB_NEVER)
|
||||||
|
mips_multi_add_insn ("bne\t%0,%z1,2f", tmp1, required_oldval, NULL);
|
||||||
|
|
||||||
/* CMP = 0 [delay slot]. */
|
/* CMP = 0 [delay slot]. */
|
||||||
if (cmp)
|
if (cmp)
|
||||||
mips_multi_add_insn ("li\t%0,0", cmp, NULL);
|
mips_multi_add_insn ("li\t%0,0", cmp, NULL);
|
||||||
|
|
||||||
|
if (TARGET_CB_MAYBE && required_oldval == const0_rtx)
|
||||||
|
mips_multi_add_insn ("bnezc\t%0,2f", tmp1, NULL);
|
||||||
|
else if (TARGET_CB_MAYBE)
|
||||||
|
mips_multi_add_insn ("bnec\t%0,%1,2f", tmp1, required_oldval, NULL);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* $TMP1 = OLDVAL & EXCLUSIVE_MASK. */
|
/* $TMP1 = OLDVAL & EXCLUSIVE_MASK. */
|
||||||
|
|
@ -13369,7 +13617,10 @@ mips_process_sync_loop (rtx_insn *insn, rtx *operands)
|
||||||
be annulled. To ensure this behaviour unconditionally use a NOP
|
be annulled. To ensure this behaviour unconditionally use a NOP
|
||||||
in the delay slot for the branch likely case. */
|
in the delay slot for the branch likely case. */
|
||||||
|
|
||||||
mips_multi_add_insn ("beq%?\t%0,%.,1b%~", at, NULL);
|
if (TARGET_CB_MAYBE)
|
||||||
|
mips_multi_add_insn ("beqzc\t%0,1b", at, NULL);
|
||||||
|
else
|
||||||
|
mips_multi_add_insn ("beq%?\t%0,%.,1b%~", at, NULL);
|
||||||
|
|
||||||
/* if (INSN1 != MOVE && INSN1 != LI) NEWVAL = $TMP3 [delay slot]. */
|
/* if (INSN1 != MOVE && INSN1 != LI) NEWVAL = $TMP3 [delay slot]. */
|
||||||
if (insn1 != SYNC_INSN1_MOVE && insn1 != SYNC_INSN1_LI && tmp3 != newval)
|
if (insn1 != SYNC_INSN1_MOVE && insn1 != SYNC_INSN1_LI && tmp3 != newval)
|
||||||
|
|
@ -16651,7 +16902,7 @@ mips_orphaned_high_part_p (mips_offset_table *htab, rtx_insn *insn)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mips_avoid_hazard (rtx_insn *after, rtx_insn *insn, int *hilo_delay,
|
mips_avoid_hazard (rtx_insn *after, rtx_insn *insn, int *hilo_delay,
|
||||||
rtx *delayed_reg, rtx lo_reg)
|
rtx *delayed_reg, rtx lo_reg, bool *fs_delay)
|
||||||
{
|
{
|
||||||
rtx pattern, set;
|
rtx pattern, set;
|
||||||
int nops, ninsns;
|
int nops, ninsns;
|
||||||
|
|
@ -16677,6 +16928,15 @@ mips_avoid_hazard (rtx_insn *after, rtx_insn *insn, int *hilo_delay,
|
||||||
nops = 2 - *hilo_delay;
|
nops = 2 - *hilo_delay;
|
||||||
else if (*delayed_reg != 0 && reg_referenced_p (*delayed_reg, pattern))
|
else if (*delayed_reg != 0 && reg_referenced_p (*delayed_reg, pattern))
|
||||||
nops = 1;
|
nops = 1;
|
||||||
|
/* If processing a forbidden slot hazard then a NOP is required if the
|
||||||
|
branch instruction was not in a sequence (as the sequence would
|
||||||
|
imply it is not actually a compact branch anyway) and the current
|
||||||
|
insn is not an inline asm, and can't go in a delay slot. */
|
||||||
|
else if (*fs_delay && get_attr_can_delay (insn) == CAN_DELAY_NO
|
||||||
|
&& GET_CODE (PATTERN (after)) != SEQUENCE
|
||||||
|
&& GET_CODE (pattern) != ASM_INPUT
|
||||||
|
&& asm_noperands (pattern) < 0)
|
||||||
|
nops = 1;
|
||||||
else
|
else
|
||||||
nops = 0;
|
nops = 0;
|
||||||
|
|
||||||
|
|
@ -16689,12 +16949,18 @@ mips_avoid_hazard (rtx_insn *after, rtx_insn *insn, int *hilo_delay,
|
||||||
/* Set up the state for the next instruction. */
|
/* Set up the state for the next instruction. */
|
||||||
*hilo_delay += ninsns;
|
*hilo_delay += ninsns;
|
||||||
*delayed_reg = 0;
|
*delayed_reg = 0;
|
||||||
|
*fs_delay = false;
|
||||||
if (INSN_CODE (insn) >= 0)
|
if (INSN_CODE (insn) >= 0)
|
||||||
switch (get_attr_hazard (insn))
|
switch (get_attr_hazard (insn))
|
||||||
{
|
{
|
||||||
case HAZARD_NONE:
|
case HAZARD_NONE:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case HAZARD_FORBIDDEN_SLOT:
|
||||||
|
if (TARGET_CB_MAYBE)
|
||||||
|
*fs_delay = true;
|
||||||
|
break;
|
||||||
|
|
||||||
case HAZARD_HILO:
|
case HAZARD_HILO:
|
||||||
*hilo_delay = 0;
|
*hilo_delay = 0;
|
||||||
break;
|
break;
|
||||||
|
|
@ -16718,6 +16984,7 @@ mips_reorg_process_insns (void)
|
||||||
rtx_insn *insn, *last_insn, *subinsn, *next_insn;
|
rtx_insn *insn, *last_insn, *subinsn, *next_insn;
|
||||||
rtx lo_reg, delayed_reg;
|
rtx lo_reg, delayed_reg;
|
||||||
int hilo_delay;
|
int hilo_delay;
|
||||||
|
bool fs_delay;
|
||||||
|
|
||||||
/* Force all instructions to be split into their final form. */
|
/* Force all instructions to be split into their final form. */
|
||||||
split_all_insns_noflow ();
|
split_all_insns_noflow ();
|
||||||
|
|
@ -16786,6 +17053,7 @@ mips_reorg_process_insns (void)
|
||||||
hilo_delay = 2;
|
hilo_delay = 2;
|
||||||
delayed_reg = 0;
|
delayed_reg = 0;
|
||||||
lo_reg = gen_rtx_REG (SImode, LO_REGNUM);
|
lo_reg = gen_rtx_REG (SImode, LO_REGNUM);
|
||||||
|
fs_delay = false;
|
||||||
|
|
||||||
/* Make a second pass over the instructions. Delete orphaned
|
/* Make a second pass over the instructions. Delete orphaned
|
||||||
high-part relocations or turn them into NOPs. Avoid hazards
|
high-part relocations or turn them into NOPs. Avoid hazards
|
||||||
|
|
@ -16809,7 +17077,7 @@ mips_reorg_process_insns (void)
|
||||||
INSN_CODE (subinsn) = CODE_FOR_nop;
|
INSN_CODE (subinsn) = CODE_FOR_nop;
|
||||||
}
|
}
|
||||||
mips_avoid_hazard (last_insn, subinsn, &hilo_delay,
|
mips_avoid_hazard (last_insn, subinsn, &hilo_delay,
|
||||||
&delayed_reg, lo_reg);
|
&delayed_reg, lo_reg, &fs_delay);
|
||||||
}
|
}
|
||||||
last_insn = insn;
|
last_insn = insn;
|
||||||
}
|
}
|
||||||
|
|
@ -16830,7 +17098,7 @@ mips_reorg_process_insns (void)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mips_avoid_hazard (last_insn, insn, &hilo_delay,
|
mips_avoid_hazard (last_insn, insn, &hilo_delay,
|
||||||
&delayed_reg, lo_reg);
|
&delayed_reg, lo_reg, &fs_delay);
|
||||||
last_insn = insn;
|
last_insn = insn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -17695,6 +17963,27 @@ mips_option_override (void)
|
||||||
target_flags |= MASK_ODD_SPREG;
|
target_flags |= MASK_ODD_SPREG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!ISA_HAS_COMPACT_BRANCHES && mips_cb == MIPS_CB_ALWAYS)
|
||||||
|
{
|
||||||
|
error ("unsupported combination: %qs%s %s",
|
||||||
|
mips_arch_info->name, TARGET_MICROMIPS ? " -mmicromips" : "",
|
||||||
|
"-mcompact-branches=always");
|
||||||
|
}
|
||||||
|
else if (!ISA_HAS_DELAY_SLOTS && mips_cb == MIPS_CB_NEVER)
|
||||||
|
{
|
||||||
|
error ("unsupported combination: %qs%s %s",
|
||||||
|
mips_arch_info->name, TARGET_MICROMIPS ? " -mmicromips" : "",
|
||||||
|
"-mcompact-branches=never");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Require explicit relocs for MIPS R6 onwards. This enables simplification
|
||||||
|
of the compact branch and jump support through the backend. */
|
||||||
|
if (!TARGET_EXPLICIT_RELOCS && mips_isa_rev >= 6)
|
||||||
|
{
|
||||||
|
error ("unsupported combination: %qs %s",
|
||||||
|
mips_arch_info->name, "-mno-explicit-relocs");
|
||||||
|
}
|
||||||
|
|
||||||
/* The effect of -mabicalls isn't defined for the EABI. */
|
/* The effect of -mabicalls isn't defined for the EABI. */
|
||||||
if (mips_abi == ABI_EABI && TARGET_ABICALLS)
|
if (mips_abi == ABI_EABI && TARGET_ABICALLS)
|
||||||
{
|
{
|
||||||
|
|
@ -18714,6 +19003,18 @@ mips_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
|
||||||
|
|
||||||
#undef OP
|
#undef OP
|
||||||
|
|
||||||
|
/* If we are using compact branches we don't have delay slots so
|
||||||
|
place the instruction that was in the delay slot before the JRC
|
||||||
|
instruction. */
|
||||||
|
|
||||||
|
if (TARGET_CB_ALWAYS)
|
||||||
|
{
|
||||||
|
rtx temp;
|
||||||
|
temp = trampoline[i-2];
|
||||||
|
trampoline[i-2] = trampoline[i-1];
|
||||||
|
trampoline[i-1] = temp;
|
||||||
|
}
|
||||||
|
|
||||||
/* Copy the trampoline code. Leave any padding uninitialized. */
|
/* Copy the trampoline code. Leave any padding uninitialized. */
|
||||||
for (j = 0; j < i; j++)
|
for (j = 0; j < i; j++)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,33 @@ struct mips_cpu_info {
|
||||||
/* True if we are generating position-independent VxWorks RTP code. */
|
/* True if we are generating position-independent VxWorks RTP code. */
|
||||||
#define TARGET_RTP_PIC (TARGET_VXWORKS_RTP && flag_pic)
|
#define TARGET_RTP_PIC (TARGET_VXWORKS_RTP && flag_pic)
|
||||||
|
|
||||||
|
/* Compact branches must not be used if the user either selects the
|
||||||
|
'never' policy or the 'optimal' policy on a core that lacks
|
||||||
|
compact branch instructions. */
|
||||||
|
#define TARGET_CB_NEVER (mips_cb == MIPS_CB_NEVER \
|
||||||
|
|| (mips_cb == MIPS_CB_OPTIMAL \
|
||||||
|
&& !ISA_HAS_COMPACT_BRANCHES))
|
||||||
|
|
||||||
|
/* Compact branches may be used if the user either selects the
|
||||||
|
'always' policy or the 'optimal' policy on a core that supports
|
||||||
|
compact branch instructions. */
|
||||||
|
#define TARGET_CB_MAYBE (TARGET_CB_ALWAYS \
|
||||||
|
|| (mips_cb == MIPS_CB_OPTIMAL \
|
||||||
|
&& ISA_HAS_COMPACT_BRANCHES))
|
||||||
|
|
||||||
|
/* Compact branches must always be generated if the user selects
|
||||||
|
the 'always' policy or the 'optimal' policy om a core that
|
||||||
|
lacks delay slot branch instructions. */
|
||||||
|
#define TARGET_CB_ALWAYS (mips_cb == MIPS_CB_ALWAYS \
|
||||||
|
|| (mips_cb == MIPS_CB_OPTIMAL \
|
||||||
|
&& !ISA_HAS_DELAY_SLOTS))
|
||||||
|
|
||||||
|
/* Special handling for JRC that exists in microMIPSR3 as well as R6
|
||||||
|
ISAs with full compact branch support. */
|
||||||
|
#define ISA_HAS_JRC ((ISA_HAS_COMPACT_BRANCHES \
|
||||||
|
|| TARGET_MICROMIPS) \
|
||||||
|
&& mips_cb != MIPS_CB_NEVER)
|
||||||
|
|
||||||
/* True if the output file is marked as ".abicalls; .option pic0"
|
/* True if the output file is marked as ".abicalls; .option pic0"
|
||||||
(-call_nonpic). */
|
(-call_nonpic). */
|
||||||
#define TARGET_ABICALLS_PIC0 \
|
#define TARGET_ABICALLS_PIC0 \
|
||||||
|
|
@ -872,6 +899,10 @@ struct mips_cpu_info {
|
||||||
|
|
||||||
#define ISA_HAS_JR (mips_isa_rev <= 5)
|
#define ISA_HAS_JR (mips_isa_rev <= 5)
|
||||||
|
|
||||||
|
#define ISA_HAS_DELAY_SLOTS 1
|
||||||
|
|
||||||
|
#define ISA_HAS_COMPACT_BRANCHES (mips_isa_rev >= 6)
|
||||||
|
|
||||||
/* ISA has branch likely instructions (e.g. mips2). */
|
/* ISA has branch likely instructions (e.g. mips2). */
|
||||||
/* Disable branchlikely for tx39 until compare rewrite. They haven't
|
/* Disable branchlikely for tx39 until compare rewrite. They haven't
|
||||||
been generated up to this point. */
|
been generated up to this point. */
|
||||||
|
|
@ -2645,6 +2676,9 @@ typedef struct mips_args {
|
||||||
#define MIPS_BRANCH(OPCODE, OPERANDS) \
|
#define MIPS_BRANCH(OPCODE, OPERANDS) \
|
||||||
"%*" OPCODE "%?\t" OPERANDS "%/"
|
"%*" OPCODE "%?\t" OPERANDS "%/"
|
||||||
|
|
||||||
|
#define MIPS_BRANCH_C(OPCODE, OPERANDS) \
|
||||||
|
"%*" OPCODE "%:\t" OPERANDS
|
||||||
|
|
||||||
/* Return an asm string that forces INSN to be treated as an absolute
|
/* Return an asm string that forces INSN to be treated as an absolute
|
||||||
J or JAL instruction instead of an assembler macro. */
|
J or JAL instruction instead of an assembler macro. */
|
||||||
#define MIPS_ABSOLUTE_JUMP(INSN) \
|
#define MIPS_ABSOLUTE_JUMP(INSN) \
|
||||||
|
|
@ -2652,45 +2686,6 @@ typedef struct mips_args {
|
||||||
? ".option\tpic0\n\t" INSN "\n\t.option\tpic2" \
|
? ".option\tpic0\n\t" INSN "\n\t.option\tpic2" \
|
||||||
: INSN)
|
: INSN)
|
||||||
|
|
||||||
/* Return the asm template for a call. INSN is the instruction's mnemonic
|
|
||||||
("j" or "jal"), OPERANDS are its operands, TARGET_OPNO is the operand
|
|
||||||
number of the target. SIZE_OPNO is the operand number of the argument size
|
|
||||||
operand that can optionally hold the call attributes. If SIZE_OPNO is not
|
|
||||||
-1 and the call is indirect, use the function symbol from the call
|
|
||||||
attributes to attach a R_MIPS_JALR relocation to the call.
|
|
||||||
|
|
||||||
When generating GOT code without explicit relocation operators,
|
|
||||||
all calls should use assembly macros. Otherwise, all indirect
|
|
||||||
calls should use "jr" or "jalr"; we will arrange to restore $gp
|
|
||||||
afterwards if necessary. Finally, we can only generate direct
|
|
||||||
calls for -mabicalls by temporarily switching to non-PIC mode.
|
|
||||||
|
|
||||||
For microMIPS jal(r), we try to generate jal(r)s when a 16-bit
|
|
||||||
instruction is in the delay slot of jal(r). */
|
|
||||||
#define MIPS_CALL(INSN, OPERANDS, TARGET_OPNO, SIZE_OPNO) \
|
|
||||||
(TARGET_USE_GOT && !TARGET_EXPLICIT_RELOCS \
|
|
||||||
? "%*" INSN "\t%" #TARGET_OPNO "%/" \
|
|
||||||
: REG_P (OPERANDS[TARGET_OPNO]) \
|
|
||||||
? (mips_get_pic_call_symbol (OPERANDS, SIZE_OPNO) \
|
|
||||||
? ("%*.reloc\t1f,R_MIPS_JALR,%" #SIZE_OPNO "\n" \
|
|
||||||
"1:\t" INSN "r\t%" #TARGET_OPNO "%/") \
|
|
||||||
: TARGET_MICROMIPS && !TARGET_INTERLINK_COMPRESSED \
|
|
||||||
? "%*" INSN "r%!\t%" #TARGET_OPNO "%/" \
|
|
||||||
: "%*" INSN "r\t%" #TARGET_OPNO "%/") \
|
|
||||||
: TARGET_MICROMIPS && !TARGET_INTERLINK_COMPRESSED \
|
|
||||||
? MIPS_ABSOLUTE_JUMP ("%*" INSN "%!\t%" #TARGET_OPNO "%/") \
|
|
||||||
: MIPS_ABSOLUTE_JUMP ("%*" INSN "\t%" #TARGET_OPNO "%/")) \
|
|
||||||
|
|
||||||
/* Similar to MIPS_CALL, but this is for MICROMIPS "j" to generate
|
|
||||||
"jrc" when nop is in the delay slot of "jr". */
|
|
||||||
|
|
||||||
#define MICROMIPS_J(INSN, OPERANDS, OPNO) \
|
|
||||||
(TARGET_USE_GOT && !TARGET_EXPLICIT_RELOCS \
|
|
||||||
? "%*j\t%" #OPNO "%/" \
|
|
||||||
: REG_P (OPERANDS[OPNO]) \
|
|
||||||
? "%*jr%:\t%" #OPNO \
|
|
||||||
: MIPS_ABSOLUTE_JUMP ("%*" INSN "\t%" #OPNO "%/"))
|
|
||||||
|
|
||||||
|
|
||||||
/* Control the assembler format that we output. */
|
/* Control the assembler format that we output. */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -409,6 +409,15 @@
|
||||||
(eq_attr "sync_mem" "!none") (const_string "syncloop")]
|
(eq_attr "sync_mem" "!none") (const_string "syncloop")]
|
||||||
(const_string "unknown")))
|
(const_string "unknown")))
|
||||||
|
|
||||||
|
(define_attr "compact_form" "always,maybe,never"
|
||||||
|
(cond [(eq_attr "jal" "direct")
|
||||||
|
(const_string "always")
|
||||||
|
(eq_attr "jal" "indirect")
|
||||||
|
(const_string "maybe")
|
||||||
|
(eq_attr "type" "jump")
|
||||||
|
(const_string "maybe")]
|
||||||
|
(const_string "never")))
|
||||||
|
|
||||||
;; Mode for conversion types (fcvt)
|
;; Mode for conversion types (fcvt)
|
||||||
;; I2S integer to float single (SI/DI to SF)
|
;; I2S integer to float single (SI/DI to SF)
|
||||||
;; I2D integer to float double (SI/DI to DF)
|
;; I2D integer to float double (SI/DI to DF)
|
||||||
|
|
@ -694,7 +703,7 @@
|
||||||
;; DELAY means that the next instruction cannot read the result
|
;; DELAY means that the next instruction cannot read the result
|
||||||
;; of this one. HILO means that the next two instructions cannot
|
;; of this one. HILO means that the next two instructions cannot
|
||||||
;; write to HI or LO.
|
;; write to HI or LO.
|
||||||
(define_attr "hazard" "none,delay,hilo"
|
(define_attr "hazard" "none,delay,hilo,forbidden_slot"
|
||||||
(cond [(and (eq_attr "type" "load,fpload,fpidxload")
|
(cond [(and (eq_attr "type" "load,fpload,fpidxload")
|
||||||
(match_test "ISA_HAS_LOAD_DELAY"))
|
(match_test "ISA_HAS_LOAD_DELAY"))
|
||||||
(const_string "delay")
|
(const_string "delay")
|
||||||
|
|
@ -1045,21 +1054,37 @@
|
||||||
(nil)
|
(nil)
|
||||||
(eq_attr "can_delay" "yes")])
|
(eq_attr "can_delay" "yes")])
|
||||||
|
|
||||||
;; Branches that don't have likely variants do not annul on false.
|
;; Branches that have delay slots and don't have likely variants do
|
||||||
|
;; not annul on false.
|
||||||
(define_delay (and (eq_attr "type" "branch")
|
(define_delay (and (eq_attr "type" "branch")
|
||||||
(not (match_test "TARGET_MIPS16"))
|
(not (match_test "TARGET_MIPS16"))
|
||||||
|
(ior (match_test "TARGET_CB_NEVER")
|
||||||
|
(and (eq_attr "compact_form" "maybe")
|
||||||
|
(not (match_test "TARGET_CB_ALWAYS")))
|
||||||
|
(eq_attr "compact_form" "never"))
|
||||||
(eq_attr "branch_likely" "no"))
|
(eq_attr "branch_likely" "no"))
|
||||||
[(eq_attr "can_delay" "yes")
|
[(eq_attr "can_delay" "yes")
|
||||||
(nil)
|
(nil)
|
||||||
(nil)])
|
(nil)])
|
||||||
|
|
||||||
(define_delay (eq_attr "type" "jump")
|
(define_delay (and (eq_attr "type" "jump")
|
||||||
|
(ior (match_test "TARGET_CB_NEVER")
|
||||||
|
(and (eq_attr "compact_form" "maybe")
|
||||||
|
(not (match_test "TARGET_CB_ALWAYS")))
|
||||||
|
(eq_attr "compact_form" "never")))
|
||||||
[(eq_attr "can_delay" "yes")
|
[(eq_attr "can_delay" "yes")
|
||||||
(nil)
|
(nil)
|
||||||
(nil)])
|
(nil)])
|
||||||
|
|
||||||
|
;; Call type instructions should never have a compact form as the
|
||||||
|
;; type is only used for MIPS16 patterns. For safety put the compact
|
||||||
|
;; branch detection condition in anyway.
|
||||||
(define_delay (and (eq_attr "type" "call")
|
(define_delay (and (eq_attr "type" "call")
|
||||||
(eq_attr "jal_macro" "no"))
|
(eq_attr "jal_macro" "no")
|
||||||
|
(ior (match_test "TARGET_CB_NEVER")
|
||||||
|
(and (eq_attr "compact_form" "maybe")
|
||||||
|
(not (match_test "TARGET_CB_ALWAYS")))
|
||||||
|
(eq_attr "compact_form" "never")))
|
||||||
[(eq_attr "can_delay" "yes")
|
[(eq_attr "can_delay" "yes")
|
||||||
(nil)
|
(nil)
|
||||||
(nil)])
|
(nil)])
|
||||||
|
|
@ -5813,25 +5838,29 @@
|
||||||
[(set (pc)
|
[(set (pc)
|
||||||
(if_then_else
|
(if_then_else
|
||||||
(match_operator 1 "order_operator"
|
(match_operator 1 "order_operator"
|
||||||
[(match_operand:GPR 2 "register_operand" "d")
|
[(match_operand:GPR 2 "register_operand" "d,d")
|
||||||
(const_int 0)])
|
(match_operand:GPR 3 "reg_or_0_operand" "J,d")])
|
||||||
(label_ref (match_operand 0 "" ""))
|
(label_ref (match_operand 0 "" ""))
|
||||||
(pc)))]
|
(pc)))]
|
||||||
"!TARGET_MIPS16"
|
"!TARGET_MIPS16"
|
||||||
{ return mips_output_order_conditional_branch (insn, operands, false); }
|
{ return mips_output_order_conditional_branch (insn, operands, false); }
|
||||||
[(set_attr "type" "branch")])
|
[(set_attr "type" "branch")
|
||||||
|
(set_attr "compact_form" "maybe,always")
|
||||||
|
(set_attr "hazard" "forbidden_slot")])
|
||||||
|
|
||||||
(define_insn "*branch_order<mode>_inverted"
|
(define_insn "*branch_order<mode>_inverted"
|
||||||
[(set (pc)
|
[(set (pc)
|
||||||
(if_then_else
|
(if_then_else
|
||||||
(match_operator 1 "order_operator"
|
(match_operator 1 "order_operator"
|
||||||
[(match_operand:GPR 2 "register_operand" "d")
|
[(match_operand:GPR 2 "register_operand" "d,d")
|
||||||
(const_int 0)])
|
(match_operand:GPR 3 "reg_or_0_operand" "J,d")])
|
||||||
(pc)
|
(pc)
|
||||||
(label_ref (match_operand 0 "" ""))))]
|
(label_ref (match_operand 0 "" ""))))]
|
||||||
"!TARGET_MIPS16"
|
"!TARGET_MIPS16"
|
||||||
{ return mips_output_order_conditional_branch (insn, operands, true); }
|
{ return mips_output_order_conditional_branch (insn, operands, true); }
|
||||||
[(set_attr "type" "branch")])
|
[(set_attr "type" "branch")
|
||||||
|
(set_attr "compact_form" "maybe,always")
|
||||||
|
(set_attr "hazard" "forbidden_slot")])
|
||||||
|
|
||||||
;; Conditional branch on equality comparison.
|
;; Conditional branch on equality comparison.
|
||||||
|
|
||||||
|
|
@ -5844,20 +5873,10 @@
|
||||||
(label_ref (match_operand 0 "" ""))
|
(label_ref (match_operand 0 "" ""))
|
||||||
(pc)))]
|
(pc)))]
|
||||||
"!TARGET_MIPS16"
|
"!TARGET_MIPS16"
|
||||||
{
|
{ return mips_output_equal_conditional_branch (insn, operands, false); }
|
||||||
/* For a simple BNEZ or BEQZ microMIPS branch. */
|
[(set_attr "type" "branch")
|
||||||
if (TARGET_MICROMIPS
|
(set_attr "compact_form" "maybe")
|
||||||
&& operands[3] == const0_rtx
|
(set_attr "hazard" "forbidden_slot")])
|
||||||
&& get_attr_length (insn) <= 8)
|
|
||||||
return mips_output_conditional_branch (insn, operands,
|
|
||||||
"%*b%C1z%:\t%2,%0",
|
|
||||||
"%*b%N1z%:\t%2,%0");
|
|
||||||
|
|
||||||
return mips_output_conditional_branch (insn, operands,
|
|
||||||
MIPS_BRANCH ("b%C1", "%2,%z3,%0"),
|
|
||||||
MIPS_BRANCH ("b%N1", "%2,%z3,%0"));
|
|
||||||
}
|
|
||||||
[(set_attr "type" "branch")])
|
|
||||||
|
|
||||||
(define_insn "*branch_equality<mode>_inverted"
|
(define_insn "*branch_equality<mode>_inverted"
|
||||||
[(set (pc)
|
[(set (pc)
|
||||||
|
|
@ -5868,20 +5887,10 @@
|
||||||
(pc)
|
(pc)
|
||||||
(label_ref (match_operand 0 "" ""))))]
|
(label_ref (match_operand 0 "" ""))))]
|
||||||
"!TARGET_MIPS16"
|
"!TARGET_MIPS16"
|
||||||
{
|
{ return mips_output_equal_conditional_branch (insn, operands, true); }
|
||||||
/* For a simple BNEZ or BEQZ microMIPS branch. */
|
[(set_attr "type" "branch")
|
||||||
if (TARGET_MICROMIPS
|
(set_attr "compact_form" "maybe")
|
||||||
&& operands[3] == const0_rtx
|
(set_attr "hazard" "forbidden_slot")])
|
||||||
&& get_attr_length (insn) <= 8)
|
|
||||||
return mips_output_conditional_branch (insn, operands,
|
|
||||||
"%*b%N0z%:\t%2,%1",
|
|
||||||
"%*b%C0z%:\t%2,%1");
|
|
||||||
|
|
||||||
return mips_output_conditional_branch (insn, operands,
|
|
||||||
MIPS_BRANCH ("b%N1", "%2,%z3,%0"),
|
|
||||||
MIPS_BRANCH ("b%C1", "%2,%z3,%0"));
|
|
||||||
}
|
|
||||||
[(set_attr "type" "branch")])
|
|
||||||
|
|
||||||
;; MIPS16 branches
|
;; MIPS16 branches
|
||||||
|
|
||||||
|
|
@ -6176,11 +6185,22 @@
|
||||||
"!TARGET_MIPS16 && TARGET_ABSOLUTE_JUMPS"
|
"!TARGET_MIPS16 && TARGET_ABSOLUTE_JUMPS"
|
||||||
{
|
{
|
||||||
if (get_attr_length (insn) <= 8)
|
if (get_attr_length (insn) <= 8)
|
||||||
return "%*b\t%l0%/";
|
{
|
||||||
|
if (TARGET_CB_MAYBE)
|
||||||
|
return MIPS_ABSOLUTE_JUMP ("%*b%:\t%l0");
|
||||||
|
else
|
||||||
|
return MIPS_ABSOLUTE_JUMP ("%*b\t%l0%/");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return MIPS_ABSOLUTE_JUMP ("%*j\t%l0%/");
|
{
|
||||||
|
if (TARGET_CB_MAYBE && !final_sequence)
|
||||||
|
return MIPS_ABSOLUTE_JUMP ("%*bc\t%l0");
|
||||||
|
else
|
||||||
|
return MIPS_ABSOLUTE_JUMP ("%*j\t%l0%/");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
[(set_attr "type" "branch")])
|
[(set_attr "type" "branch")
|
||||||
|
(set_attr "compact_form" "maybe")])
|
||||||
|
|
||||||
(define_insn "*jump_pic"
|
(define_insn "*jump_pic"
|
||||||
[(set (pc)
|
[(set (pc)
|
||||||
|
|
@ -6188,14 +6208,23 @@
|
||||||
"!TARGET_MIPS16 && !TARGET_ABSOLUTE_JUMPS"
|
"!TARGET_MIPS16 && !TARGET_ABSOLUTE_JUMPS"
|
||||||
{
|
{
|
||||||
if (get_attr_length (insn) <= 8)
|
if (get_attr_length (insn) <= 8)
|
||||||
return "%*b\t%l0%/";
|
{
|
||||||
|
if (TARGET_CB_MAYBE)
|
||||||
|
return "%*b%:\t%l0";
|
||||||
|
else
|
||||||
|
return "%*b\t%l0%/";
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mips_output_load_label (operands[0]);
|
mips_output_load_label (operands[0]);
|
||||||
return "%*jr\t%@%/%]";
|
if (TARGET_CB_MAYBE)
|
||||||
|
return "%*jr%:\t%@%]";
|
||||||
|
else
|
||||||
|
return "%*jr\t%@%/%]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
[(set_attr "type" "branch")])
|
[(set_attr "type" "branch")
|
||||||
|
(set_attr "compact_form" "maybe")])
|
||||||
|
|
||||||
;; We need a different insn for the mips16, because a mips16 branch
|
;; We need a different insn for the mips16, because a mips16 branch
|
||||||
;; does not have a delay slot.
|
;; does not have a delay slot.
|
||||||
|
|
@ -6242,12 +6271,9 @@
|
||||||
(define_insn "indirect_jump_<mode>"
|
(define_insn "indirect_jump_<mode>"
|
||||||
[(set (pc) (match_operand:P 0 "register_operand" "d"))]
|
[(set (pc) (match_operand:P 0 "register_operand" "d"))]
|
||||||
""
|
""
|
||||||
{
|
{
|
||||||
if (TARGET_MICROMIPS)
|
return mips_output_jump (operands, 0, -1, false);
|
||||||
return "%*jr%:\t%0";
|
}
|
||||||
else
|
|
||||||
return "%*j\t%0%/";
|
|
||||||
}
|
|
||||||
[(set_attr "type" "jump")
|
[(set_attr "type" "jump")
|
||||||
(set_attr "mode" "none")])
|
(set_attr "mode" "none")])
|
||||||
|
|
||||||
|
|
@ -6291,12 +6317,9 @@
|
||||||
(match_operand:P 0 "register_operand" "d"))
|
(match_operand:P 0 "register_operand" "d"))
|
||||||
(use (label_ref (match_operand 1 "" "")))]
|
(use (label_ref (match_operand 1 "" "")))]
|
||||||
""
|
""
|
||||||
{
|
{
|
||||||
if (TARGET_MICROMIPS)
|
return mips_output_jump (operands, 0, -1, false);
|
||||||
return "%*jr%:\t%0";
|
}
|
||||||
else
|
|
||||||
return "%*j\t%0%/";
|
|
||||||
}
|
|
||||||
[(set_attr "type" "jump")
|
[(set_attr "type" "jump")
|
||||||
(set_attr "mode" "none")])
|
(set_attr "mode" "none")])
|
||||||
|
|
||||||
|
|
@ -6508,10 +6531,8 @@
|
||||||
[(any_return)]
|
[(any_return)]
|
||||||
""
|
""
|
||||||
{
|
{
|
||||||
if (TARGET_MICROMIPS)
|
operands[0] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
|
||||||
return "%*jr%:\t$31";
|
return mips_output_jump (operands, 0, -1, false);
|
||||||
else
|
|
||||||
return "%*j\t$31%/";
|
|
||||||
}
|
}
|
||||||
[(set_attr "type" "jump")
|
[(set_attr "type" "jump")
|
||||||
(set_attr "mode" "none")])
|
(set_attr "mode" "none")])
|
||||||
|
|
@ -6522,12 +6543,10 @@
|
||||||
[(any_return)
|
[(any_return)
|
||||||
(use (match_operand 0 "pmode_register_operand" ""))]
|
(use (match_operand 0 "pmode_register_operand" ""))]
|
||||||
""
|
""
|
||||||
{
|
{
|
||||||
if (TARGET_MICROMIPS)
|
operands[0] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
|
||||||
return "%*jr%:\t%0";
|
return mips_output_jump (operands, 0, -1, false);
|
||||||
else
|
}
|
||||||
return "%*j\t%0%/";
|
|
||||||
}
|
|
||||||
[(set_attr "type" "jump")
|
[(set_attr "type" "jump")
|
||||||
(set_attr "mode" "none")])
|
(set_attr "mode" "none")])
|
||||||
|
|
||||||
|
|
@ -6783,12 +6802,7 @@
|
||||||
[(call (mem:SI (match_operand 0 "call_insn_operand" "j,S"))
|
[(call (mem:SI (match_operand 0 "call_insn_operand" "j,S"))
|
||||||
(match_operand 1 "" ""))]
|
(match_operand 1 "" ""))]
|
||||||
"TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
|
"TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
|
||||||
{
|
{ return mips_output_jump (operands, 0, 1, false); }
|
||||||
if (TARGET_MICROMIPS)
|
|
||||||
return MICROMIPS_J ("j", operands, 0);
|
|
||||||
else
|
|
||||||
return MIPS_CALL ("j", operands, 0, 1);
|
|
||||||
}
|
|
||||||
[(set_attr "jal" "indirect,direct")
|
[(set_attr "jal" "indirect,direct")
|
||||||
(set_attr "jal_macro" "no")])
|
(set_attr "jal_macro" "no")])
|
||||||
|
|
||||||
|
|
@ -6809,12 +6823,7 @@
|
||||||
(call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
|
(call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
|
||||||
(match_operand 2 "" "")))]
|
(match_operand 2 "" "")))]
|
||||||
"TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
|
"TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
|
||||||
{
|
{ return mips_output_jump (operands, 1, 2, false); }
|
||||||
if (TARGET_MICROMIPS)
|
|
||||||
return MICROMIPS_J ("j", operands, 1);
|
|
||||||
else
|
|
||||||
return MIPS_CALL ("j", operands, 1, 2);
|
|
||||||
}
|
|
||||||
[(set_attr "jal" "indirect,direct")
|
[(set_attr "jal" "indirect,direct")
|
||||||
(set_attr "jal_macro" "no")])
|
(set_attr "jal_macro" "no")])
|
||||||
|
|
||||||
|
|
@ -6826,12 +6835,7 @@
|
||||||
(call (mem:SI (match_dup 1))
|
(call (mem:SI (match_dup 1))
|
||||||
(match_dup 2)))]
|
(match_dup 2)))]
|
||||||
"TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
|
"TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
|
||||||
{
|
{ return mips_output_jump (operands, 1, 2, false); }
|
||||||
if (TARGET_MICROMIPS)
|
|
||||||
return MICROMIPS_J ("j", operands, 1);
|
|
||||||
else
|
|
||||||
return MIPS_CALL ("j", operands, 1, 2);
|
|
||||||
}
|
|
||||||
[(set_attr "jal" "indirect,direct")
|
[(set_attr "jal" "indirect,direct")
|
||||||
(set_attr "jal_macro" "no")])
|
(set_attr "jal_macro" "no")])
|
||||||
|
|
||||||
|
|
@ -6887,7 +6891,10 @@
|
||||||
(match_operand 1 "" ""))
|
(match_operand 1 "" ""))
|
||||||
(clobber (reg:SI RETURN_ADDR_REGNUM))]
|
(clobber (reg:SI RETURN_ADDR_REGNUM))]
|
||||||
""
|
""
|
||||||
{ return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 0, 1); }
|
{
|
||||||
|
return (TARGET_SPLIT_CALLS ? "#"
|
||||||
|
: mips_output_jump (operands, 0, 1, true));
|
||||||
|
}
|
||||||
"reload_completed && TARGET_SPLIT_CALLS"
|
"reload_completed && TARGET_SPLIT_CALLS"
|
||||||
[(const_int 0)]
|
[(const_int 0)]
|
||||||
{
|
{
|
||||||
|
|
@ -6902,7 +6909,7 @@
|
||||||
(clobber (reg:SI RETURN_ADDR_REGNUM))
|
(clobber (reg:SI RETURN_ADDR_REGNUM))
|
||||||
(clobber (reg:SI 28))]
|
(clobber (reg:SI 28))]
|
||||||
"TARGET_SPLIT_CALLS"
|
"TARGET_SPLIT_CALLS"
|
||||||
{ return MIPS_CALL ("jal", operands, 0, 1); }
|
{ return mips_output_jump (operands, 0, 1, true); }
|
||||||
[(set_attr "jal" "indirect,direct")
|
[(set_attr "jal" "indirect,direct")
|
||||||
(set_attr "jal_macro" "no")])
|
(set_attr "jal_macro" "no")])
|
||||||
|
|
||||||
|
|
@ -6916,7 +6923,10 @@
|
||||||
(const_int 1)
|
(const_int 1)
|
||||||
(clobber (reg:SI RETURN_ADDR_REGNUM))]
|
(clobber (reg:SI RETURN_ADDR_REGNUM))]
|
||||||
""
|
""
|
||||||
{ return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 0, -1); }
|
{
|
||||||
|
return (TARGET_SPLIT_CALLS ? "#"
|
||||||
|
: mips_output_jump (operands, 0, -1, true));
|
||||||
|
}
|
||||||
"reload_completed && TARGET_SPLIT_CALLS"
|
"reload_completed && TARGET_SPLIT_CALLS"
|
||||||
[(const_int 0)]
|
[(const_int 0)]
|
||||||
{
|
{
|
||||||
|
|
@ -6933,7 +6943,7 @@
|
||||||
(clobber (reg:SI RETURN_ADDR_REGNUM))
|
(clobber (reg:SI RETURN_ADDR_REGNUM))
|
||||||
(clobber (reg:SI 28))]
|
(clobber (reg:SI 28))]
|
||||||
"TARGET_SPLIT_CALLS"
|
"TARGET_SPLIT_CALLS"
|
||||||
{ return MIPS_CALL ("jal", operands, 0, -1); }
|
{ return mips_output_jump (operands, 0, -1, true); }
|
||||||
[(set_attr "jal" "direct")
|
[(set_attr "jal" "direct")
|
||||||
(set_attr "jal_macro" "no")])
|
(set_attr "jal_macro" "no")])
|
||||||
|
|
||||||
|
|
@ -6956,7 +6966,10 @@
|
||||||
(match_operand 2 "" "")))
|
(match_operand 2 "" "")))
|
||||||
(clobber (reg:SI RETURN_ADDR_REGNUM))]
|
(clobber (reg:SI RETURN_ADDR_REGNUM))]
|
||||||
""
|
""
|
||||||
{ return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1, 2); }
|
{
|
||||||
|
return (TARGET_SPLIT_CALLS ? "#"
|
||||||
|
: mips_output_jump (operands, 1, 2, true));
|
||||||
|
}
|
||||||
"reload_completed && TARGET_SPLIT_CALLS"
|
"reload_completed && TARGET_SPLIT_CALLS"
|
||||||
[(const_int 0)]
|
[(const_int 0)]
|
||||||
{
|
{
|
||||||
|
|
@ -6974,7 +6987,7 @@
|
||||||
(clobber (reg:SI RETURN_ADDR_REGNUM))
|
(clobber (reg:SI RETURN_ADDR_REGNUM))
|
||||||
(clobber (reg:SI 28))]
|
(clobber (reg:SI 28))]
|
||||||
"TARGET_SPLIT_CALLS"
|
"TARGET_SPLIT_CALLS"
|
||||||
{ return MIPS_CALL ("jal", operands, 1, 2); }
|
{ return mips_output_jump (operands, 1, 2, true); }
|
||||||
[(set_attr "jal" "indirect,direct")
|
[(set_attr "jal" "indirect,direct")
|
||||||
(set_attr "jal_macro" "no")])
|
(set_attr "jal_macro" "no")])
|
||||||
|
|
||||||
|
|
@ -6986,7 +6999,10 @@
|
||||||
(const_int 1)
|
(const_int 1)
|
||||||
(clobber (reg:SI RETURN_ADDR_REGNUM))]
|
(clobber (reg:SI RETURN_ADDR_REGNUM))]
|
||||||
""
|
""
|
||||||
{ return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1, -1); }
|
{
|
||||||
|
return (TARGET_SPLIT_CALLS ? "#"
|
||||||
|
: mips_output_jump (operands, 1, -1, true));
|
||||||
|
}
|
||||||
"reload_completed && TARGET_SPLIT_CALLS"
|
"reload_completed && TARGET_SPLIT_CALLS"
|
||||||
[(const_int 0)]
|
[(const_int 0)]
|
||||||
{
|
{
|
||||||
|
|
@ -7005,7 +7021,7 @@
|
||||||
(clobber (reg:SI RETURN_ADDR_REGNUM))
|
(clobber (reg:SI RETURN_ADDR_REGNUM))
|
||||||
(clobber (reg:SI 28))]
|
(clobber (reg:SI 28))]
|
||||||
"TARGET_SPLIT_CALLS"
|
"TARGET_SPLIT_CALLS"
|
||||||
{ return MIPS_CALL ("jal", operands, 1, -1); }
|
{ return mips_output_jump (operands, 1, -1, true); }
|
||||||
[(set_attr "jal" "direct")
|
[(set_attr "jal" "direct")
|
||||||
(set_attr "jal_macro" "no")])
|
(set_attr "jal_macro" "no")])
|
||||||
|
|
||||||
|
|
@ -7019,7 +7035,10 @@
|
||||||
(match_dup 2)))
|
(match_dup 2)))
|
||||||
(clobber (reg:SI RETURN_ADDR_REGNUM))]
|
(clobber (reg:SI RETURN_ADDR_REGNUM))]
|
||||||
""
|
""
|
||||||
{ return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1, 2); }
|
{
|
||||||
|
return (TARGET_SPLIT_CALLS ? "#"
|
||||||
|
: mips_output_jump (operands, 1, 2, true));
|
||||||
|
}
|
||||||
"reload_completed && TARGET_SPLIT_CALLS"
|
"reload_completed && TARGET_SPLIT_CALLS"
|
||||||
[(const_int 0)]
|
[(const_int 0)]
|
||||||
{
|
{
|
||||||
|
|
@ -7040,7 +7059,7 @@
|
||||||
(clobber (reg:SI RETURN_ADDR_REGNUM))
|
(clobber (reg:SI RETURN_ADDR_REGNUM))
|
||||||
(clobber (reg:SI 28))]
|
(clobber (reg:SI 28))]
|
||||||
"TARGET_SPLIT_CALLS"
|
"TARGET_SPLIT_CALLS"
|
||||||
{ return MIPS_CALL ("jal", operands, 1, 2); }
|
{ return mips_output_jump (operands, 1, 2, true); }
|
||||||
[(set_attr "jal" "indirect,direct")
|
[(set_attr "jal" "indirect,direct")
|
||||||
(set_attr "jal_macro" "no")])
|
(set_attr "jal_macro" "no")])
|
||||||
|
|
||||||
|
|
@ -7411,7 +7430,7 @@
|
||||||
(clobber (reg:P PIC_FUNCTION_ADDR_REGNUM))
|
(clobber (reg:P PIC_FUNCTION_ADDR_REGNUM))
|
||||||
(clobber (reg:P RETURN_ADDR_REGNUM))]
|
(clobber (reg:P RETURN_ADDR_REGNUM))]
|
||||||
"HAVE_AS_TLS && TARGET_MIPS16"
|
"HAVE_AS_TLS && TARGET_MIPS16"
|
||||||
{ return MIPS_CALL ("jal", operands, 0, -1); }
|
{ return mips_output_jump (operands, 0, -1, true); }
|
||||||
[(set_attr "type" "call")
|
[(set_attr "type" "call")
|
||||||
(set_attr "insn_count" "3")
|
(set_attr "insn_count" "3")
|
||||||
(set_attr "mode" "<MODE>")])
|
(set_attr "mode" "<MODE>")])
|
||||||
|
|
@ -7452,7 +7471,7 @@
|
||||||
(clobber (reg:P PIC_FUNCTION_ADDR_REGNUM))
|
(clobber (reg:P PIC_FUNCTION_ADDR_REGNUM))
|
||||||
(clobber (reg:P RETURN_ADDR_REGNUM))]
|
(clobber (reg:P RETURN_ADDR_REGNUM))]
|
||||||
"TARGET_HARD_FLOAT_ABI && TARGET_MIPS16"
|
"TARGET_HARD_FLOAT_ABI && TARGET_MIPS16"
|
||||||
{ return MIPS_CALL ("jal", operands, 0, -1); }
|
{ return mips_output_jump (operands, 0, -1, true); }
|
||||||
[(set_attr "type" "call")
|
[(set_attr "type" "call")
|
||||||
(set_attr "insn_count" "3")])
|
(set_attr "insn_count" "3")])
|
||||||
|
|
||||||
|
|
@ -7482,7 +7501,7 @@
|
||||||
(clobber (reg:P PIC_FUNCTION_ADDR_REGNUM))
|
(clobber (reg:P PIC_FUNCTION_ADDR_REGNUM))
|
||||||
(clobber (reg:P RETURN_ADDR_REGNUM))]
|
(clobber (reg:P RETURN_ADDR_REGNUM))]
|
||||||
"TARGET_HARD_FLOAT_ABI && TARGET_MIPS16"
|
"TARGET_HARD_FLOAT_ABI && TARGET_MIPS16"
|
||||||
{ return MIPS_CALL ("jal", operands, 0, -1); }
|
{ return mips_output_jump (operands, 0, -1, true); }
|
||||||
[(set_attr "type" "call")
|
[(set_attr "type" "call")
|
||||||
(set_attr "insn_count" "3")])
|
(set_attr "insn_count" "3")])
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -418,3 +418,20 @@ Driver
|
||||||
mload-store-pairs
|
mload-store-pairs
|
||||||
Target Report Var(TARGET_LOAD_STORE_PAIRS) Init(1)
|
Target Report Var(TARGET_LOAD_STORE_PAIRS) Init(1)
|
||||||
Enable load/store bonding.
|
Enable load/store bonding.
|
||||||
|
|
||||||
|
mcompact-branches=
|
||||||
|
Target RejectNegative JoinedOrMissing Var(mips_cb) Report Enum(mips_cb_setting) Init(MIPS_CB_OPTIMAL)
|
||||||
|
Specify the compact branch usage policy
|
||||||
|
|
||||||
|
Enum
|
||||||
|
Name(mips_cb_setting) Type(enum mips_cb_setting)
|
||||||
|
Policies available for use with -mcompact-branches=:
|
||||||
|
|
||||||
|
EnumValue
|
||||||
|
Enum(mips_cb_setting) String(never) Value(MIPS_CB_NEVER)
|
||||||
|
|
||||||
|
EnumValue
|
||||||
|
Enum(mips_cb_setting) String(optimal) Value(MIPS_CB_OPTIMAL)
|
||||||
|
|
||||||
|
EnumValue
|
||||||
|
Enum(mips_cb_setting) String(always) Value(MIPS_CB_ALWAYS)
|
||||||
|
|
|
||||||
|
|
@ -475,7 +475,18 @@
|
||||||
(match_code "eq,ne,lt,ltu,ge,geu"))
|
(match_code "eq,ne,lt,ltu,ge,geu"))
|
||||||
|
|
||||||
(define_predicate "order_operator"
|
(define_predicate "order_operator"
|
||||||
(match_code "lt,ltu,le,leu,ge,geu,gt,gtu"))
|
(match_code "lt,ltu,le,leu,ge,geu,gt,gtu")
|
||||||
|
{
|
||||||
|
if (XEXP (op, 1) == const0_rtx)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (TARGET_CB_MAYBE
|
||||||
|
&& (GET_CODE (op) == LT || GET_CODE (op) == LTU
|
||||||
|
|| GET_CODE (op) == GE || GET_CODE (op) == GEU))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
})
|
||||||
|
|
||||||
;; For NE, cstore uses sltu instructions in which the first operand is $0.
|
;; For NE, cstore uses sltu instructions in which the first operand is $0.
|
||||||
;; This isn't possible in mips16 code.
|
;; This isn't possible in mips16 code.
|
||||||
|
|
|
||||||
|
|
@ -782,6 +782,7 @@ Objective-C and Objective-C++ Dialects}.
|
||||||
-mgp32 -mgp64 -mfp32 -mfpxx -mfp64 -mhard-float -msoft-float @gol
|
-mgp32 -mgp64 -mfp32 -mfpxx -mfp64 -mhard-float -msoft-float @gol
|
||||||
-mno-float -msingle-float -mdouble-float @gol
|
-mno-float -msingle-float -mdouble-float @gol
|
||||||
-modd-spreg -mno-odd-spreg @gol
|
-modd-spreg -mno-odd-spreg @gol
|
||||||
|
-mcompact-branches=@var{policy} @gol
|
||||||
-mabs=@var{mode} -mnan=@var{encoding} @gol
|
-mabs=@var{mode} -mnan=@var{encoding} @gol
|
||||||
-mdsp -mno-dsp -mdspr2 -mno-dspr2 @gol
|
-mdsp -mno-dsp -mdspr2 -mno-dspr2 @gol
|
||||||
-mmcu -mmno-mcu @gol
|
-mmcu -mmno-mcu @gol
|
||||||
|
|
@ -17303,6 +17304,30 @@ for the o32 ABI. This is the default for processors that are known to
|
||||||
support these registers. When using the o32 FPXX ABI, @option{-mno-odd-spreg}
|
support these registers. When using the o32 FPXX ABI, @option{-mno-odd-spreg}
|
||||||
is set by default.
|
is set by default.
|
||||||
|
|
||||||
|
@item -mcompact-branches=never
|
||||||
|
@itemx -mcompact-branches=optimal
|
||||||
|
@itemx -mcompact-branches=always
|
||||||
|
@opindex mcompact-branches=never
|
||||||
|
@opindex mcompact-branches=optimal
|
||||||
|
@opindex mcompact-branches=always
|
||||||
|
These options control which form of branches will be generated. The
|
||||||
|
default is @option{-mcompact-branches=optimal}.
|
||||||
|
|
||||||
|
The @option{-mcompact-branches=never} option ensures that compact branch
|
||||||
|
instructions will never be generated.
|
||||||
|
|
||||||
|
The @option{-mcompact-branches=always} option ensures that a compact
|
||||||
|
branch instruction will be generated if available. If a compact branch
|
||||||
|
instruction is not available, a delay slot form of the branch will be
|
||||||
|
used instead.
|
||||||
|
|
||||||
|
This option is supported from MIPS Release 6 onwards.
|
||||||
|
|
||||||
|
The @option{-mcompact-branches=optimal} option will cause a delay slot
|
||||||
|
branch to be used if one is available in the current ISA and the delay
|
||||||
|
slot is successfully filled. If the delay slot is not filled, a compact
|
||||||
|
branch will be chosen if one is available.
|
||||||
|
|
||||||
@item -mabs=2008
|
@item -mabs=2008
|
||||||
@itemx -mabs=legacy
|
@itemx -mabs=legacy
|
||||||
@opindex mabs=2008
|
@opindex mabs=2008
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,42 @@
|
||||||
|
2015-09-01 Matthew Fortune <matthew.fortune@imgtec.com>
|
||||||
|
Andrew Bennett <andrew.bennett@imgtec.com>
|
||||||
|
|
||||||
|
* gcc.target/mips/mips.exp (mips-dg-options): Handle the
|
||||||
|
dependencies between ISA level and compact-branches.
|
||||||
|
* gcc.target/mips/branch-10.c: Update expected output to allow
|
||||||
|
compact forms of b/bal.
|
||||||
|
* gcc.target/mips/branch-11.c: Likewise.
|
||||||
|
* gcc.target/mips/branch-12.c: Likewise.
|
||||||
|
* gcc.target/mips/branch-13.c: Likewise.
|
||||||
|
* gcc.target/mips/branch-3.c: Likewise.
|
||||||
|
* gcc.target/mips/branch-4.c: Likewise.
|
||||||
|
* gcc.target/mips/branch-5.c: Likewise.
|
||||||
|
* gcc.target/mips/branch-6.c: Likewise.
|
||||||
|
* gcc.target/mips/branch-7.c: Likewise.
|
||||||
|
* gcc.target/mips/branch-8.c: Likewise.
|
||||||
|
* gcc.target/mips/branch-9.c: Likewise.
|
||||||
|
* gcc.target/mips/branch-cost-1.c: Likewise.
|
||||||
|
* gcc.target/mips/call-1.c: Likewise.
|
||||||
|
* gcc.target/mips/call-2.c: Likewise.
|
||||||
|
* gcc.target/mips/call-3.c: Likewise.
|
||||||
|
* gcc.target/mips/call-4.c: Likewise.
|
||||||
|
* gcc.target/mips/call-5.c: Likewise.
|
||||||
|
* gcc.target/mips/call-6.c: Likewise.
|
||||||
|
* gcc.target/mips/lazy-binding-1.c: Likewise.
|
||||||
|
* gcc.target/mips/near-far-1.c: Likewise.
|
||||||
|
* gcc.target/mips/near-far-2.c: Likewise.
|
||||||
|
* gcc.target/mips/near-far-3.c: Likewise.
|
||||||
|
* gcc.target/mips/near-far-4.c: Likewise.
|
||||||
|
* gcc.target/mips/umips-branch-3.c: Ensure the test is
|
||||||
|
run with compact branches allowed.
|
||||||
|
* gcc.target/mips/compact-branches-1.c: New file.
|
||||||
|
* gcc.target/mips/compact-branches-2.c: Likewise.
|
||||||
|
* gcc.target/mips/compact-branches-3.c: Likewise.
|
||||||
|
* gcc.target/mips/compact-branches-4.c: Likewise.
|
||||||
|
* gcc.target/mips/compact-branches-5.c: Likewise.
|
||||||
|
* gcc.target/mips/compact-branches-6.c: Likewise.
|
||||||
|
* gcc.target/mips/compact-branches-7.c: Likewise.
|
||||||
|
|
||||||
2015-09-01 Steven G. Kargl <kargl@gcc.gnu.org>
|
2015-09-01 Steven G. Kargl <kargl@gcc.gnu.org>
|
||||||
|
|
||||||
* gfortran.dg/read_dir.f90: XFAIL this testcase on FreeBSD.
|
* gfortran.dg/read_dir.f90: XFAIL this testcase on FreeBSD.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/* { dg-options "-mshared -mabi=n32" } */
|
/* { dg-options "-mshared -mabi=n32" } */
|
||||||
/* { dg-final { scan-assembler-not "(\\\$28|%gp_rel|%got)" } } */
|
/* { dg-final { scan-assembler-not "(\\\$28|%gp_rel|%got)" } } */
|
||||||
/* { dg-final { scan-assembler-not "\tjr\t\\\$1\n" } } */
|
/* { dg-final { scan-assembler-not "\tjrc?\t\\\$1\n" } } */
|
||||||
|
|
||||||
#include "branch-helper.h"
|
#include "branch-helper.h"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
/* { dg-final { scan-assembler "\taddiu\t\\\$28,\\\$28,%lo\\(%neg\\(%gp_rel\\(foo\\)\\)\\)\n" } } */
|
/* { dg-final { scan-assembler "\taddiu\t\\\$28,\\\$28,%lo\\(%neg\\(%gp_rel\\(foo\\)\\)\\)\n" } } */
|
||||||
/* { dg-final { scan-assembler "\tlw\t\\\$1,%got_page\\(\[^)\]*\\)\\(\\\$28\\)\n" } } */
|
/* { dg-final { scan-assembler "\tlw\t\\\$1,%got_page\\(\[^)\]*\\)\\(\\\$28\\)\n" } } */
|
||||||
/* { dg-final { scan-assembler "\taddiu\t\\\$1,\\\$1,%got_ofst\\(\[^)\]*\\)\n" } } */
|
/* { dg-final { scan-assembler "\taddiu\t\\\$1,\\\$1,%got_ofst\\(\[^)\]*\\)\n" } } */
|
||||||
/* { dg-final { scan-assembler "\tjr\t\\\$1\n" } } */
|
/* { dg-final { scan-assembler "\tjrc?\t\\\$1\n" } } */
|
||||||
|
|
||||||
#include "branch-helper.h"
|
#include "branch-helper.h"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/* { dg-options "-mshared -mabi=64" } */
|
/* { dg-options "-mshared -mabi=64" } */
|
||||||
/* { dg-final { scan-assembler-not "(\\\$28|%gp_rel|%got)" } } */
|
/* { dg-final { scan-assembler-not "(\\\$28|%gp_rel|%got)" } } */
|
||||||
/* { dg-final { scan-assembler-not "\tjr\t\\\$1\n" } } */
|
/* { dg-final { scan-assembler-not "\tjrc?\t\\\$1\n" } } */
|
||||||
|
|
||||||
#include "branch-helper.h"
|
#include "branch-helper.h"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
/* { dg-final { scan-assembler "\tdaddiu\t\\\$28,\\\$28,%lo\\(%neg\\(%gp_rel\\(foo\\)\\)\\)\n" } } */
|
/* { dg-final { scan-assembler "\tdaddiu\t\\\$28,\\\$28,%lo\\(%neg\\(%gp_rel\\(foo\\)\\)\\)\n" } } */
|
||||||
/* { dg-final { scan-assembler "\tld\t\\\$1,%got_page\\(\[^)\]*\\)\\(\\\$28\\)\n" } } */
|
/* { dg-final { scan-assembler "\tld\t\\\$1,%got_page\\(\[^)\]*\\)\\(\\\$28\\)\n" } } */
|
||||||
/* { dg-final { scan-assembler "\tdaddiu\t\\\$1,\\\$1,%got_ofst\\(\[^)\]*\\)\n" } } */
|
/* { dg-final { scan-assembler "\tdaddiu\t\\\$1,\\\$1,%got_ofst\\(\[^)\]*\\)\n" } } */
|
||||||
/* { dg-final { scan-assembler "\tjr\t\\\$1\n" } } */
|
/* { dg-final { scan-assembler "\tjrc?\t\\\$1\n" } } */
|
||||||
|
|
||||||
#include "branch-helper.h"
|
#include "branch-helper.h"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/* { dg-options "-mshared -mabi=32" } */
|
/* { dg-options "-mshared -mabi=32" } */
|
||||||
/* { dg-final { scan-assembler "\t\\.cpload\t\\\$25\n" } } */
|
/* { dg-final { scan-assembler "\t\\.cpload\t\\\$25\n" } } */
|
||||||
/* { dg-final { scan-assembler "\tjr\t\\\$1\n" } } */
|
/* { dg-final { scan-assembler "\tjrc?\t\\\$1\n" } } */
|
||||||
/* { dg-final { scan-assembler-not "\\.cprestore" } } */
|
/* { dg-final { scan-assembler-not "\\.cprestore" } } */
|
||||||
|
|
||||||
#include "branch-helper.h"
|
#include "branch-helper.h"
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/* { dg-options "-mshared -mabi=n32" } */
|
/* { dg-options "-mshared -mabi=n32" } */
|
||||||
/* { dg-final { scan-assembler-not "(\\\$25|\\\$28|%gp_rel|%got)" } } */
|
/* { dg-final { scan-assembler-not "(\\\$25|\\\$28|%gp_rel|%got)" } } */
|
||||||
/* { dg-final { scan-assembler-not "\tjr\t\\\$1\n" } } */
|
/* { dg-final { scan-assembler-not "\tjrc?\t\\\$1\n" } } */
|
||||||
|
|
||||||
#include "branch-helper.h"
|
#include "branch-helper.h"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/* { dg-options "-mshared -mabi=n32" } */
|
/* { dg-options "-mshared -mabi=n32" } */
|
||||||
/* { dg-final { scan-assembler "\taddiu\t\\\$3,\\\$3,%lo\\(%neg\\(%gp_rel\\(foo\\)\\)\\)\n" } } */
|
/* { dg-final { scan-assembler "\taddiu\t\\\$3,\\\$3,%lo\\(%neg\\(%gp_rel\\(foo\\)\\)\\)\n" } } */
|
||||||
/* { dg-final { scan-assembler "\tlw\t\\\$1,%got_page\\(\[^)\]*\\)\\(\\\$3\\)\\n" } } */
|
/* { dg-final { scan-assembler "\tlw\t\\\$1,%got_page\\(\[^)\]*\\)\\(\\\$3\\)\\n" } } */
|
||||||
/* { dg-final { scan-assembler "\tjr\t\\\$1\n" } } */
|
/* { dg-final { scan-assembler "\tjrc?\t\\\$1\n" } } */
|
||||||
/* { dg-final { scan-assembler-not "\\\$28" } } */
|
/* { dg-final { scan-assembler-not "\\\$28" } } */
|
||||||
|
|
||||||
#include "branch-helper.h"
|
#include "branch-helper.h"
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/* { dg-options "-mshared -mabi=64" } */
|
/* { dg-options "-mshared -mabi=64" } */
|
||||||
/* { dg-final { scan-assembler-not "(\\\$25|\\\$28|%gp_rel|%got)" } } */
|
/* { dg-final { scan-assembler-not "(\\\$25|\\\$28|%gp_rel|%got)" } } */
|
||||||
/* { dg-final { scan-assembler-not "\tjr\t\\\$1\n" } } */
|
/* { dg-final { scan-assembler-not "\tjrc?\t\\\$1\n" } } */
|
||||||
|
|
||||||
#include "branch-helper.h"
|
#include "branch-helper.h"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/* { dg-options "-mshared -mabi=64" } */
|
/* { dg-options "-mshared -mabi=64" } */
|
||||||
/* { dg-final { scan-assembler "\tdaddiu\t\\\$3,\\\$3,%lo\\(%neg\\(%gp_rel\\(foo\\)\\)\\)\n" } } */
|
/* { dg-final { scan-assembler "\tdaddiu\t\\\$3,\\\$3,%lo\\(%neg\\(%gp_rel\\(foo\\)\\)\\)\n" } } */
|
||||||
/* { dg-final { scan-assembler "\tld\t\\\$1,%got_page\\(\[^)\]*\\)\\(\\\$3\\)\\n" } } */
|
/* { dg-final { scan-assembler "\tld\t\\\$1,%got_page\\(\[^)\]*\\)\\(\\\$3\\)\\n" } } */
|
||||||
/* { dg-final { scan-assembler "\tjr\t\\\$1\n" } } */
|
/* { dg-final { scan-assembler "\tjrc?\t\\\$1\n" } } */
|
||||||
/* { dg-final { scan-assembler-not "\\\$28" } } */
|
/* { dg-final { scan-assembler-not "\\\$28" } } */
|
||||||
|
|
||||||
#include "branch-helper.h"
|
#include "branch-helper.h"
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/* { dg-options "-mshared -mabi=32" } */
|
/* { dg-options "-mshared -mabi=32" } */
|
||||||
/* { dg-final { scan-assembler-not "(\\\$28|cpload|cprestore)" } } */
|
/* { dg-final { scan-assembler-not "(\\\$28|cpload|cprestore)" } } */
|
||||||
/* { dg-final { scan-assembler-not "\tjr\t\\\$1\n" } } */
|
/* { dg-final { scan-assembler-not "\tjrc?\t\\\$1\n" } } */
|
||||||
|
|
||||||
#include "branch-helper.h"
|
#include "branch-helper.h"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
/* { dg-final { scan-assembler "\tlw\t\\\$1,16\\(\\\$(fp|sp)\\)\n" } } */
|
/* { dg-final { scan-assembler "\tlw\t\\\$1,16\\(\\\$(fp|sp)\\)\n" } } */
|
||||||
/* { dg-final { scan-assembler "\tlw\t\\\$1,%got\\(\[^)\]*\\)\\(\\\$1\\)\n" } } */
|
/* { dg-final { scan-assembler "\tlw\t\\\$1,%got\\(\[^)\]*\\)\\(\\\$1\\)\n" } } */
|
||||||
/* { dg-final { scan-assembler "\taddiu\t\\\$1,\\\$1,%lo\\(\[^)\]*\\)\n" } } */
|
/* { dg-final { scan-assembler "\taddiu\t\\\$1,\\\$1,%lo\\(\[^)\]*\\)\n" } } */
|
||||||
/* { dg-final { scan-assembler "\tjr\t\\\$1\n" } } */
|
/* { dg-final { scan-assembler "\tjrc?\t\\\$1\n" } } */
|
||||||
/* { dg-final { scan-assembler-not "\\\$28" } } */
|
/* { dg-final { scan-assembler-not "\\\$28" } } */
|
||||||
|
|
||||||
#include "branch-helper.h"
|
#include "branch-helper.h"
|
||||||
|
|
|
||||||
|
|
@ -6,4 +6,4 @@ foo (int x, int y, int z, int k)
|
||||||
return x == k ? x + y : z - x;
|
return x == k ? x + y : z - x;
|
||||||
}
|
}
|
||||||
/* { dg-final { scan-assembler-not "\t(movz|movn)\t" } } */
|
/* { dg-final { scan-assembler-not "\t(movz|movn)\t" } } */
|
||||||
/* { dg-final { scan-assembler "\t(bne|beq)\t" } } */
|
/* { dg-final { scan-assembler "\t(bnec?|beqc?)\t" } } */
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
/* { dg-options "-mrelax-pic-calls -mshared -foptimize-sibling-calls -mabi=32" } */
|
/* { dg-options "-mrelax-pic-calls -mshared -foptimize-sibling-calls -mabi=32" } */
|
||||||
/* { dg-skip-if "requires -foptimize-sibling-calls" { *-*-* } { "-O0" } { "" } } */
|
/* { dg-skip-if "requires -foptimize-sibling-calls" { *-*-* } { "-O0" } { "" } } */
|
||||||
/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,normal\n1:\tjalrs?\t" } } */
|
/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,normal\n1:\tjalrc?s?\t" } } */
|
||||||
/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,normal2\n1:\tjalrs?\t" } } */
|
/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,normal2\n1:\tjalrc?s?\t" } } */
|
||||||
/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,staticfunc\n1:\tjalrs?\t" } } */
|
/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,staticfunc\n1:\tjalrc?s?\t" } } */
|
||||||
/* { dg-final { scan-assembler "(\\.reloc\t1f,R_MIPS_JALR,tail\n1:)?\tjrc?\t" } } */
|
/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,tail\n1:\tjrc?\t" } } */
|
||||||
/* { dg-final { scan-assembler "(\\.reloc\t1f,R_MIPS_JALR,tail2\n1:)?\tjrc?\t" } } */
|
/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,tail2\n1:\tjrc?\t" } } */
|
||||||
/* { dg-final { scan-assembler "(\\.reloc\t1f,R_MIPS_JALR,tail3\n1:)?\tjrc?\t" } } */
|
/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,tail3\n1:\tjrc?\t" } } */
|
||||||
/* { dg-final { scan-assembler "(\\.reloc\t1f,R_MIPS_JALR,tail4\n1:)?\tjrc?\t" } } */
|
/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,tail4\n1:\tjrc?\t" } } */
|
||||||
|
|
||||||
__attribute__ ((noinline)) static void staticfunc () { asm (""); }
|
__attribute__ ((noinline)) static void staticfunc () { asm (""); }
|
||||||
int normal ();
|
int normal ();
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/* See through some simple data-flow. */
|
/* See through some simple data-flow. */
|
||||||
/* { dg-options "-mrelax-pic-calls" } */
|
/* { dg-options "-mrelax-pic-calls" } */
|
||||||
/* { dg-final { scan-assembler-times "\\.reloc\t1f,R_MIPS_JALR,g\n1:\tjalrs?\t" 2 } } */
|
/* { dg-final { scan-assembler-times "\\.reloc\t1f,R_MIPS_JALR,g\n1:\tjalrc?s?\t" 2 } } */
|
||||||
|
|
||||||
extern void g (void);
|
extern void g (void);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/* { dg-options "-mrelax-pic-calls -mno-shared" } */
|
/* { dg-options "-mrelax-pic-calls -mno-shared" } */
|
||||||
/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,g\n1:\tjalrs?\t" } } */
|
/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,g\n1:\tjalrc?s?\t" } } */
|
||||||
/* { dg-require-visibility "" } */
|
/* { dg-require-visibility "" } */
|
||||||
|
|
||||||
__attribute__ ((visibility ("hidden"))) void g ();
|
__attribute__ ((visibility ("hidden"))) void g ();
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/* See through some simple data-flow. */
|
/* See through some simple data-flow. */
|
||||||
/* { dg-options "-mrelax-pic-calls" } */
|
/* { dg-options "-mrelax-pic-calls" } */
|
||||||
/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,g\n1:\tjalr\t" } } */
|
/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,g\n1:\tjalrc?\t" } } */
|
||||||
|
|
||||||
extern void g (void);
|
extern void g (void);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,13 @@
|
||||||
in this case (PR target/57260). */
|
in this case (PR target/57260). */
|
||||||
/* { dg-options "-mrelax-pic-calls -mshared -foptimize-sibling-calls -mabi=n32" } */
|
/* { dg-options "-mrelax-pic-calls -mshared -foptimize-sibling-calls -mabi=n32" } */
|
||||||
/* { dg-skip-if "requires -foptimize-sibling-calls" { *-*-* } { "-O0" } { "" } } */
|
/* { dg-skip-if "requires -foptimize-sibling-calls" { *-*-* } { "-O0" } { "" } } */
|
||||||
/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,normal\n1:\tjalr\t" } } */
|
/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,normal\n1:\tjalrc?\t" } } */
|
||||||
/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,normal2\n1:\tjalr\t" } } */
|
/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,normal2\n1:\tjalrc?\t" } } */
|
||||||
/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,staticfunc\n1:\tjalr\t" } } */
|
/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,staticfunc\n1:\tjalrc?\t" } } */
|
||||||
/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,tail\n1:\tjalr\t" } } */
|
/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,tail\n1:\tjalrc?\t" } } */
|
||||||
/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,tail2\n1:\tjalr\t" } } */
|
/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,tail2\n1:\tjalrc?\t" } } */
|
||||||
/* { dg-final { scan-assembler "(\\.reloc\t1f,R_MIPS_JALR,tail3\n1:)?\tjrc?\t" } } */
|
/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,tail3\n1:\tjrc?\t" } } */
|
||||||
/* { dg-final { scan-assembler "(\\.reloc\t1f,R_MIPS_JALR,tail4\n1:)?\tjrc?\t" } } */
|
/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,tail4\n1:\tjrc?\t" } } */
|
||||||
|
|
||||||
__attribute__ ((noinline)) static void staticfunc () { asm (""); }
|
__attribute__ ((noinline)) static void staticfunc () { asm (""); }
|
||||||
int normal ();
|
int normal ();
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
/* Like call-5.c, but for n64. */
|
/* Like call-5.c, but for n64. */
|
||||||
/* { dg-options "-mrelax-pic-calls -mshared -foptimize-sibling-calls -mabi=64" } */
|
/* { dg-options "-mrelax-pic-calls -mshared -foptimize-sibling-calls -mabi=64" } */
|
||||||
/* { dg-skip-if "requires -foptimize-sibling-calls" { *-*-* } { "-O0" } { "" } } */
|
/* { dg-skip-if "requires -foptimize-sibling-calls" { *-*-* } { "-O0" } { "" } } */
|
||||||
/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,normal\n1:\tjalr\t" } } */
|
/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,normal\n1:\tjalrc?\t" } } */
|
||||||
/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,normal2\n1:\tjalr\t" } } */
|
/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,normal2\n1:\tjalrc?\t" } } */
|
||||||
/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,staticfunc\n1:\tjalr\t" } } */
|
/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,staticfunc\n1:\tjalrc?\t" } } */
|
||||||
/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,tail\n1:\tjalr\t" } } */
|
/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,tail\n1:\tjalrc?\t" } } */
|
||||||
/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,tail2\n1:\tjalr\t" } } */
|
/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,tail2\n1:\tjalrc?\t" } } */
|
||||||
/* { dg-final { scan-assembler "(\\.reloc\t1f,R_MIPS_JALR,tail3\n1:)?\tjrc?\t" } } */
|
/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,tail3\n1:\tjrc?\t" } } */
|
||||||
/* { dg-final { scan-assembler "(\\.reloc\t1f,R_MIPS_JALR,tail4\n1:)?\tjrc?\t" } } */
|
/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,tail4\n1:\tjrc?\t" } } */
|
||||||
|
|
||||||
__attribute__ ((noinline)) static void staticfunc () { asm (""); }
|
__attribute__ ((noinline)) static void staticfunc () { asm (""); }
|
||||||
int normal ();
|
int normal ();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
/* { dg-options "-mcompact-branches=always -mno-micromips" } */
|
||||||
|
int glob;
|
||||||
|
|
||||||
|
void
|
||||||
|
foo (int a, int b)
|
||||||
|
{
|
||||||
|
if (a < b)
|
||||||
|
glob = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* { dg-final { scan-assembler "\tbgec\t\\\$\[0-9\]*,\\\$\[0-9\]*" } } */
|
||||||
|
/* { dg-final { scan-assembler "\tjrc\t\\\$31" } } */
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
/* { dg-options "-mcompact-branches=never" } */
|
||||||
|
int glob;
|
||||||
|
|
||||||
|
void
|
||||||
|
foo (int a, int b)
|
||||||
|
{
|
||||||
|
if (a < b)
|
||||||
|
glob = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* { dg-final { scan-assembler-not "\tb\[^ \t\]*c" } } */
|
||||||
|
/* { dg-final { scan-assembler-not "\tj\[^ \t\]*c" } } */
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
/* { dg-options "-mcompact-branches=never isa_rev>=6" } */
|
||||||
|
int glob;
|
||||||
|
|
||||||
|
void
|
||||||
|
foo (int a, int b, volatile int * bar)
|
||||||
|
{
|
||||||
|
if (a < b)
|
||||||
|
glob = *bar;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* { dg-final { scan-assembler "\tnop" } } */
|
||||||
|
/* { dg-final { scan-assembler-not "\tb\[^ \t\]*c" } } */
|
||||||
|
/* { dg-final { scan-assembler-not "\tj\[^ \t\]*c" } } */
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
/* { dg-options "-mcompact-branches=optimal isa_rev>=6" } */
|
||||||
|
int glob;
|
||||||
|
|
||||||
|
void
|
||||||
|
foo (int a, int b, volatile int * bar)
|
||||||
|
{
|
||||||
|
if (a < b)
|
||||||
|
glob = *bar;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* { dg-final { scan-assembler "\tb\[^ \t\]*c" } } */
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
/* { dg-options "-mno-abicalls -mcompact-branches=never isa_rev>=6" } */
|
||||||
|
void bar (int);
|
||||||
|
|
||||||
|
void
|
||||||
|
foo ()
|
||||||
|
{
|
||||||
|
bar (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* { dg-final { scan-assembler "\t(j|jal)\t" } } */
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
/* { dg-options "-mno-abicalls -mcompact-branches=optimal isa_rev>=6" } */
|
||||||
|
void bar (int);
|
||||||
|
|
||||||
|
void
|
||||||
|
foo ()
|
||||||
|
{
|
||||||
|
bar (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* { dg-final { scan-assembler "\t(bc|balc)\t" } } */
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
/* { dg-options "-mhard-float -mcompact-branches=always isa_rev>=6 -mno-micromips" } */
|
||||||
|
int bar;
|
||||||
|
|
||||||
|
void
|
||||||
|
foo (float a, volatile int * b)
|
||||||
|
{
|
||||||
|
if (a < 0.1)
|
||||||
|
bar = *b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* { dg-final { scan-assembler "\t(bc1eqz|bc1nez)\t" } } */
|
||||||
|
/* { dg-final { scan-assembler "\tnop" } } */
|
||||||
|
|
@ -19,6 +19,6 @@ foo (int n)
|
||||||
/* There should be exactly five uses of $25: one to set up $gp, two to
|
/* There should be exactly five uses of $25: one to set up $gp, two to
|
||||||
load the address of bar (), and two to call it. */
|
load the address of bar (), and two to call it. */
|
||||||
/* { dg-final { scan-assembler-times "\tl.\t\\\$25,%call16\\\(bar\\\)" 2 } } */
|
/* { dg-final { scan-assembler-times "\tl.\t\\\$25,%call16\\\(bar\\\)" 2 } } */
|
||||||
/* { dg-final { scan-assembler-times "\tjalrs?\t\\\$25" 2 } } */
|
/* { dg-final { scan-assembler-times "\tjalrc?s?\t\\\$25" 2 } } */
|
||||||
/* { dg-final { scan-assembler "(\\\$28,|\t.cpload\t)\\\$25" } } */
|
/* { dg-final { scan-assembler "(\\\$28,|\t.cpload\t)\\\$25" } } */
|
||||||
/* { dg-final { scan-assembler-times "\\\$25" 5 } } */
|
/* { dg-final { scan-assembler-times "\\\$25" 5 } } */
|
||||||
|
|
|
||||||
|
|
@ -243,6 +243,7 @@ set mips_option_groups {
|
||||||
mips16 "-mips16|-mno-mips16|-mflip-mips16"
|
mips16 "-mips16|-mno-mips16|-mflip-mips16"
|
||||||
mips3d "-mips3d|-mno-mips3d"
|
mips3d "-mips3d|-mno-mips3d"
|
||||||
pic "-f(no-|)(pic|PIC)"
|
pic "-f(no-|)(pic|PIC)"
|
||||||
|
cb "-mcompact-branches=.*"
|
||||||
profiling "-pg"
|
profiling "-pg"
|
||||||
small-data "-G[0-9]+"
|
small-data "-G[0-9]+"
|
||||||
warnings "-w"
|
warnings "-w"
|
||||||
|
|
@ -1068,8 +1069,10 @@ proc mips-dg-options { args } {
|
||||||
# We need a revision 6 or better ISA for:
|
# We need a revision 6 or better ISA for:
|
||||||
#
|
#
|
||||||
# - When the LSA instruction is required
|
# - When the LSA instruction is required
|
||||||
|
# - When only using compact branches
|
||||||
if { $isa_rev < 6
|
if { $isa_rev < 6
|
||||||
&& ([mips_have_test_option_p options "HAS_LSA"]) } {
|
&& ([mips_have_test_option_p options "HAS_LSA"]
|
||||||
|
|| [mips_have_test_option_p options "-mcompact-branches=always"]) } {
|
||||||
if { $gp_size == 32 } {
|
if { $gp_size == 32 } {
|
||||||
mips_make_test_option options "-mips32r6"
|
mips_make_test_option options "-mips32r6"
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1164,6 +1167,9 @@ proc mips-dg-options { args } {
|
||||||
mips_make_test_option options "-mips64r5"
|
mips_make_test_option options "-mips64r5"
|
||||||
}
|
}
|
||||||
mips_make_test_option options "-mnan=2008"
|
mips_make_test_option options "-mnan=2008"
|
||||||
|
if { [mips_have_option_p options "-mcompact-branches=always"] } {
|
||||||
|
mips_make_test_option options "-mcompact-branches=optimal"
|
||||||
|
}
|
||||||
# Check whether we need to switch from a 32-bit processor to the
|
# Check whether we need to switch from a 32-bit processor to the
|
||||||
# "nearest" 64-bit processor.
|
# "nearest" 64-bit processor.
|
||||||
} elseif { $gp_size == 64 && [mips_32bit_arch_p $arch] } {
|
} elseif { $gp_size == 64 && [mips_32bit_arch_p $arch] } {
|
||||||
|
|
@ -1308,6 +1314,11 @@ proc mips-dg-options { args } {
|
||||||
mips_make_test_option options "-mno-micromips"
|
mips_make_test_option options "-mno-micromips"
|
||||||
mips_make_test_option options "-mnan=legacy"
|
mips_make_test_option options "-mnan=legacy"
|
||||||
}
|
}
|
||||||
|
if { $isa_rev < 6 } {
|
||||||
|
if { [mips_have_option_p options "-mcompact-branches=always"] } {
|
||||||
|
mips_make_test_option options "-mcompact-branches=optimal"
|
||||||
|
}
|
||||||
|
}
|
||||||
if { $isa_rev > 5 } {
|
if { $isa_rev > 5 } {
|
||||||
mips_make_test_option options "-mno-dsp"
|
mips_make_test_option options "-mno-dsp"
|
||||||
mips_make_test_option options "-mno-mips16"
|
mips_make_test_option options "-mno-mips16"
|
||||||
|
|
|
||||||
|
|
@ -16,5 +16,5 @@ int test ()
|
||||||
|
|
||||||
/* { dg-final { scan-assembler-not "\tjal\tlong_call_func\n" } } */
|
/* { dg-final { scan-assembler-not "\tjal\tlong_call_func\n" } } */
|
||||||
/* { dg-final { scan-assembler-not "\tjal\tfar_func\n" } } */
|
/* { dg-final { scan-assembler-not "\tjal\tfar_func\n" } } */
|
||||||
/* { dg-final { scan-assembler "\tjal(|s)\tnear_func\n" } } */
|
/* { dg-final { scan-assembler "\t(jal(|s)|balc)\tnear_func\n" } } */
|
||||||
/* { dg-final { scan-assembler-not "\tjal\tnormal_func\n" } } */
|
/* { dg-final { scan-assembler-not "\tjal\tnormal_func\n" } } */
|
||||||
|
|
|
||||||
|
|
@ -16,5 +16,5 @@ int test ()
|
||||||
|
|
||||||
/* { dg-final { scan-assembler-not "\tjal(|s)\tlong_call_func\n" } } */
|
/* { dg-final { scan-assembler-not "\tjal(|s)\tlong_call_func\n" } } */
|
||||||
/* { dg-final { scan-assembler-not "\tjal(|s)\tfar_func\n" } } */
|
/* { dg-final { scan-assembler-not "\tjal(|s)\tfar_func\n" } } */
|
||||||
/* { dg-final { scan-assembler "\tjal(|s)\tnear_func\n" } } */
|
/* { dg-final { scan-assembler "\t(jal(|s)|balc)\tnear_func\n" } } */
|
||||||
/* { dg-final { scan-assembler "\tjal(|s)\tnormal_func\n" } } */
|
/* { dg-final { scan-assembler "\t(jal(|s)|balc)\tnormal_func\n" } } */
|
||||||
|
|
|
||||||
|
|
@ -13,5 +13,5 @@ NOMIPS16 int test4 () { return normal_func (); }
|
||||||
|
|
||||||
/* { dg-final { scan-assembler-not "\tj\tlong_call_func\n" } } */
|
/* { dg-final { scan-assembler-not "\tj\tlong_call_func\n" } } */
|
||||||
/* { dg-final { scan-assembler-not "\tj\tfar_func\n" } } */
|
/* { dg-final { scan-assembler-not "\tj\tfar_func\n" } } */
|
||||||
/* { dg-final { scan-assembler "\tj(|al|als)\tnear_func\n" } } */
|
/* { dg-final { scan-assembler "\t(j(|al|als)|b(|al)c)\tnear_func\n" } } */
|
||||||
/* { dg-final { scan-assembler-not "\tj\tnormal_func\n" } } */
|
/* { dg-final { scan-assembler-not "\tj\tnormal_func\n" } } */
|
||||||
|
|
|
||||||
|
|
@ -13,5 +13,5 @@ NOMIPS16 int test4 () { return normal_func (); }
|
||||||
|
|
||||||
/* { dg-final { scan-assembler-not "\tj\tlong_call_func\n" } } */
|
/* { dg-final { scan-assembler-not "\tj\tlong_call_func\n" } } */
|
||||||
/* { dg-final { scan-assembler-not "\tj\tfar_func\n" } } */
|
/* { dg-final { scan-assembler-not "\tj\tfar_func\n" } } */
|
||||||
/* { dg-final { scan-assembler "\tj(|al|als)\tnear_func\n" } } */
|
/* { dg-final { scan-assembler "\t(j(|al|als)|b(|al)c)\tnear_func\n" } } */
|
||||||
/* { dg-final { scan-assembler "\tj(|al|als)\tnormal_func\n" } } */
|
/* { dg-final { scan-assembler "\t(j(|al|als)|b(|al)c)\tnormal_func\n" } } */
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/* { dg-options "(-mmicromips)" } */
|
/* { dg-options "(-mmicromips) -mcompact-branches=optimal" } */
|
||||||
/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
|
/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
|
||||||
|
|
||||||
void MICROMIPS
|
void MICROMIPS
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue