Commit 30c0ee9c by Matthew Fortune Committed by Robert Suchanek

MIPS: Add support for P6600.

gcc/ChangeLog:

2018-06-13  Matthew Fortune  <matthew.fortune@mips.com>
            Prachi Godbole  <prachi.godbole@imgtec.com>

	* config/mips/mips-cpus.def: Define P6600.
	* config/mips/mips-tables.opt: Regenerate.
	* config/mips/mips.c (mips_ucbranch_type): New enum.
	(mips_rtx_cost_data): Add support for P6600.
	(mips_issue_rate): Likewise.
	(mips_multipass_dfa_lookahead): Likewise.
	(mips_avoid_hazard): Likewise.
	(mips_reorg_process_insns): Likewise.
	(mips_classify_branch_p6600): New function.
	* config/mips/mips.h (TUNE_P6600): New define.
	(MIPS_ISA_LEVEL_SPEC): Infer mips64r6 from p6600.
	(ENABLE_LD_ST_PAIRS): Enable load/store bonding for p6600.
	* config/mips/mips.md: Include p6600.md.
	(processor): Add p6600.
	* config/mips/p6600.md: New file.
	* doc/invoke.texi: Add p6600 to supported architectures.

Co-Authored-By: Prachi Godbole <prachi.godbole@imgtec.com>

