aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Henderson <rth@gcc.gnu.org>1999-01-06 19:18:28 -0800
committerRichard Henderson <rth@gcc.gnu.org>1999-01-06 19:18:28 -0800
commit8947065c4433a12febf38644b041e32081825000 (patch)
treec4682cc19df3771080fc19efa4aad62918b35228 /gcc
parent4ddb3ea6f72010459858f5ec470578481d2f7274 (diff)
downloadgcc-8947065c4433a12febf38644b041e32081825000.zip
gcc-8947065c4433a12febf38644b041e32081825000.tar.gz
gcc-8947065c4433a12febf38644b041e32081825000.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog28
-rw-r--r--gcc/config/sparc/sparc.c415
-rw-r--r--gcc/config/sparc/sparc.h98
-rw-r--r--gcc/config/sparc/sparc.md49
-rwxr-xr-xgcc/configure2
-rw-r--r--gcc/configure.in2
6 files changed, 421 insertions, 173 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 54197b2..5493f51 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 2748a9a..a538070 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -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 ()
{
diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h
index a0ecb14..a71ca1b 100644
--- a/gcc/config/sparc/sparc.h
+++ b/gcc/config/sparc/sparc.h
@@ -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 ();
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index 59fcd59..2b1e518 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -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.
diff --git a/gcc/configure b/gcc/configure
index 63b5027..9e0748e 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -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"
;;
*)
diff --git a/gcc/configure.in b/gcc/configure.in
index c77d3cd..92675af 100644
--- a/gcc/configure.in
+++ b/gcc/configure.in
@@ -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"
;;
*)