OSDN Git Service

Merge from pch-branch up to tag pch-commit-20020603.
[pf3gnuchains/gcc-fork.git] / gcc / config / sparc / sparc.h
index 3ebe626..333a5d5 100644 (file)
@@ -122,9 +122,11 @@ extern enum cmodel sparc_cmodel;
 #define TARGET_CPU_sparcv9     7       /* alias */
 #define TARGET_CPU_sparc64     7       /* alias */
 #define TARGET_CPU_ultrasparc  8
+#define TARGET_CPU_ultrasparc3 9
 
 #if TARGET_CPU_DEFAULT == TARGET_CPU_v9 \
- || TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc
+ || TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc \
+ || TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc3
 
 #define CPP_CPU32_DEFAULT_SPEC ""
 #define ASM_CPU32_DEFAULT_SPEC ""
@@ -141,6 +143,10 @@ extern enum cmodel sparc_cmodel;
 #define CPP_CPU64_DEFAULT_SPEC "-D__sparc_v9__"
 #define ASM_CPU64_DEFAULT_SPEC "-Av9a"
 #endif
+#if TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc3
+#define CPP_CPU64_DEFAULT_SPEC "-D__sparc_v9__"
+#define ASM_CPU64_DEFAULT_SPEC "-Av9b"
+#endif
 
 #else
 
@@ -230,6 +236,7 @@ Unrecognized value in TARGET_CPU_DEFAULT.
 %{mcpu=sparclite86x:-D__sparclite86x__} \
 %{mcpu=v9:-D__sparc_v9__} \
 %{mcpu=ultrasparc:-D__sparc_v9__} \
+%{mcpu=ultrasparc3:-D__sparc_v9__} \
 %{!mcpu*:%{!mcypress:%{!msparclite:%{!mf930:%{!mf934:%{!mv8:%{!msupersparc:%(cpp_cpu_default)}}}}}}} \
 "
 
@@ -239,20 +246,9 @@ Unrecognized value in TARGET_CPU_DEFAULT.
    sparc64 in 32 bit environments, so for now we only use `sparc64' in
    64 bit environments.  */
 
-#ifdef SPARC_BI_ARCH
-
-#define CPP_ARCH32_SPEC "-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int \
--D__GCC_NEW_VARARGS__ -Acpu=sparc -Amachine=sparc"
-#define CPP_ARCH64_SPEC "-D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int \
--D__arch64__ -Acpu=sparc64 -Amachine=sparc64"
-
-#else
-
 #define CPP_ARCH32_SPEC "-D__GCC_NEW_VARARGS__ -Acpu=sparc -Amachine=sparc"
 #define CPP_ARCH64_SPEC "-D__arch64__ -Acpu=sparc64 -Amachine=sparc64"
 
-#endif
-
 #define CPP_ARCH_DEFAULT_SPEC \
 (DEFAULT_ARCH32_P ? CPP_ARCH32_SPEC : CPP_ARCH64_SPEC)
 
@@ -296,6 +292,7 @@ Unrecognized value in TARGET_CPU_DEFAULT.
 %{mv8plus:-Av8plus} \
 %{mcpu=v9:-Av9} \
 %{mcpu=ultrasparc:%{!mv8plus:-Av9a}} \
+%{mcpu=ultrasparc3:%{!mv8plus:-Av9b}} \
 %{!mcpu*:%{!mcypress:%{!msparclite:%{!mf930:%{!mf934:%{!mv8:%{!msupersparc:%(asm_cpu_default)}}}}}}} \
 "
 
@@ -364,10 +361,6 @@ Unrecognized value in TARGET_CPU_DEFAULT.
 #define LINK_GCC_C_SEQUENCE_SPEC "%G %L %G %L"
 
 \f
-#ifdef SPARC_BI_ARCH
-#define NO_BUILTIN_PTRDIFF_TYPE
-#define NO_BUILTIN_SIZE_TYPE
-#endif
 #define PTRDIFF_TYPE (TARGET_ARCH64 ? "long int" : "int")
 #define SIZE_TYPE (TARGET_ARCH64 ? "long unsigned int" : "unsigned int")
 
@@ -623,7 +616,8 @@ enum processor_type {
   PROCESSOR_SPARCLET,
   PROCESSOR_TSC701,
   PROCESSOR_V9,
-  PROCESSOR_ULTRASPARC
+  PROCESSOR_ULTRASPARC,
+  PROCESSOR_ULTRASPARC3
 };
 
 /* This is set from -m{cpu,tune}=xxx.  */
@@ -832,19 +826,6 @@ if (TARGET_ARCH64                          \
 #ifndef SUNOS4_SHARED_LIBRARIES
 #define SUNOS4_SHARED_LIBRARIES 0
 #endif
-
-
-/* Use text section for a constant
-   unless we need more alignment than that offers.  */
-/* This is defined differently for v9 in a cover file.  */
-#define SELECT_RTX_SECTION(MODE, X, ALIGN)     \
-{                                              \
-  if (GET_MODE_BITSIZE (MODE) <= MAX_TEXT_ALIGN \
-      && ! (flag_pic && (symbolic_operand ((X), (MODE)) || SUNOS4_SHARED_LIBRARIES)))  \
-    text_section ();                           \
-  else                                         \
-    data_section ();                           \
-}
 \f
 /* Standard register usage.  */
 
@@ -1005,12 +986,16 @@ do                                                               \
       fixed_regs[4] = 0;                                       \
     if (TARGET_FLAT)                                           \
       {                                                                \
+       int regno;                                              \
        /* Let the compiler believe the frame pointer is still  \
           %fp, but output it as %i7.  */                       \
        fixed_regs[31] = 1;                                     \
        reg_names[HARD_FRAME_POINTER_REGNUM] = "%i7";           \
        /* Disable leaf functions */                            \
        memset (sparc_leaf_regs, 0, FIRST_PSEUDO_REGISTER);     \
+       /* Make LEAF_REG_REMAP a noop.  */                      \
+       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) \
+         leaf_reg_remap [regno] = regno;                       \
       }                                                                \
   }                                                            \
 while (0)
@@ -1260,16 +1245,31 @@ extern enum reg_class sparc_regno_reg_class[FIRST_PSEUDO_REGISTER];
 
 /* This is the order in which to allocate registers normally.  
    
-   We put %f0/%f1 last among the float registers, so as to make it more
+   We put %f0-%f7 last among the float registers, so as to make it more
    likely that a pseudo-register which dies in the float return register
-   will get allocated to the float return register, thus saving a move
-   instruction at the end of the function.  */
+   area will get allocated to the float return register, thus saving a move
+   instruction at the end of the function.
+
+   Similarly for integer return value registers.
+
+   We know in this case that we will not end up with a leaf function.
+
+   The register allocater is given the global and out registers first
+   because these registers are call clobbered and thus less useful to
+   global register allocation.
+
+   Next we list the local and in registers.  They are not call clobbered
+   and thus very useful for global register allocation.  We list the input
+   registers before the locals so that it is more likely the incoming
+   arguments received in those registers can just stay there and not be
+   reloaded.  */
 
 #define REG_ALLOC_ORDER \
-{ 8, 9, 10, 11, 12, 13, 2, 3,          \
-  15, 16, 17, 18, 19, 20, 21, 22,      \
-  23, 24, 25, 26, 27, 28, 29, 31,      \
-  34, 35, 36, 37, 38, 39,              /* %f2-%f7 */   \
+{ 1, 2, 3, 4, 5, 6, 7,                 /* %g1-%g7 */   \
+  13, 12, 11, 10, 9, 8,                /* %o5-%o0 */   \
+  15,                                  /* %o7 */       \
+  16, 17, 18, 19, 20, 21, 22, 23,      /* %l0-%l7 */   \
+  29, 28, 27, 26, 25, 24, 31,          /* %i5-%i0,%i7 */\
   40, 41, 42, 43, 44, 45, 46, 47,      /* %f8-%f15 */  \
   48, 49, 50, 51, 52, 53, 54, 55,      /* %f16-%f23 */ \
   56, 57, 58, 59, 60, 61, 62, 63,      /* %f24-%f31 */ \
@@ -1277,37 +1277,55 @@ extern enum reg_class sparc_regno_reg_class[FIRST_PSEUDO_REGISTER];
   72, 73, 74, 75, 76, 77, 78, 79,      /* %f40-%f47 */ \
   80, 81, 82, 83, 84, 85, 86, 87,      /* %f48-%f55 */ \
   88, 89, 90, 91, 92, 93, 94, 95,      /* %f56-%f63 */ \
-  32, 33,                              /* %f0,%f1 */   \
-  96, 97, 98, 99, 100,                 /* %fcc0-3, %icc */ \
-  1, 4, 5, 6, 7, 0, 14, 30, 101}
+  39, 38, 37, 36, 35, 34, 33, 32,      /* %f7-%f0 */   \
+  96, 97, 98, 99,                      /* %fcc0-3 */   \
+  100, 0, 14, 30, 101}                 /* %icc, %g0, %o6, %i6, %sfp */
 
 /* This is the order in which to allocate registers for
-   leaf functions.  If all registers can fit in the "gi" registers,
-   then we have the possibility of having a leaf function.  */
+   leaf functions.  If all registers can fit in the global and
+   output registers, then we have the possibility of having a leaf
+   function.
+
+   The macro actually mentioned the input registers first,
+   because they get renumbered into the output registers once
+   we know really do have a leaf function.
+
+   To be more precise, this register allocation order is used
+   when %o7 is found to not be clobbered right before register
+   allocation.  Normally, the reason %o7 would be clobbered is
+   due to a call which could not be transformed into a sibling
+   call.
+
+   As a consequence, it is possible to use the leaf register
+   allocation order and not end up with a leaf function.  We will
+   not get suboptimal register allocation in that case because by
+   definition of being potentially leaf, there were no function
+   calls.  Therefore, allocation order within the local register
+   window is not critical like it is when we do have function calls.  */
 
 #define REG_LEAF_ALLOC_ORDER \
-{ 2, 3, 24, 25, 26, 27, 28, 29,                \
-  4, 5, 6, 7, 1,                       \
-  15, 8, 9, 10, 11, 12, 13,            \
-  16, 17, 18, 19, 20, 21, 22, 23,      \
-  34, 35, 36, 37, 38, 39,              \
-  40, 41, 42, 43, 44, 45, 46, 47,      \
-  48, 49, 50, 51, 52, 53, 54, 55,      \
-  56, 57, 58, 59, 60, 61, 62, 63,      \
-  64, 65, 66, 67, 68, 69, 70, 71,      \
-  72, 73, 74, 75, 76, 77, 78, 79,      \
-  80, 81, 82, 83, 84, 85, 86, 87,      \
-  88, 89, 90, 91, 92, 93, 94, 95,      \
-  32, 33,                              \
-  96, 97, 98, 99, 100,                 \
-  0, 14, 30, 31, 101}
+{ 1, 2, 3, 4, 5, 6, 7,                         /* %g1-%g7 */   \
+  29, 28, 27, 26, 25, 24,              /* %i5-%i0 */   \
+  15,                                  /* %o7 */       \
+  13, 12, 11, 10, 9, 8,                        /* %o5-%o0 */   \
+  16, 17, 18, 19, 20, 21, 22, 23,      /* %l0-%l7 */   \
+  40, 41, 42, 43, 44, 45, 46, 47,      /* %f8-%f15 */  \
+  48, 49, 50, 51, 52, 53, 54, 55,      /* %f16-%f23 */ \
+  56, 57, 58, 59, 60, 61, 62, 63,      /* %f24-%f31 */ \
+  64, 65, 66, 67, 68, 69, 70, 71,      /* %f32-%f39 */ \
+  72, 73, 74, 75, 76, 77, 78, 79,      /* %f40-%f47 */ \
+  80, 81, 82, 83, 84, 85, 86, 87,      /* %f48-%f55 */ \
+  88, 89, 90, 91, 92, 93, 94, 95,      /* %f56-%f63 */ \
+  39, 38, 37, 36, 35, 34, 33, 32,      /* %f7-%f0 */   \
+  96, 97, 98, 99,                      /* %fcc0-3 */   \
+  100, 0, 14, 30, 31, 101}             /* %icc, %g0, %o6, %i6, %i7, %sfp */
   
 #define ORDER_REGS_FOR_LOCAL_ALLOC order_regs_for_local_alloc ()
 
 extern char sparc_leaf_regs[];
 #define LEAF_REGISTERS sparc_leaf_regs
 
-extern const char leaf_reg_remap[];
+extern char leaf_reg_remap[];
 #define LEAF_REG_REMAP(REGNO) (leaf_reg_remap[REGNO])
 
 /* The class value for index registers, and the one for base regs.  */
@@ -1414,7 +1432,10 @@ extern const char leaf_reg_remap[];
 
    We need a temporary when loading/storing a HImode/QImode value
    between memory and the FPU registers.  This can happen when combine puts
-   a paradoxical subreg in a float/fix conversion insn.  */
+   a paradoxical subreg in a float/fix conversion insn.
+
+   We need a temporary when loading/storing a DFmode value between
+   unaligned memory and the upper FPU registers.  */
 
 #define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, IN)          \
   ((FP_REG_CLASS_P (CLASS)                                     \
@@ -1423,28 +1444,36 @@ extern const char leaf_reg_remap[];
         || ((GET_CODE (IN) == REG || GET_CODE (IN) == SUBREG)  \
             && true_regnum (IN) == -1)))                       \
    ? GENERAL_REGS                                              \
-   : (((TARGET_CM_MEDANY                                       \
-        && symbolic_operand ((IN), (MODE)))                    \
-       || (TARGET_CM_EMBMEDANY                                 \
-           && text_segment_operand ((IN), (MODE))))            \
-      && !flag_pic)                                            \
-     ? GENERAL_REGS                                            \
-     : NO_REGS)
+   : ((CLASS) == EXTRA_FP_REGS && (MODE) == DFmode             \
+      && GET_CODE (IN) == MEM && TARGET_ARCH32                 \
+      && ! mem_min_alignment ((IN), 8))                                \
+     ? FP_REGS                                                 \
+     : (((TARGET_CM_MEDANY                                     \
+         && symbolic_operand ((IN), (MODE)))                   \
+        || (TARGET_CM_EMBMEDANY                                \
+            && text_segment_operand ((IN), (MODE))))           \
+       && !flag_pic)                                           \
+       ? GENERAL_REGS                                          \
+       : NO_REGS)
 
 #define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, IN)         \
-   ((FP_REG_CLASS_P (CLASS)                                    \
+  ((FP_REG_CLASS_P (CLASS)                                     \
      && ((MODE) == HImode || (MODE) == QImode)                 \
      && (GET_CODE (IN) == MEM                                  \
          || ((GET_CODE (IN) == REG || GET_CODE (IN) == SUBREG) \
              && true_regnum (IN) == -1)))                      \
-    ? GENERAL_REGS                                             \
-   : (((TARGET_CM_MEDANY                                       \
-        && symbolic_operand ((IN), (MODE)))                    \
-       || (TARGET_CM_EMBMEDANY                                 \
-           && text_segment_operand ((IN), (MODE))))            \
-      && !flag_pic)                                            \
-     ? GENERAL_REGS                                            \
-     : NO_REGS)
+   ? GENERAL_REGS                                              \
+   : ((CLASS) == EXTRA_FP_REGS && (MODE) == DFmode             \
+      && GET_CODE (IN) == MEM && TARGET_ARCH32                 \
+      && ! mem_min_alignment ((IN), 8))                                \
+     ? FP_REGS                                                 \
+     : (((TARGET_CM_MEDANY                                     \
+         && symbolic_operand ((IN), (MODE)))                   \
+        || (TARGET_CM_EMBMEDANY                                \
+            && text_segment_operand ((IN), (MODE))))           \
+       && !flag_pic)                                           \
+       ? GENERAL_REGS                                          \
+       : NO_REGS)
 
 /* On SPARC it is not possible to directly move data between 
    GENERAL_REGS and FP_REGS.  */
@@ -1780,7 +1809,8 @@ function_arg_padding ((MODE), (TYPE))
    stored from the compare operation.  Note that we can't use "rtx" here
    since it hasn't been defined!  */
 
-extern struct rtx_def *sparc_compare_op0, *sparc_compare_op1;
+extern GTY(()) rtx sparc_compare_op0;
+extern GTY(()) rtx sparc_compare_op1;
 
 \f
 /* Generate the special assembly code needed to tell the assembler whatever
@@ -1902,8 +1932,25 @@ do {                                                                     \
 #define STRICT_ARGUMENT_NAMING TARGET_V9
 
 /* We do not allow sibling calls if -mflat, nor
-   we do not allow indirect calls to be optimized into sibling calls.  */
-#define FUNCTION_OK_FOR_SIBCALL(DECL) (DECL && ! TARGET_FLAT)
+   we do not allow indirect calls to be optimized into sibling calls.
+
+   Also, on sparc 32-bit we cannot emit a sibling call when the
+   current function returns a structure.  This is because the "unimp
+   after call" convention would cause the callee to return to the
+   wrong place.  The generic code already disallows cases where the
+   function being called returns a structure.
+
+   It may seem strange how this last case could occur.  Usually there
+   is code after the call which jumps to epilogue code which dumps the
+   return value into the struct return area.  That ought to invalidate
+   the sibling call right?  Well, in the c++ case we can end up passing
+   the pointer to the struct return area to a constructor (which returns
+   void) and then nothing else happens.  Such a sibling call would look
+   valid without the added check here.  */
+#define FUNCTION_OK_FOR_SIBCALL(DECL) \
+       (DECL \
+        && ! TARGET_FLAT \
+        && (TARGET_ARCH64 || ! current_function_returns_struct))
 
 /* Generate RTL to flush the register windows so as to make arbitrary frames
    available.  */
@@ -2336,12 +2383,13 @@ do {                                                                    \
   /* Decompose SImode constants into hi+lo_sum.  We do have to                 \
      rerecognize what we produce, so be careful.  */                   \
   if (CONSTANT_P (X)                                                   \
-      && (MODE != TFmode || TARGET_V9)                                 \
+      && (MODE != TFmode || TARGET_ARCH64)                             \
       && GET_MODE (X) == SImode                                                \
       && GET_CODE (X) != LO_SUM && GET_CODE (X) != HIGH                        \
       && ! (flag_pic                                                   \
            && (symbolic_operand (X, Pmode)                             \
-               || pic_address_needs_scratch (X))))                     \
+               || pic_address_needs_scratch (X)))                      \
+      && sparc_cmodel <= CM_MEDLOW)                                    \
     {                                                                  \
       X = gen_rtx_LO_SUM (GET_MODE (X),                                        \
                          gen_rtx_HIGH (GET_MODE (X), X), X);           \
@@ -2358,16 +2406,6 @@ do {                                                                    \
    On the SPARC this is never true.  */
 
 #define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL)
-
-/* If we are referencing a function make the SYMBOL_REF special.
-   In the Embedded Medium/Anywhere code model, %g4 points to the data segment
-   so we must not add it to function addresses.  */
-
-#define ENCODE_SECTION_INFO(DECL, FIRST)                               \
-  do {                                                                 \
-    if (TARGET_CM_EMBMEDANY && TREE_CODE (DECL) == FUNCTION_DECL)      \
-      SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1;                 \
-  } while (0)
 \f
 /* Specify the machine mode that this machine uses
    for the index in the tablejump instruction.  */
@@ -2523,6 +2561,11 @@ do {                                                                    \
 #define LTTF2_LIBCALL "_Q_flt"
 #define LETF2_LIBCALL "_Q_fle"
 
+/* Assume by default that the _Qp_* 64-bit libcalls are implemented such
+   that the inputs are fully consumed before the output memory is clobbered.  */
+
+#define TARGET_BUGGY_QP_LIB    0
+
 /* We can define the TFmode sqrt optab only if TARGET_FPU.  This is because
    with soft-float, the SFmode and DFmode sqrt instructions will be absent,
    and the compiler will notice and try to use the TFmode sqrt instruction
@@ -2570,33 +2613,6 @@ do {                                                                    \
    of the libgcc2 functions is used.  */
 #define FLOAT_LIB_COMPARE_RETURNS_BOOL(MODE, COMPARISON) ((MODE) == TFmode)
 
-/* Compute the cost of computing a constant rtl expression RTX
-   whose rtx-code is CODE.  The body of this macro is a portion
-   of a switch statement.  If the code is computed here,
-   return it with a return statement.  Otherwise, break from the switch.  */
-
-#define CONST_COSTS(RTX,CODE,OUTER_CODE) \
-  case CONST_INT:                                              \
-    if (INTVAL (RTX) < 0x1000 && INTVAL (RTX) >= -0x1000)      \
-      return 0;                                                        \
-  case HIGH:                                                   \
-    return 2;                                                  \
-  case CONST:                                                  \
-  case LABEL_REF:                                              \
-  case SYMBOL_REF:                                             \
-    return 4;                                                  \
-  case CONST_DOUBLE:                                           \
-    if (GET_MODE (RTX) == DImode)                              \
-      if ((XINT (RTX, 3) == 0                                  \
-          && (unsigned) XINT (RTX, 2) < 0x1000)                \
-         || (XINT (RTX, 3) == -1                               \
-             && XINT (RTX, 2) < 0                              \
-             && XINT (RTX, 2) >= -0x1000))                     \
-       return 0;                                               \
-    return 8;
-
-#define ADDRESS_COST(RTX)  1
-
 /* Compute extra cost of moving data between one register class
    and another.  */
 #define GENERAL_OR_I64(C) ((C) == GENERAL_REGS || (C) == I64_REGS)
@@ -2604,34 +2620,59 @@ do {                                                                    \
   (((FP_REG_CLASS_P (CLASS1) && GENERAL_OR_I64 (CLASS2)) \
     || (GENERAL_OR_I64 (CLASS1) && FP_REG_CLASS_P (CLASS2)) \
     || (CLASS1) == FPCC_REGS || (CLASS2) == FPCC_REGS)         \
-   ? (sparc_cpu == PROCESSOR_ULTRASPARC ? 12 : 6) : 2)
+   ? ((sparc_cpu == PROCESSOR_ULTRASPARC \
+       || sparc_cpu == PROCESSOR_ULTRASPARC3) ? 12 : 6) : 2)
+
+/* Provide the cost of a branch.  For pre-v9 processors we use
+   a value of 3 to take into account the potential annulling of
+   the delay slot (which ends up being a bubble in the pipeline slot)
+   plus a cycle to take into consideration the instruction cache
+   effects.
+
+   On v9 and later, which have branch prediction facilities, we set
+   it to the depth of the pipeline as that is the cost of a
+   mispredicted branch.  */
+
+#define BRANCH_COST \
+       ((sparc_cpu == PROCESSOR_V9 \
+         || sparc_cpu == PROCESSOR_ULTRASPARC) \
+        ? 7 \
+         : (sparc_cpu == PROCESSOR_ULTRASPARC3 \
+            ? 9 : 3))
+
+/* The cases that RTX_COSTS handles.  */
+
+#define RTX_COSTS_CASES        \
+case PLUS: case MINUS: case ABS: case NEG: \
+case FLOAT: case UNSIGNED_FLOAT: \
+case FIX: case UNSIGNED_FIX: \
+case FLOAT_EXTEND: case FLOAT_TRUNCATE: \
+case SQRT: \
+case COMPARE: case IF_THEN_ELSE: \
+case MEM: \
+case MULT: case DIV: case UDIV: case MOD: case UMOD: \
+case CONST_INT: case HIGH: case CONST: \
+case LABEL_REF: case SYMBOL_REF: case CONST_DOUBLE:
 
 /* Provide the costs of a rtl expression.  This is in the body of a
-   switch on CODE.  The purpose for the cost of MULT is to encourage
-   `synth_mult' to find a synthetic multiply when reasonable.
-
-   If we need more than 12 insns to do a multiply, then go out-of-line,
-   since the call overhead will be < 10% of the cost of the multiply.  */
+   switch on CODE.  */
 
 #define RTX_COSTS(X,CODE,OUTER_CODE)                   \