From-SVN: r261570
parent 1df5fce4
2018-06-13 Matthew Fortune <matthew.fortune@mips.com>
Prachi Godbole <prachi.godbole@imgtec.com>
* config/mips/mips-cpus.def: Define P6600.
* config/mips/mips-tables.opt: Regenerate.
* config/mips/mips.c (mips_ucbranch_type): New enum.
(mips_rtx_cost_data): Add support for P6600.
(mips_issue_rate): Likewise.
(mips_multipass_dfa_lookahead): Likewise.
(mips_avoid_hazard): Likewise.
(mips_reorg_process_insns): Likewise.
(mips_classify_branch_p6600): New function.
* config/mips/mips.h (TUNE_P6600): New define.
(MIPS_ISA_LEVEL_SPEC): Infer mips64r6 from p6600.
(ENABLE_LD_ST_PAIRS): Enable load/store bonding for p6600.
* config/mips/mips.md: Include p6600.md.
(processor): Add p6600.
* config/mips/p6600.md: New file.
* doc/invoke.texi: Add p6600 to supported architectures.
2018-06-13 Martin Sebor <msebor@redhat.com>
PR tree-optimization/86114
......
......@@ -172,3 +172,4 @@ MIPS_CPU ("xlp", PROCESSOR_XLP, 65, PTF_AVOID_BRANCHLIKELY_SPEED)
/* MIPS64 Release 6 processors. */
MIPS_CPU ("i6400", PROCESSOR_I6400, 69, 0)
MIPS_CPU ("i6500", PROCESSOR_I6400, 69, 0)
MIPS_CPU ("p6600", PROCESSOR_P6600, 69, 0)
......@@ -699,3 +699,6 @@ Enum(mips_arch_opt_value) String(i6400) Value(102) Canonical
EnumValue
Enum(mips_arch_opt_value) String(i6500) Value(103) Canonical
EnumValue
Enum(mips_arch_opt_value) String(p6600) Value(104) Canonical
......@@ -198,6 +198,16 @@ enum mips_address_type {
ADDRESS_SYMBOLIC
};
/* Classifies an unconditional branch of interest for the P6600. */
enum mips_ucbranch_type
{
/* May not even be a branch. */
UC_UNDEFINED,
UC_BALC,
UC_OTHER
};
/* Macros to create an enumeration identifier for a function prototype. */
#define MIPS_FTYPE_NAME1(A, B) MIPS_##A##_FTYPE_##B
#define MIPS_FTYPE_NAME2(A, B, C) MIPS_##A##_FTYPE_##B##_##C
......@@ -1127,6 +1137,19 @@ static const struct mips_rtx_cost_data
COSTS_N_INSNS (36), /* int_div_di */
2, /* branch_cost */
4 /* memory_latency */
},
{ /* P6600 */
COSTS_N_INSNS (4), /* fp_add */
COSTS_N_INSNS (5), /* fp_mult_sf */
COSTS_N_INSNS (5), /* fp_mult_df */
COSTS_N_INSNS (17), /* fp_div_sf */
COSTS_N_INSNS (17), /* fp_div_df */
COSTS_N_INSNS (5), /* int_mult_si */
COSTS_N_INSNS (5), /* int_mult_di */
COSTS_N_INSNS (8), /* int_div_si */
COSTS_N_INSNS (8), /* int_div_di */
2, /* branch_cost */
4 /* memory_latency */
}
};
......@@ -14592,6 +14615,7 @@ mips_issue_rate (void)
case PROCESSOR_LOONGSON_2F:
case PROCESSOR_LOONGSON_3A:
case PROCESSOR_P5600:
case PROCESSOR_P6600:
return 4;
case PROCESSOR_XLP:
......@@ -14727,7 +14751,7 @@ mips_multipass_dfa_lookahead (void)
if (TUNE_OCTEON)
return 2;
if (TUNE_P5600 || TUNE_I6400)
if (TUNE_P5600 || TUNE_P6600 || TUNE_I6400)
return 4;
return 0;
......@@ -18647,6 +18671,29 @@ mips_orphaned_high_part_p (mips_offset_table *htab, rtx_insn *insn)
return false;
}
/* Subroutine of mips_avoid_hazard. We classify unconditional branches
of interest for the P6600 for performance reasons. We're interested
in differentiating BALC from JIC, JIALC and BC. */
static enum mips_ucbranch_type
mips_classify_branch_p6600 (rtx_insn *insn)
{
/* We ignore sequences here as they represent a filled delay slot. */
if (!insn
|| !USEFUL_INSN_P (insn)
|| GET_CODE (PATTERN (insn)) == SEQUENCE)
return UC_UNDEFINED;
if (get_attr_jal (insn) == JAL_INDIRECT /* JIC and JIALC. */
|| get_attr_type (insn) == TYPE_JUMP) /* BC. */
return UC_OTHER;
if (CALL_P (insn) && get_attr_jal (insn) == JAL_DIRECT)
return UC_BALC;
return UC_UNDEFINED;
}
/* Subroutine of mips_reorg_process_insns. If there is a hazard between
INSN and a previous instruction, avoid it by inserting nops after
instruction AFTER.
......@@ -18699,14 +18746,40 @@ mips_avoid_hazard (rtx_insn *after, rtx_insn *insn, int *hilo_delay,
&& GET_CODE (pattern) != ASM_INPUT
&& asm_noperands (pattern) < 0)
nops = 1;
/* The P6600's branch predictor can handle static sequences of back-to-back
branches in the following cases:
(1) BALC followed by any conditional compact branch
(2) BALC followed by BALC
Any other combinations of compact branches will incur performance
penalty. Inserting a no-op only costs space as the dispatch unit will
disregard the nop. */
else if (TUNE_P6600 && TARGET_CB_MAYBE && !optimize_size
&& ((mips_classify_branch_p6600 (after) == UC_BALC
&& mips_classify_branch_p6600 (insn) == UC_OTHER)
|| (mips_classify_branch_p6600 (insn) == UC_BALC
&& mips_classify_branch_p6600 (after) == UC_OTHER)))
nops = 1;
else
nops = 0;
/* Insert the nops between this instruction and the previous one.
Each new nop takes us further from the last hilo hazard. */
*hilo_delay += nops;
/* Move to the next real instruction if we are inserting a NOP and this
instruction is a call with debug information. The reason being that
we can't separate the call from the debug info. */
rtx_insn *real_after = after;
if (real_after && nops && CALL_P (real_after))
while (real_after
&& (NOTE_P (NEXT_INSN (real_after))
|| BARRIER_P (NEXT_INSN (real_after))))
real_after = NEXT_INSN (real_after);
while (nops-- > 0)
emit_insn_after (gen_hazard_nop (), after);
emit_insn_after (gen_hazard_nop (), real_after);
/* Set up the state for the next instruction. */
*hilo_delay += ninsns;
......@@ -18716,6 +18789,15 @@ mips_avoid_hazard (rtx_insn *after, rtx_insn *insn, int *hilo_delay,
switch (get_attr_hazard (insn))
{
case HAZARD_NONE:
/* For the P6600, flag some unconditional branches as having a
pseudo-forbidden slot. This will cause additional nop insertion
or SEQUENCE breaking as required. This is for performance
reasons not correctness. */
if (TUNE_P6600
&& !optimize_size
&& TARGET_CB_MAYBE
&& mips_classify_branch_p6600 (insn) == UC_OTHER)
*fs_delay = true;
break;
case HAZARD_FORBIDDEN_SLOT:
......@@ -18955,9 +19037,19 @@ mips_reorg_process_insns (void)
and the next useful instruction is a SEQUENCE of a jump
and a non-nop instruction in the delay slot, remove the
sequence and replace it with the delay slot instruction
then the jump to clear the forbidden slot hazard. */
if (fs_delay)
then the jump to clear the forbidden slot hazard.
For the P6600, this optimisation solves the performance
penalty associated with BALC followed by a delay slot
branch. We do not set fs_delay as we do not want
the full logic of a forbidden slot; the penalty exists
only against branches not the full class of forbidden
slot instructions. */
if (fs_delay || (TUNE_P6600
&& TARGET_CB_MAYBE
&& mips_classify_branch_p6600 (insn)
== UC_BALC))
{
/* Search onwards from the current position looking for
a SEQUENCE. We are looking for pipeline hazards here
......
......@@ -317,6 +317,7 @@ struct mips_cpu_info {
|| mips_tune == PROCESSOR_SB1A)
#define TUNE_P5600 (mips_tune == PROCESSOR_P5600)
#define TUNE_I6400 (mips_tune == PROCESSOR_I6400)
#define TUNE_P6600 (mips_tune == PROCESSOR_P6600)
/* Whether vector modes and intrinsics for ST Microelectronics
Loongson-2E/2F processors should be enabled. In o32 pairs of
......@@ -782,7 +783,7 @@ struct mips_cpu_info {
%{march=mips64r2|march=loongson3a|march=octeon|march=xlp: -mips64r2} \
%{march=mips64r3: -mips64r3} \
%{march=mips64r5: -mips64r5} \
%{march=mips64r6|march=i6400|march=i6500: -mips64r6}}"
%{march=mips64r6|march=i6400|march=i6500|march=p6600: -mips64r6}}"
/* A spec that injects the default multilib ISA if no architecture is
specified. */
......@@ -3403,5 +3404,6 @@ struct GTY(()) machine_function {
performance can be degraded for those targets. Hence, do not bond for
micromips or fix_24k. */
#define ENABLE_LD_ST_PAIRS \
(TARGET_LOAD_STORE_PAIRS && (TUNE_P5600 || TUNE_I6400) \
(TARGET_LOAD_STORE_PAIRS \
&& (TUNE_P5600 || TUNE_I6400 || TUNE_P6600) \
&& !TARGET_MICROMIPS && !TARGET_FIX_24K)
......@@ -69,6 +69,7 @@
p5600
m5100
i6400
p6600
])
(define_c_enum "unspec" [
......@@ -1152,6 +1153,7 @@
(include "i6400.md")
(include "p5600.md")
(include "m5100.md")
(include "p6600.md")
(include "4k.md")
(include "5k.md")
(include "20kc.md")
......
......@@ -20112,7 +20112,7 @@ The processor names are:
@samp{m5100}, @samp{m5101},
@samp{octeon}, @samp{octeon+}, @samp{octeon2}, @samp{octeon3},
@samp{orion},
@samp{p5600},
@samp{p5600}, @samp{p6600},
@samp{r2000}, @samp{r3000}, @samp{r3900}, @samp{r4000}, @samp{r4400},
@samp{r4600}, @samp{r4650}, @samp{r4700}, @samp{r6000}, @samp{r8000},
@samp{rm7000}, @samp{rm9000},
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment