sparc.h (PREFERRED_RELOAD_CLASS): Select GENERAL_REGS for integer data not destined for fp regs.

* sparc.h (PREFERRED_RELOAD_CLASS): Select GENERAL_REGS for
        integer data not destined for fp regs.
        (LEGITIMIZE_RELOAD_ADDRESS): New.
Thu Jan  7 03:03:42 1999  Stan Cox  <scox@cygnus.com>
                          Richard Henderson  <rth@cygnus.com>
        Support for Hypersparc and Sparclite86x:
        * sparc.h (TARGET_CPU_hypersparc, TARGET_CPU_sparclite86x): New.
        (CPP_CPU32_DEFAULT_SPEC): Fix up for the new targets.
        (ASM_CPU32_DEFAULT_SPEC): Likewise.
        (TARGET_CPU_DEFAULT): Likewise.
        (enum processor_type): Likewise.
        (CPP_ENDIAN_SPEC): Handle little endian data.
        (LIBGCC2_WORDS_BIG_ENDIAN): Likewise.
        (ADJUST_COST): Call sparc_adjust_cost.
        * sparc.c (sparc_override_options): Fix up for the new targets.
        (supersparc_adjust_cost): Make static.
        (hypersparc_adjust_cost): New.
        (ultrasparc_adjust_cost): Make static.
        (sparc_adjust_cost): New.
        * sparc.md (attr cpu): Add hypersparc and sparclite86x.
        (function_unit): Add hypersparc scheduling rules.
        * configure.in (with_cpu handler): Recognize hypersparc.

From-SVN: r24556
This commit is contained in:
Richard Henderson 1999-01-06 19:18:28 -08:00
parent 4ddb3ea6f7
commit 8947065c44
6 changed files with 421 additions and 173 deletions

View File

@ -1,3 +1,31 @@
Thu Jan 7 03:08:17 1999 Richard Henderson <rth@cygnus.com>
* sparc.h (PREFERRED_RELOAD_CLASS): Select GENERAL_REGS for
integer data not destined for fp regs.
(LEGITIMIZE_RELOAD_ADDRESS): New.
Thu Jan 7 03:03:42 1999 Stan Cox <scox@cygnus.com>
Richard Henderson <rth@cygnus.com>
Support for Hypersparc and Sparclite86x:
* sparc.h (TARGET_CPU_hypersparc, TARGET_CPU_sparclite86x): New.
(CPP_CPU32_DEFAULT_SPEC): Fix up for the new targets.
(ASM_CPU32_DEFAULT_SPEC): Likewise.
(TARGET_CPU_DEFAULT): Likewise.
(enum processor_type): Likewise.
(CPP_ENDIAN_SPEC): Handle little endian data.
(LIBGCC2_WORDS_BIG_ENDIAN): Likewise.
(ADJUST_COST): Call sparc_adjust_cost.
* sparc.c (sparc_override_options): Fix up for the new targets.
(supersparc_adjust_cost): Make static.
(hypersparc_adjust_cost): New.
(ultrasparc_adjust_cost): Make static.
(sparc_adjust_cost): New.
* sparc.md (attr cpu): Add hypersparc and sparclite86x.
(function_unit): Add hypersparc scheduling rules.
* configure.in (with_cpu handler): Recognize hypersparc.
Thu Jan 7 23:54:05 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
* config/c4x/c4x.c: Added space after negation operator.

View File

@ -110,6 +110,11 @@ static void build_big_number PROTO((FILE *, int, char *));
static int function_arg_slotno PROTO((const CUMULATIVE_ARGS *,
enum machine_mode, tree, int, int,
int *, int *));
static int supersparc_adjust_cost PROTO((rtx, rtx, rtx, int));
static int hypersparc_adjust_cost PROTO((rtx, rtx, rtx, int));
static int ultrasparc_adjust_cost PROTO((rtx, rtx, rtx, int));
static void sparc_output_addr_vec PROTO((rtx));
static void sparc_output_addr_diff_vec PROTO((rtx));
static void sparc_output_deferred_case_vectors PROTO((void));
@ -176,6 +181,8 @@ sparc_override_options ()
{ TARGET_CPU_sparclet, "tsc701" },
{ TARGET_CPU_sparclite, "f930" },
{ TARGET_CPU_v8, "v8" },
{ TARGET_CPU_hypersparc, "hypersparc" },
{ TARGET_CPU_sparclite86x, "sparclite86x" },
{ TARGET_CPU_supersparc, "supersparc" },
{ TARGET_CPU_v9, "v9" },
{ TARGET_CPU_ultrasparc, "ultrasparc" },
@ -199,6 +206,8 @@ sparc_override_options ()
The Fujitsu MB86934 is the recent sparclite chip, with an fpu. */
{ "f930", PROCESSOR_F930, MASK_ISA|MASK_FPU, MASK_SPARCLITE },
{ "f934", PROCESSOR_F934, MASK_ISA, MASK_SPARCLITE|MASK_FPU },
{ "hypersparc", PROCESSOR_HYPERSPARC, MASK_ISA, MASK_V8|MASK_FPU },
{ "sparclite86x", PROCESSOR_SPARCLITE86X, MASK_ISA|MASK_FPU, MASK_V8 },
{ "sparclet", PROCESSOR_SPARCLET, MASK_ISA, MASK_SPARCLET },
/* TEMIC sparclet */
{ "tsc701", PROCESSOR_TSC701, MASK_ISA, MASK_SPARCLET },
@ -6194,7 +6203,7 @@ sparc_flat_eligible_for_epilogue_delay (trial, slot)
/* Adjust the cost of a scheduling dependency. Return the new cost of
a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
int
static int
supersparc_adjust_cost (insn, link, dep_insn, cost)
rtx insn;
rtx link;
@ -6259,6 +6268,261 @@ supersparc_adjust_cost (insn, link, dep_insn, cost)
return cost;
}
static int
hypersparc_adjust_cost (insn, link, dep_insn, cost)
rtx insn;
rtx link;
rtx dep_insn;
int cost;
{
enum attr_type insn_type, dep_type;
rtx pat = PATTERN(insn);
rtx dep_pat = PATTERN (dep_insn);
if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
return cost;
insn_type = get_attr_type (insn);
dep_type = get_attr_type (dep_insn);
switch (REG_NOTE_KIND (link))
{
case 0:
/* Data dependency; DEP_INSN writes a register that INSN reads some
cycles later. */
switch (insn_type)
{
case TYPE_STORE:
case TYPE_FPSTORE:
/* Get the delay iff the address of the store is the dependence. */
if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET)
return cost;
if (rtx_equal_p (SET_DEST (dep_pat), SET_SRC (pat)))
return cost;
return cost + 3;
case TYPE_LOAD:
case TYPE_SLOAD:
case TYPE_FPLOAD:
/* If a load, then the dependence must be on the memory address. If
the addresses aren't equal, then it might be a false dependency */
if (dep_type == TYPE_STORE || dep_type == TYPE_FPSTORE)
{
if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET
|| GET_CODE (SET_DEST (dep_pat)) != MEM
|| GET_CODE (SET_SRC (pat)) != MEM
|| ! rtx_equal_p (XEXP (SET_DEST (dep_pat), 0),
XEXP (SET_SRC (pat), 0)))
return cost + 2;
return cost + 8;
}
break;
case TYPE_BRANCH:
/* Compare to branch latency is 0. There is no benefit from
separating compare and branch. */
if (dep_type == TYPE_COMPARE)
return 0;
/* Floating point compare to branch latency is less than
compare to conditional move. */
if (dep_type == TYPE_FPCMP)
return cost - 1;
break;
}
break;
case REG_DEP_ANTI:
/* Anti-dependencies only penalize the fpu unit. */
if (insn_type == TYPE_IALU || insn_type == TYPE_SHIFT)
return 0;
break;
default:
break;
}
return cost;
}
static int
ultrasparc_adjust_cost (insn, link, dep_insn, cost)
rtx insn;
rtx link;
rtx dep_insn;
int cost;
{
enum attr_type insn_type, dep_type;
rtx pat = PATTERN(insn);
rtx dep_pat = PATTERN (dep_insn);
if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
return cost;
insn_type = get_attr_type (insn);
dep_type = get_attr_type (dep_insn);
/* Nothing issues in parallel with integer multiplies, so
mark as zero cost since the scheduler can not do anything
about it. */
if (insn_type == TYPE_IMUL)
return 0;
#define SLOW_FP(dep_type) \
(dep_type == TYPE_FPSQRT || dep_type == TYPE_FPDIVS || dep_type == TYPE_FPDIVD)
switch (REG_NOTE_KIND (link))
{
case 0:
/* Data dependency; DEP_INSN writes a register that INSN reads some
cycles later. */
if (dep_type == TYPE_CMOVE)
{
/* Instructions that read the result of conditional moves cannot
be in the same group or the following group. */
return cost + 1;
}
switch (insn_type)
{
/* UltraSPARC can dual issue a store and an instruction setting
the value stored, except for divide and square root. */
case TYPE_FPSTORE:
if (! SLOW_FP (dep_type))
return 0;
return cost;
case TYPE_STORE:
if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET)
return cost;
if (rtx_equal_p (SET_DEST (dep_pat), SET_SRC (pat)))
/* The dependency between the two instructions is on the data
that is being stored. Assume that the address of the store
is not also dependent. */
return 0;
return cost;
case TYPE_LOAD:
case TYPE_SLOAD:
case TYPE_FPLOAD:
/* A load does not return data until at least 11 cycles after
a store to the same location. 3 cycles are accounted for
in the load latency; add the other 8 here. */
if (dep_type == TYPE_STORE || dep_type == TYPE_FPSTORE)
{
/* If the addresses are not equal this may be a false
dependency because pointer aliasing could not be
determined. Add only 2 cycles in that case. 2 is
an arbitrary compromise between 8, which would cause
the scheduler to generate worse code elsewhere to
compensate for a dependency which might not really
exist, and 0. */
if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET
|| GET_CODE (SET_SRC (pat)) != MEM
|| GET_CODE (SET_DEST (dep_pat)) != MEM
|| ! rtx_equal_p (XEXP (SET_SRC (pat), 0),
XEXP (SET_DEST (dep_pat), 0)))
return cost + 2;
return cost + 8;
}
return cost;
case TYPE_BRANCH:
/* Compare to branch latency is 0. There is no benefit from
separating compare and branch. */
if (dep_type == TYPE_COMPARE)
return 0;
/* Floating point compare to branch latency is less than
compare to conditional move. */
if (dep_type == TYPE_FPCMP)
return cost - 1;
return cost;
case TYPE_FPCMOVE:
/* FMOVR class instructions can not issue in the same cycle
or the cycle after an instruction which writes any
integer register. Model this as cost 2 for dependent
instructions. */
if ((dep_type == TYPE_IALU || dep_type == TYPE_UNARY
|| dep_type == TYPE_BINARY)
&& cost < 2)
return 2;
/* Otherwise check as for integer conditional moves. */
case TYPE_CMOVE:
/* Conditional moves involving integer registers wait until
3 cycles after loads return data. The interlock applies
to all loads, not just dependent loads, but that is hard
to model. */
if (dep_type == TYPE_LOAD || dep_type == TYPE_SLOAD)
return cost + 3;
return cost;
default:
break;
}
break;
case REG_DEP_ANTI:
/* Divide and square root lock destination registers for full latency. */
if (! SLOW_FP (dep_type))
return 0;
break;
case REG_DEP_OUTPUT:
/* IEU and FPU instruction that have the same destination
register cannot be grouped together. */
return cost + 1;
default:
break;
}
/* Other costs not accounted for:
- Single precision floating point loads lock the other half of
the even/odd register pair.
- Several hazards associated with ldd/std are ignored because these
instructions are rarely generated for V9.
- The floating point pipeline can not have both a single and double
precision operation active at the same time. Format conversions
and graphics instructions are given honorary double precision status.
- call and jmpl are always the first instruction in a group. */
return cost;
#undef SLOW_FP
}
int
sparc_adjust_cost(insn, link, dep, cost)
rtx insn;
rtx link;
rtx dep;
int cost;
{
switch (sparc_cpu)
{
case PROCESSOR_SUPERSPARC:
cost = supersparc_adjust_cost (insn, link, dep, cost);
break;
case PROCESSOR_HYPERSPARC:
case PROCESSOR_SPARCLITE86X:
cost = hypersparc_adjust_cost (insn, link, dep, cost);
break;
case PROCESSOR_ULTRASPARC:
cost = ultrasparc_adjust_cost (insn, link, dep, cost);
break;
default:
break;
}
return cost;
}
/* This describes the state of the UltraSPARC pipeline during
instruction scheduling. */
@ -6990,155 +7254,6 @@ ultrasparc_sched_reorder (dump, sched_verbose, ready, n_ready)
}
}
int
ultrasparc_adjust_cost (insn, link, dep_insn, cost)
rtx insn;
rtx link;
rtx dep_insn;
int cost;
{
enum attr_type insn_type, dep_type;
rtx pat = PATTERN(insn);
rtx dep_pat = PATTERN (dep_insn);
if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
return cost;
insn_type = get_attr_type (insn);
dep_type = get_attr_type (dep_insn);
/* Nothing issues in parallel with integer multiplies, so
mark as zero cost since the scheduler can not do anything
about it. */
if (insn_type == TYPE_IMUL)
return 0;
#define SLOW_FP(dep_type) \
(dep_type == TYPE_FPSQRT || dep_type == TYPE_FPDIVS || dep_type == TYPE_FPDIVD)
switch (REG_NOTE_KIND (link))
{
case 0:
/* Data dependency; DEP_INSN writes a register that INSN reads some
cycles later. */
if (dep_type == TYPE_CMOVE)
{
/* Instructions that read the result of conditional moves cannot
be in the same group or the following group. */
return cost + 1;
}
switch (insn_type)
{
/* UltraSPARC can dual issue a store and an instruction setting
the value stored, except for divide and square root. */
case TYPE_FPSTORE:
if (! SLOW_FP (dep_type))
return 0;
return cost;
case TYPE_STORE:
if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET)
return cost;
if (rtx_equal_p (SET_DEST (dep_pat), SET_SRC (pat)))
/* The dependency between the two instructions is on the data
that is being stored. Assume that the address of the store
is not also dependent. */
return 0;
return cost;
case TYPE_LOAD:
case TYPE_SLOAD:
case TYPE_FPLOAD:
/* A load does not return data until at least 11 cycles after
a store to the same location. 3 cycles are accounted for
in the load latency; add the other 8 here. */
if (dep_type == TYPE_STORE || dep_type == TYPE_FPSTORE)
{
/* If the addresses are not equal this may be a false
dependency because pointer aliasing could not be
determined. Add only 2 cycles in that case. 2 is
an arbitrary compromise between 8, which would cause
the scheduler to generate worse code elsewhere to
compensate for a dependency which might not really
exist, and 0. */
if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET
|| GET_CODE (SET_SRC (pat)) != MEM
|| GET_CODE (SET_DEST (dep_pat)) != MEM
|| ! rtx_equal_p (XEXP (SET_SRC (pat), 0),
XEXP (SET_DEST (dep_pat), 0)))
return cost + 2;
return cost + 8;
}
return cost;
case TYPE_BRANCH:
/* Compare to branch latency is 0. There is no benefit from
separating compare and branch. */
if (dep_type == TYPE_COMPARE)
return 0;
/* Floating point compare to branch latency is less than
compare to conditional move. */
if (dep_type == TYPE_FPCMP)
return cost - 1;
return cost;
case TYPE_FPCMOVE:
/* FMOVR class instructions can not issue in the same cycle
or the cycle after an instruction which writes any
integer register. Model this as cost 2 for dependent
instructions. */
if ((dep_type == TYPE_IALU || dep_type == TYPE_UNARY
|| dep_type == TYPE_BINARY)
&& cost < 2)
return 2;
/* Otherwise check as for integer conditional moves. */
case TYPE_CMOVE:
/* Conditional moves involving integer registers wait until
3 cycles after loads return data. The interlock applies
to all loads, not just dependent loads, but that is hard
to model. */
if (dep_type == TYPE_LOAD || dep_type == TYPE_SLOAD)
return cost + 3;
return cost;
default:
break;
}
break;
case REG_DEP_ANTI:
/* Divide and square root lock destination registers for full latency. */
if (! SLOW_FP (dep_type))
return 0;
break;
case REG_DEP_OUTPUT:
/* IEU and FPU instruction that have the same destination
register cannot be grouped together. */
return cost + 1;
default:
break;
}
/* Other costs not accounted for:
- Single precision floating point loads lock the other half of
the even/odd register pair.
- Several hazards associated with ldd/std are ignored because these
instructions are rarely generated for V9.
- The floating point pipeline can not have both a single and double
precision operation active at the same time. Format conversions
and graphics instructions are given honorary double precision status.
- call and jmpl are always the first instruction in a group. */
return cost;
}
int
sparc_issue_rate ()
{

View File

@ -106,18 +106,23 @@ extern enum cmodel sparc_cmodel;
/* Values of TARGET_CPU_DEFAULT, set via -D in the Makefile,
and specified by the user via --with-cpu=foo.
This specifies the cpu implementation, not the architecture size. */
/* Note that TARGET_CPU_v9 is assumed to start the list of 64-bit
capable cpu's. */
#define TARGET_CPU_sparc 0
#define TARGET_CPU_v7 0 /* alias for previous */
#define TARGET_CPU_sparclet 1
#define TARGET_CPU_sparclite 2
#define TARGET_CPU_v8 3 /* generic v8 implementation */
#define TARGET_CPU_supersparc 4
#define TARGET_CPU_v9 5 /* generic v9 implementation */
#define TARGET_CPU_sparcv9 5 /* alias */
#define TARGET_CPU_sparc64 5 /* alias */
#define TARGET_CPU_ultrasparc 6
#define TARGET_CPU_hypersparc 5
#define TARGET_CPU_sparclite86x 6
#define TARGET_CPU_v9 7 /* generic v9 implementation */
#define TARGET_CPU_sparcv9 7 /* alias */
#define TARGET_CPU_sparc64 7 /* alias */
#define TARGET_CPU_ultrasparc 8
#if TARGET_CPU_DEFAULT == TARGET_CPU_v9 || TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc
#if TARGET_CPU_DEFAULT == TARGET_CPU_v9 \
|| TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc
#define CPP_CPU32_DEFAULT_SPEC ""
#define ASM_CPU32_DEFAULT_SPEC ""
@ -140,19 +145,37 @@ extern enum cmodel sparc_cmodel;
#define CPP_CPU64_DEFAULT_SPEC ""
#define ASM_CPU64_DEFAULT_SPEC ""
#if TARGET_CPU_DEFAULT == TARGET_CPU_sparc || TARGET_CPU_DEFAULT == TARGET_CPU_v8 || TARGET_CPU_DEFAULT == TARGET_CPU_supersparc
#if TARGET_CPU_DEFAULT == TARGET_CPU_sparc \
|| TARGET_CPU_DEFAULT == TARGET_CPU_v8
#define CPP_CPU32_DEFAULT_SPEC ""
#define ASM_CPU32_DEFAULT_SPEC ""
#endif
#if TARGET_CPU_DEFAULT == TARGET_CPU_sparclet
#define CPP_CPU32_DEFAULT_SPEC "-D__sparclet__"
#define ASM_CPU32_DEFAULT_SPEC "-Asparclet"
#endif
#if TARGET_CPU_DEFAULT == TARGET_CPU_sparclite
#define CPP_CPU32_DEFAULT_SPEC "-D__sparclite__"
#define ASM_CPU32_DEFAULT_SPEC "-Asparclite"
#endif
#if TARGET_CPU_DEFAULT == TARGET_CPU_supersparc
#define CPP_CPU32_DEFAULT_SPEC "-D__supersparc__ -D__sparc_v8__"
#define ASM_CPU32_DEFAULT_SPEC ""
#endif
#if TARGET_CPU_DEFAULT == TARGET_CPU_hypersparc
#define CPP_CPU32_DEFAULT_SPEC "-D__hypersparc__ -D__sparc_v8__"
#define ASM_CPU32_DEFAULT_SPEC ""
#endif
#if TARGET_CPU_DEFAULT == TARGET_CPU_sparclite86x
#define CPP_CPU32_DEFAULT_SPEC "-D__sparclite86x__ -D__sparc_v8__"
#define ASM_CPU32_DEFAULT_SPEC "-Av8"
#endif
#endif
#if !defined(CPP_CPU32_DEFAULT_SPEC) || !defined(CPP_CPU64_DEFAULT_SPEC)
@ -208,6 +231,8 @@ Unrecognized value in TARGET_CPU_DEFAULT.
%{mcpu=f930:-D__sparclite__} %{mcpu=f934:-D__sparclite__} \
%{mcpu=v8:-D__sparc_v8__} \
%{mcpu=supersparc:-D__supersparc__ -D__sparc_v8__} \
%{mcpu=hypersparc:-D__hypersparc__ -D__sparc_v8__} \
%{mcpu=sparclite86x:-D__sparclite86x__ -D__sparc_v8__} \
%{mcpu=v9:-D__sparc_v9__} \
%{mcpu=ultrasparc:-D__sparc_v9__} \
%{!mcpu*:%{!mcypress:%{!msparclite:%{!mf930:%{!mf934:%{!mv8:%{!msupersparc:%(cpp_cpu_default)}}}}}}} \
@ -243,7 +268,9 @@ Unrecognized value in TARGET_CPU_DEFAULT.
"
/* Macros to distinguish endianness. */
#define CPP_ENDIAN_SPEC "%{mlittle-endian:-D__LITTLE_ENDIAN__}"
#define CPP_ENDIAN_SPEC "\
%{mlittle-endian:-D__LITTLE_ENDIAN__} \
%{mlittle-endian-data:-D__LITTLE_ENDIAN_DATA__}"
/* Macros to distinguish the particular subtarget. */
#define CPP_SUBTARGET_SPEC ""
@ -598,6 +625,8 @@ enum processor_type {
PROCESSOR_SPARCLITE,
PROCESSOR_F930,
PROCESSOR_F934,
PROCESSOR_HYPERSPARC,
PROCESSOR_SPARCLITE86X,
PROCESSOR_SPARCLET,
PROCESSOR_TSC701,
PROCESSOR_V9,
@ -684,7 +713,7 @@ extern int sparc_align_funcs;
/* Define this to set the endianness to use in libgcc2.c, which can
not depend on target_flags. */
#if defined (__LITTLE_ENDIAN__)
#if defined (__LITTLE_ENDIAN__) || defined(__LITTLE_ENDIAN_DATA__)
#define LIBGCC2_WORDS_BIG_ENDIAN 0
#else
#define LIBGCC2_WORDS_BIG_ENDIAN 1
@ -1410,15 +1439,23 @@ extern char leaf_reg_remap[];
in class CLASS, return the class of reg to actually use.
In general this is just CLASS; but on some machines
in some cases it is preferable to use a more restrictive class. */
/* We can't load constants into FP registers. We can't load any FP constant
if an 'E' constraint fails to match it. */
/* - We can't load constants into FP registers. We can't load any FP
constant if an 'E' constraint fails to match it.
- Try and reload integer constants (symbolic or otherwise) back into
registers directly, rather than having them dumped to memory. */
#define PREFERRED_RELOAD_CLASS(X,CLASS) \
(CONSTANT_P (X) \
&& (FP_REG_CLASS_P (CLASS) \
? ((FP_REG_CLASS_P (CLASS) \
|| (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \
&& (HOST_FLOAT_FORMAT != IEEE_FLOAT_FORMAT \
|| HOST_BITS_PER_INT != BITS_PER_WORD))) \
? NO_REGS : (CLASS))
? NO_REGS \
: (!FP_REG_CLASS_P (CLASS) \
&& GET_MODE_CLASS (GET_MODE (X)) == MODE_INT) \
? GENERAL_REGS \
: (CLASS)) \
: (CLASS))
/* Return the register class of a scratch register needed to load IN into
a register of class CLASS in MODE.
@ -2515,6 +2552,32 @@ extern struct rtx_def *legitimize_pic_address ();
if (memory_address_p (MODE, X)) \
goto WIN; }
/* Try a machine-dependent way of reloading an illegitimate address
operand. If we find one, push the reload and jump to WIN. This
macro is used in only one place: `find_reloads_address' in reload.c.
For Sparc 32, we wish to handle addresses by splitting them into
HIGH+LO_SUM pairs, retaining the LO_SUM in the memory reference.
This cuts the number of extra insns by one. */
#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN) \
do { \
/* Decompose SImode constants into hi+lo_sum. We do have to \
rerecognize what we produce, so be careful. */ \
if (CONSTANT_P (X) \
&& GET_MODE (X) == SImode \
&& GET_CODE (X) != LO_SUM && GET_CODE (X) != HIGH) \
{ \
X = gen_rtx_LO_SUM (GET_MODE (X), \
gen_rtx_HIGH (GET_MODE (X), X), X); \
push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL_PTR, \
BASE_REG_CLASS, GET_MODE (X), VOIDmode, 0, 0, \
OPNUM, TYPE); \
goto WIN; \
} \
/* ??? 64-bit reloads. */ \
} while (0)
/* Go to LABEL if ADDR (a legitimate address expression)
has an effect that depends on the machine mode it is used for.
On the SPARC this is never true. */
@ -2803,12 +2866,8 @@ extern struct rtx_def *legitimize_pic_address ();
#define ISSUE_RATE sparc_issue_rate()
/* Adjust the cost of dependencies. */
#define ADJUST_COST(INSN,LINK,DEP,COST) \
if (sparc_cpu == PROCESSOR_SUPERSPARC) \
(COST) = supersparc_adjust_cost (INSN, LINK, DEP, COST); \
else if (sparc_cpu == PROCESSOR_ULTRASPARC) \
(COST) = ultrasparc_adjust_cost (INSN, LINK, DEP, COST); \
else
#define ADJUST_COST(INSN,LINK,DEP,COST) \
sparc_adjust_cost(INSN, LINK, DEP, COST)
extern void ultrasparc_sched_reorder ();
extern void ultrasparc_sched_init ();
@ -3394,11 +3453,10 @@ extern int sparc_flat_epilogue_delay_slots ();
extern int sparc_issue_rate ();
extern int splittable_immediate_memory_operand ();
extern int splittable_symbolic_memory_operand ();
extern int supersparc_adjust_cost ();
extern int sparc_adjust_cost ();
extern int symbolic_memory_operand ();
extern int symbolic_operand ();
extern int text_segment_operand ();
extern int ultrasparc_adjust_cost ();
extern int uns_small_int ();
extern int v9_regcmp_op ();
extern int v9_regcmp_p ();

View File

@ -65,7 +65,7 @@
;; Attribute for cpu type.
;; These must match the values for enum processor_type in sparc.h.
(define_attr "cpu" "v7,cypress,v8,supersparc,sparclite,f930,f934,sparclet,tsc701,v9,ultrasparc"
(define_attr "cpu" "v7,cypress,v8,supersparc,sparclite,f930,f934,hypersparc,sparclite86x,sparclet,tsc701,v9,ultrasparc"
(const (symbol_ref "sparc_cpu_attr")))
;; Attribute for the instruction set.
@ -345,6 +345,53 @@
(eq_attr "type" "imul"))
4 4)
;; ----- hypersparc/sparclite86x scheduling
;; The Hypersparc can issue 1 - 2 insns per cycle. The dual issue cases are:
;; L-Ld/St I-Int F-Float B-Branch LI/LF/LB/II/IF/IB/FF/FB
;; II/FF case is only when loading a 32 bit hi/lo constant
;; Single issue insns include call, jmpl, u/smul, u/sdiv, lda, sta, fcmp
;; Memory delivers its result in one cycle to IU
(define_function_unit "memory" 1 0
(and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
(eq_attr "type" "load,sload,fpload"))
1 1)
(define_function_unit "memory" 1 0
(and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
(eq_attr "type" "store,fpstore"))
2 1)
(define_function_unit "fp_alu" 1 0
(and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
(eq_attr "type" "fp,fpmove,fpcmp"))
1 1)
(define_function_unit "fp_mds" 1 0
(and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
(eq_attr "type" "fpmul"))
1 1)
(define_function_unit "fp_mds" 1 0
(and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
(eq_attr "type" "fpdivs"))
8 6)
(define_function_unit "fp_mds" 1 0
(and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
(eq_attr "type" "fpdivd"))
12 10)
(define_function_unit "fp_mds" 1 0
(and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
(eq_attr "type" "fpsqrt"))
17 15)
(define_function_unit "fp_mds" 1 0
(and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
(eq_attr "type" "imul"))
17 15)
;; ----- sparclet tsc701 scheduling
;; The tsc701 issues 1 insn per cycle.
;; Results may be written back out of order.

2
gcc/configure vendored
View File

@ -5518,7 +5518,7 @@ for machine in $build $host $target; do
.)
target_cpu_default2=TARGET_CPU_"`echo $machine | sed 's/-.*$//'`"
;;
.supersparc | .ultrasparc | .v7 | .v8 | .v9)
.supersparc | .hypersparc | .ultrasparc | .v7 | .v8 | .v9)
target_cpu_default2="TARGET_CPU_$with_cpu"
;;
*)

View File

@ -3347,7 +3347,7 @@ changequote([,])dnl
.)
target_cpu_default2=TARGET_CPU_"`echo $machine | sed 's/-.*$//'`"
;;
.supersparc | .ultrasparc | .v7 | .v8 | .v9)
.supersparc | .hypersparc | .ultrasparc | .v7 | .v8 | .v9)
target_cpu_default2="TARGET_CPU_$with_cpu"
;;
*)