-  case MULT:                                           \
-    if (sparc_cpu == PROCESSOR_ULTRASPARC)             \
-      return (GET_MODE (X) == DImode ?                 \
-              COSTS_N_INSNS (34) : COSTS_N_INSNS (19));        \
-    return TARGET_HARD_MUL ? COSTS_N_INSNS (5) : COSTS_N_INSNS (25); \
-  case DIV:                                            \
-  case UDIV:                                           \
-  case MOD:                                            \
-  case UMOD:                                           \
-    if (sparc_cpu == PROCESSOR_ULTRASPARC)             \
-      return (GET_MODE (X) == DImode ?                 \
-              COSTS_N_INSNS (68) : COSTS_N_INSNS (37));        \
-    return COSTS_N_INSNS (25);                         \
-  /* Make FLOAT and FIX more expensive than CONST_DOUBLE,\
-     so that cse will favor the latter.  */            \
-  case FLOAT:                                          \
-  case FIX:                                            \
-    return 19;
+  RTX_COSTS_CASES                                      \
+    return sparc_rtx_costs(X,CODE,OUTER_CODE);
+
+#define ADDRESS_COST(RTX)  1
+
+#define PREFETCH_BLOCK \
+       ((sparc_cpu == PROCESSOR_ULTRASPARC \
+          || sparc_cpu == PROCESSOR_ULTRASPARC3) \
+         ? 64 : 32)
+
+#define SIMULTANEOUS_PREFETCHES \
+       ((sparc_cpu == PROCESSOR_ULTRASPARC) \
+         ? 2 \
+         : (sparc_cpu == PROCESSOR_ULTRASPARC3 \
+            ? 8 : 3))
 \f
 /* Control the assembler format that we output.  */
 
