sparc.h (PREFERRED_RELOAD_CLASS): Select GENERAL_REGS for integer data not destined...
authorRichard Henderson <rth@gcc.gnu.org>
Thu, 7 Jan 1999 03:18:28 +0000 (19:18 -0800)
committerRichard Henderson <rth@gcc.gnu.org>
Thu, 7 Jan 1999 03:18:28 +0000 (19:18 -0800)
        * 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

gcc/ChangeLog
gcc/config/sparc/sparc.c
gcc/config/sparc/sparc.h
gcc/config/sparc/sparc.md
gcc/configure
gcc/configure.in

index 54197b28c03fd37f90337989828e9324f10fd920..5493f51623a602bacffeb42b5b90725dc6f2cc2a 100644 (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.
index 2748a9ad643e3ea60b5f2b496d03b0c24fd43e31..a538070b2c6af37baaf77f9ada0b1b6bbc81325a 100644 (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 ()
 {
index a0ecb146f0beb4c3f403f91d3fc5d2348e6b1802..a71ca1b3b626b48ad13bb2023f3f3c0082f19047 100644 (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 ();
index 59fcd59afb550d40a2c48cd56ac146ce3b9f930d..2b1e518de92fb8608450248ce3e7fba7acce3371 100644 (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.
     (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.
index 63b5027f118d7a7a7cac71274f28d62977d59033..9e0748eed54ab5ecc0d960a2568d53d14b65a7ac 100755 (executable)
@@ -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"
                                ;;
                        *)
index c77d3cd88f7dca068777f072a61b61a6bb51fb2e..92675afb5968d6049a6d81662999fa1878f48df3 100644 (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"
                                ;;
                        *)