@@ -2834,24 +2875,8 @@ do {                                                                     \
 
 /* Output code to add DELTA to the first argument, and then jump to FUNCTION.
    Used for C++ multiple inheritance.  */
-#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION)       \
-do {                                                                   \
-  int reg = 0;                                                         \
-                                                                       \
-  if (TARGET_ARCH64                                                    \
-      && aggregate_value_p (TREE_TYPE (TREE_TYPE (FUNCTION))))         \
-    reg = 1;                                                           \
-  if ((DELTA) >= 4096 || (DELTA) < -4096)                              \
-    fprintf (FILE, "\tset\t%d, %%g1\n\tadd\t%%o%d, %%g1, %%o%d\n",     \
-            (int)(DELTA), reg, reg);                                   \
-  else                                                                 \
-    fprintf (FILE, "\tadd\t%%o%d, %d, %%o%d\n", reg, (int)(DELTA), reg);\
-  fprintf (FILE, "\tor\t%%o7, %%g0, %%g1\n");                          \
-  fprintf (FILE, "\tcall\t");                                          \
-  assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0));       \
-  fprintf (FILE, ", 0\n");                                             \
-  fprintf (FILE, "\t or\t%%g1, %%g0, %%o7\n");                         \
-} while (0)
+#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \
+  sparc_output_mi_thunk (FILE, THUNK_FNDECL, DELTA, FUNCTION)
 
 #define PRINT_OPERAND_PUNCT_VALID_P(CHAR) \
   ((CHAR) == '#' || (CHAR) == '*' || (CHAR) == '^' || (CHAR) == '(' || (CHAR) == '_')
@@ -2945,7 +2970,9 @@ do {                                                                      \
 
 #define PREDICATE_CODES                                                        \
 {"reg_or_0_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}},          \
+{"const1_operand", {CONST_INT}},                                       \
 {"fp_zero_operand", {CONST_DOUBLE}},                                   \
+{"fp_register_operand", {SUBREG, REG}},                                        \
 {"intreg_operand", {SUBREG, REG}},                                     \
 {"fcc_reg_operand", {REG}},                                            \
 {"fcc0_reg_operand", {REG}},                                           \