OSDN Git Service

* toplev.c (target_options): Add value field.
[pf3gnuchains/gcc-fork.git] / gcc / config / sparc / sparc.h
index 3785bad..61e6f94 100644 (file)
@@ -1,6 +1,6 @@
 /* Definitions of target machine for GNU compiler, for Sun SPARC.
    Copyright (C) 1987, 1988, 1989, 1992, 1994, 1995, 1996, 1997, 1998, 1999
-   2000, 2001 Free Software Foundation, Inc.
+   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com).
    64 bit SPARC V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
    at Cygnus Support.
@@ -107,7 +107,7 @@ 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 
+/* 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 */
@@ -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
 
@@ -181,7 +187,7 @@ extern enum cmodel sparc_cmodel;
 #endif
 
 #if !defined(CPP_CPU32_DEFAULT_SPEC) || !defined(CPP_CPU64_DEFAULT_SPEC)
-Unrecognized value in TARGET_CPU_DEFAULT.
+ #error Unrecognized value in TARGET_CPU_DEFAULT.
 #endif
 
 #ifdef SPARC_BI_ARCH
@@ -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)}}}}}}} \
 "
 
@@ -326,9 +323,11 @@ Unrecognized value in TARGET_CPU_DEFAULT.
 /* Special flags to the Sun-4 assembler when using pipe for input.  */
 
 #define ASM_SPEC "\
-%| %{R} %{!pg:%{!p:%{fpic:-k} %{fPIC:-k}}} %{keep-local-as-symbols:-L} \
+%{R} %{!pg:%{!p:%{fpic:-k} %{fPIC:-k}}} %{keep-local-as-symbols:-L} \
 %(asm_cpu) %(asm_relax)"
 
+#define AS_NEEDS_DASH_FOR_PIPED_INPUT
+
 /* This macro defines names of additional specifications to put in the specs
    that can be used in various specifications like CC1_SPEC.  Its definition
    is an initializer with a subgrouping for each command option.
@@ -358,49 +357,27 @@ Unrecognized value in TARGET_CPU_DEFAULT.
   SUBTARGET_EXTRA_SPECS
 
 #define SUBTARGET_EXTRA_SPECS
+
+/* Because libgcc can generate references back to libc (via .umul etc.) we have
+   to list libc again after the second libgcc.  */
+#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")
 
 /* ??? This should be 32 bits for v9 but what can we do?  */
 #define WCHAR_TYPE "short unsigned int"
 #define WCHAR_TYPE_SIZE 16
-#define MAX_WCHAR_TYPE_SIZE 16
 
 /* Show we can debug even without a frame pointer.  */
 #define CAN_DEBUG_WITHOUT_FP
 
-/* To make profiling work with -f{pic,PIC}, we need to emit the profiling
-   code into the rtl.  Also, if we are profiling, we cannot eliminate
-   the frame pointer (because the return address will get smashed).  */
-
-#define OVERRIDE_OPTIONS \
-  do {                                                                 \
-    if (profile_flag || profile_arc_flag)                              \
-      {                                                                        \
-       if (flag_pic)                                                   \
-         {                                                             \
-           const char *const pic_string = (flag_pic == 1) ? "-fpic" : "-fPIC";\
-           warning ("%s and profiling conflict: disabling %s",         \
-                    pic_string, pic_string);                           \
-           flag_pic = 0;                                               \
-         }                                                             \
-       flag_omit_frame_pointer = 0;                                    \
-      }                                                                        \
-    sparc_override_options ();                                         \
-    SUBTARGET_OVERRIDE_OPTIONS;                                                \
-  } while (0)
-
-/* This is meant to be redefined in the host dependent files.  */
-#define SUBTARGET_OVERRIDE_OPTIONS
+#define OVERRIDE_OPTIONS  sparc_override_options ()
 
 /* Generate DBX debugging information.  */
 
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
 \f
 /* Run-time compilation parameters selecting different hardware subsets.  */
 
@@ -410,11 +387,6 @@ extern int target_flags;
 #define MASK_FPU 1
 #define TARGET_FPU (target_flags & MASK_FPU)
 
-/* Nonzero if we should use function_epilogue().  Otherwise, we
-   use fast return insns, but lose some generality.  */
-#define MASK_EPILOGUE 2
-#define TARGET_EPILOGUE (target_flags & MASK_EPILOGUE)
-
 /* Nonzero if we should assume that double pointers might be unaligned.
    This can happen when linking gcc compiled code with other compilers,
    because the ABI only guarantees 4 byte alignment.  */
@@ -441,7 +413,7 @@ extern int target_flags;
 #define MASK_V9 0x40
 #define TARGET_V9 (target_flags & MASK_V9)
 
-/* Non-zero to generate code that uses the instructions deprecated in
+/* Nonzero to generate code that uses the instructions deprecated in
    the v9 architecture.  This option only applies to v9 systems.  */
 /* ??? This isn't user selectable yet.  It's used to enable such insns
    on 32 bit v9 systems and for the moment they're permanently disabled
@@ -453,7 +425,7 @@ extern int target_flags;
 #define MASK_ISA \
 (MASK_V8 + MASK_SPARCLITE + MASK_SPARCLET + MASK_V9 + MASK_DEPRECATED_V8_INSNS)
 
-/* Non-zero means don't pass `-assert pure-text' to the linker.  */
+/* Nonzero means don't pass `-assert pure-text' to the linker.  */
 #define MASK_IMPURE_TEXT 0x100
 #define TARGET_IMPURE_TEXT (target_flags & MASK_IMPURE_TEXT)
 
@@ -464,7 +436,7 @@ extern int target_flags;
 #define MASK_FLAT 0x200
 #define TARGET_FLAT (target_flags & MASK_FLAT)
 
-/* Nonzero means use the registers that the Sparc ABI reserves for
+/* Nonzero means use the registers that the SPARC ABI reserves for
    application software.  This must be the default to coincide with the
    setting in FIXED_REGISTERS.  */
 #define MASK_APP_REGS 0x400
@@ -476,7 +448,7 @@ extern int target_flags;
 #define MASK_HARD_QUAD 0x800
 #define TARGET_HARD_QUAD (target_flags & MASK_HARD_QUAD)
 
-/* Non-zero on little-endian machines.  */
+/* Nonzero on little-endian machines.  */
 /* ??? Little endian support currently only exists for sparclet-aout and
    sparc64-elf configurations.  May eventually want to expand the support
    to all targets, but for now it's kept local to only those two.  */
@@ -497,25 +469,25 @@ extern int target_flags;
 
 /* 0x20000,0x40000 unused */
 
-/* Non-zero means use a stack bias of 2047.  Stack offsets are obtained by
+/* Nonzero means use a stack bias of 2047.  Stack offsets are obtained by
    adding 2047 to %sp.  This option is for v9 only and is the default.  */
 #define MASK_STACK_BIAS 0x80000
 #define TARGET_STACK_BIAS (target_flags & MASK_STACK_BIAS)
 
 /* 0x100000,0x200000 unused */
 
-/* Non-zero means -m{,no-}fpu was passed on the command line.  */
+/* Nonzero means -m{,no-}fpu was passed on the command line.  */
 #define MASK_FPU_SET 0x400000
 #define TARGET_FPU_SET (target_flags & MASK_FPU_SET)
 
 /* Use the UltraSPARC Visual Instruction Set extensions.  */
-#define MASK_VIS 0x1000000          
+#define MASK_VIS 0x1000000
 #define TARGET_VIS (target_flags & MASK_VIS)
 
 /* Compile for Solaris V8+.  32 bit Solaris preserves the high bits of
    the current out and global registers and Linux 2.2+ as well.  */
 #define MASK_V8PLUS 0x2000000
-#define TARGET_V8PLUS (target_flags & MASK_V8PLUS)                            
+#define TARGET_V8PLUS (target_flags & MASK_V8PLUS)
 
 /* Force a the fastest alignment on structures to take advantage of
    faster copies.  */
@@ -538,7 +510,7 @@ extern int target_flags;
 
 #define TARGET_HARD_MUL                                        \
   (TARGET_V8 || TARGET_SPARCLITE || TARGET_SPARCLET    \
-   || TARGET_DEPRECATED_V8_INSNS || TARGET_V8PLUS)                        
+   || TARGET_DEPRECATED_V8_INSNS || TARGET_V8PLUS)
 
 
 /* Macro to define tables used to set the flags.
@@ -558,10 +530,6 @@ extern int target_flags;
     {"soft-float", -MASK_FPU,                                          \
      N_("Do not use hardware fp") },                                   \
     {"soft-float", MASK_FPU_SET,                       NULL },         \
-    {"epilogue", MASK_EPILOGUE,                                                \
-     N_("Use function_epilogue()") },                                  \
-    {"no-epilogue", -MASK_EPILOGUE,                                    \
-     N_("Do not use function_epilogue()") },                           \
     {"unaligned-doubles", MASK_UNALIGNED_DOUBLES,                      \
      N_("Assume possible double misalignment") },                      \
     {"no-unaligned-doubles", -MASK_UNALIGNED_DOUBLES,                  \
@@ -594,15 +562,15 @@ extern int target_flags;
     {"cypress", 0,                                                     \
      N_("Optimize for Cypress processors") },                          \
     {"sparclite", 0,                                                   \
-     N_("Optimize for SparcLite processors") },                        \
+     N_("Optimize for SPARCLite processors") },                        \
     {"f930", 0,                                                                \
      N_("Optimize for F930 processors") },                             \
     {"f934", 0,                                                                \
      N_("Optimize for F934 processors") },                             \
     {"v8", 0,                                                          \
-     N_("Use V8 Sparc ISA") },                                                 \
+     N_("Use V8 SPARC ISA") },                                                 \
     {"supersparc", 0,                                                  \
-     N_("Optimize for SuperSparc processors") },                       \
+     N_("Optimize for SuperSPARC processors") },                       \
     /* End of deprecated options.  */                                  \
     {"ptr64", MASK_PTR64,                                              \
      N_("Pointers are 64-bit") },                                      \
@@ -630,7 +598,7 @@ extern int target_flags;
 /* MASK_APP_REGS must always be the default because that's what
    FIXED_REGISTERS is set to and -ffixed- is processed before
    CONDITIONAL_REGISTER_USAGE is called (where we process -mno-app-regs).  */
-#define TARGET_DEFAULT (MASK_APP_REGS + MASK_EPILOGUE + MASK_FPU)
+#define TARGET_DEFAULT (MASK_APP_REGS + MASK_FPU)
 
 /* This is meant to be redefined in target specific files.  */
 #define SUBTARGET_SWITCHES
@@ -650,7 +618,8 @@ enum processor_type {
   PROCESSOR_SPARCLET,
   PROCESSOR_TSC701,
   PROCESSOR_V9,
-  PROCESSOR_ULTRASPARC
+  PROCESSOR_ULTRASPARC,
+  PROCESSOR_ULTRASPARC3
 };
 
 /* This is set from -m{cpu,tune}=xxx.  */
@@ -660,31 +629,14 @@ extern enum processor_type sparc_cpu;
    Every file includes us, but not every file includes insn-attr.h.  */
 #define sparc_cpu_attr ((enum attr_cpu) sparc_cpu)
 
-/* This macro is similar to `TARGET_SWITCHES' but defines names of
-   command options that have values.  Its definition is an
-   initializer with a subgrouping for each command option.
-
-   Each subgrouping contains a string constant, that defines the
-   fixed part of the option name, and the address of a variable. 
-   The variable, type `char *', is set to the variable part of the
-   given option if the fixed part matches.  The actual option name
-   is made by appending `-m' to the specified name.
-
-   Here is an example which defines `-mshort-data-NUMBER'.  If the
-   given option is `-mshort-data-512', the variable `m88k_short_data'
-   will be set to the string `"512"'.
-
-       extern char *m88k_short_data;
-       #define TARGET_OPTIONS { { "short-data-", &m88k_short_data } }  */
-
 #define TARGET_OPTIONS \
 {                                                              \
   { "cpu=",  &sparc_select[1].string,                          \
-    N_("Use features of and schedule code for given CPU") },   \
+    N_("Use features of and schedule code for given CPU"), 0}, \
   { "tune=", &sparc_select[2].string,                          \
-    N_("Schedule code for given CPU") },                       \
+    N_("Schedule code for given CPU"), 0},                     \
   { "cmodel=", &sparc_cmodel_string,                           \
-    N_("Use given Sparc code model") },                                \
+    N_("Use given SPARC code model"), 0},                      \
   SUBTARGET_OPTIONS                                            \
 }
 
@@ -704,10 +656,6 @@ extern struct sparc_cpu_select sparc_select[];
 \f
 /* target machine storage layout */
 
-/* Define for cross-compilation to a sparc target with no TFmode from a host
-   with a different float format (e.g. VAX).  */
-#define REAL_ARITHMETIC
-
 /* Define this if most significant bit is lowest numbered
    in instructions that operate on numbered bit-fields.  */
 #define BITS_BIG_ENDIAN 1
@@ -727,19 +675,15 @@ extern struct sparc_cpu_select sparc_select[];
 #define LIBGCC2_WORDS_BIG_ENDIAN 1
 #endif
 
-/* number of bits in an addressable storage unit */
-#define BITS_PER_UNIT 8
-
-/* Width in bits of a "word", which is the contents of a machine register.
-   Note that this is not necessarily the width of data type `int';
-   if using 16-bit ints on a 68000, this would still be 32.
-   But on a machine with 16-bit registers, this would be 16.  */
-#define BITS_PER_WORD          (TARGET_ARCH64 ? 64 : 32)
 #define MAX_BITS_PER_WORD      64
 
 /* Width of a word, in units (bytes).  */
 #define UNITS_PER_WORD         (TARGET_ARCH64 ? 8 : 4)
+#ifdef IN_LIBGCC2
+#define MIN_UNITS_PER_WORD     UNITS_PER_WORD
+#else
 #define MIN_UNITS_PER_WORD     4
+#endif
 
 /* Now define the sizes of the C data types.  */
 
@@ -757,8 +701,8 @@ extern struct sparc_cpu_select sparc_select[];
 #if 0
 /* ??? This does not work in SunOS 4.x, so it is not enabled here.
    Instead, it is enabled in sol2.h, because it does work under Solaris.  */
-/* Define for support of TFmode long double and REAL_ARITHMETIC.
-   Sparc ABI says that long double is 4 words.  */
+/* Define for support of TFmode long double.
+   SPARC ABI says that long double is 4 words.  */
 #define LONG_DOUBLE_TYPE_SIZE 128
 #endif
 
@@ -829,7 +773,7 @@ if (TARGET_ARCH64                           \
 /* Every structure's size must be a multiple of this.  */
 #define STRUCTURE_SIZE_BOUNDARY 8
 
-/* A bitfield declared as `int' forces `int' alignment for the struct.  */
+/* A bit-field declared as `int' forces `int' alignment for the struct.  */
 #define PCC_BITFIELD_TYPE_MATTERS 1
 
 /* No data type wants to be aligned rounder than this.  */
@@ -884,19 +828,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.  */
 
@@ -911,9 +842,10 @@ if (TARGET_ARCH64                          \
    accessible.  We still account for them to simplify register computations
    (eg: in CLASS_MAX_NREGS).  There are also 4 fp condition code registers, so
    32+32+32+4 == 100.
-   Register 100 is used as the integer condition code register.  */
+   Register 100 is used as the integer condition code register.
+   Register 101 is used as the soft frame pointer register.  */
 
-#define FIRST_PSEUDO_REGISTER 101
+#define FIRST_PSEUDO_REGISTER 102
 
 #define SPARC_FIRST_FP_REG     32
 /* Additional V9 fp regs.  */
@@ -979,7 +911,7 @@ if (TARGET_ARCH64                           \
   0, 0, 0, 0, 0, 0, 0, 0,      \
   0, 0, 0, 0, 0, 0, 0, 0,      \
                                \
-  0, 0, 0, 0, 0}
+  0, 0, 0, 0, 0, 1}
 
 /* 1 for registers not available across function calls.
    These must include the FIXED_REGISTERS and also any
@@ -1004,7 +936,7 @@ if (TARGET_ARCH64                          \
   1, 1, 1, 1, 1, 1, 1, 1,      \
   1, 1, 1, 1, 1, 1, 1, 1,      \
                                \
-  1, 1, 1, 1, 1}
+  1, 1, 1, 1, 1, 1}
 
 /* If !TARGET_FPU, then make the fp registers and fp cc regs fixed so that
    they won't be allocated.  */
@@ -1012,13 +944,13 @@ if (TARGET_ARCH64                                \
 #define CONDITIONAL_REGISTER_USAGE                             \
 do                                                             \
   {                                                            \
-    if (flag_pic)                                              \
+    if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)             \
       {                                                                \
        fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1;                \
        call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;            \
       }                                                                \
     /* If the user has passed -f{fixed,call-{used,saved}}-g5 */        \
-    /* then honour it.  */                                     \
+    /* then honor it.  */                                      \
     if (TARGET_ARCH32 && fixed_regs[5])                                \
       fixed_regs[5] = 1;                                       \
     else if (TARGET_ARCH64 && fixed_regs[5] == 2)              \
@@ -1043,7 +975,7 @@ do                                                         \
          fixed_regs[regno] = 1;                                \
       }                                                                \
     /* If the user has passed -f{fixed,call-{used,saved}}-g2 */        \
-    /* then honour it.  Likewise with g3 and g4.  */           \
+    /* then honor it.  Likewise with g3 and g4.  */            \
     if (fixed_regs[2] == 2)                                    \
       fixed_regs[2] = ! TARGET_APP_REGS;                       \
     if (fixed_regs[3] == 2)                                    \
@@ -1056,12 +988,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[FRAME_POINTER_REGNUM] = "%i7";                \
+       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)
@@ -1079,9 +1015,9 @@ while (0)
 
 #define HARD_REGNO_NREGS(REGNO, MODE) \
   (TARGET_ARCH64                                                       \
-   ?  ((REGNO) < 32                                                    \
-       ? (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD  \
-       : (GET_MODE_SIZE (MODE) + 3) / 4)                               \
+   ? ((REGNO) < 32 || (REGNO) == FRAME_POINTER_REGNUM                  \
+      ? (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD   \
+      : (GET_MODE_SIZE (MODE) + 3) / 4)                                        \
    : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
 
 /* Due to the ARCH64 descrepancy above we must override this next
@@ -1124,27 +1060,32 @@ extern int sparc_mode_class[];
 /* Register to use for pushing function arguments.  */
 #define STACK_POINTER_REGNUM 14
 
+/* The stack bias (amount by which the hardware register is offset by).  */
+#define SPARC_STACK_BIAS ((TARGET_ARCH64 && TARGET_STACK_BIAS) ? 2047 : 0)
+
 /* Actual top-of-stack address is 92/176 greater than the contents of the
    stack pointer register for !v9/v9.  That is:
    - !v9: 64 bytes for the in and local registers, 4 bytes for structure return
      address, and 6*4 bytes for the 6 register parameters.
    - v9: 128 bytes for the in and local registers + 6*8 bytes for the integer
      parameter regs.  */
-#define STACK_POINTER_OFFSET FIRST_PARM_OFFSET(0)
-
-/* The stack bias (amount by which the hardware register is offset by).  */
-#define SPARC_STACK_BIAS ((TARGET_ARCH64 && TARGET_STACK_BIAS) ? 2047 : 0)
-
-/* Is stack biased? */
-#define STACK_BIAS SPARC_STACK_BIAS
+#define STACK_POINTER_OFFSET (FIRST_PARM_OFFSET(0) + SPARC_STACK_BIAS)
 
 /* Base register for access to local variables of the function.  */
-#define FRAME_POINTER_REGNUM 30
-
-#if 0
-/* Register that is used for the return address for the flat model.  */
-#define RETURN_ADDR_REGNUM 15
-#endif
+#define HARD_FRAME_POINTER_REGNUM 30
+
+/* The soft frame pointer does not have the stack bias applied.  */
+#define FRAME_POINTER_REGNUM 101
+
+/* Given the stack bias, the stack pointer isn't actually aligned.  */
+#define INIT_EXPANDERS                                                  \
+  do {                                                                  \
+    if (cfun && cfun->emit->regno_pointer_align && SPARC_STACK_BIAS)    \
+      {                                                                         \
+       REGNO_POINTER_ALIGN (STACK_POINTER_REGNUM) = BITS_PER_UNIT;      \
+       REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = BITS_PER_UNIT; \
+      }                                                                         \
+  } while (0)
 
 /* Value should be nonzero if functions must have frame pointers.
    Zero means the frame pointer need not be set up (and parms
@@ -1155,21 +1096,12 @@ extern int sparc_mode_class[];
    Being a non-leaf function does not mean a frame pointer is needed in the
    flat window model.  However, the debugger won't be able to backtrace through
    us with out it.  */
-#define FRAME_POINTER_REQUIRED \
-  (TARGET_FLAT ? (current_function_calls_alloca || current_function_varargs \
-                 || !leaf_function_p ()) \
+#define FRAME_POINTER_REQUIRED                         \
+  (TARGET_FLAT                                         \
+   ? (current_function_calls_alloca                    \
+      || !leaf_function_p ())                          \
    : ! (leaf_function_p () && only_leaf_regs_used ()))
 
-/* C statement to store the difference between the frame pointer
-   and the stack pointer values immediately after the function prologue.
-
-   Note, we always pretend that this is a leaf function because if
-   it's not, there's no point in trying to eliminate the
-   frame pointer.  If it is a leaf function, we guessed right!  */
-#define INITIAL_FRAME_POINTER_OFFSET(VAR) \
-  ((VAR) = (TARGET_FLAT ? sparc_flat_compute_frame_size (get_frame_size ()) \
-           : compute_frame_size (get_frame_size (), 1)))
-
 /* Base register for access to arguments of the function.  */
 #define ARG_POINTER_REGNUM FRAME_POINTER_REGNUM
 
@@ -1180,7 +1112,7 @@ extern int sparc_mode_class[];
 /* Register which holds offset table for position-independent
    data references.  */
 
-#define PIC_OFFSET_TABLE_REGNUM 23
+#define PIC_OFFSET_TABLE_REGNUM (flag_pic ? 23 : INVALID_REGNUM)
 
 /* Pick a default value we can notice from override_options:
    !v9: Default is on.
@@ -1188,7 +1120,7 @@ extern int sparc_mode_class[];
 
 #define DEFAULT_PCC_STRUCT_RETURN -1
 
-/* Sparc ABI says that quad-precision floats and all structures are returned
+/* SPARC ABI says that quad-precision floats and all structures are returned
    in memory.
    For v9: unions <= 32 bytes in size are returned in int regs,
    structures up to 32 bytes are returned in int and fp regs.  */
@@ -1292,10 +1224,16 @@ enum reg_class { NO_REGS, FPCC_REGS, I64_REGS, GENERAL_REGS, FP_REGS,
    This is an initializer for a vector of HARD_REG_SET
    of length N_REG_CLASSES.  */
 
-#define REG_CLASS_CONTENTS \
-  {{0, 0, 0, 0}, {0, 0, 0, 0xf}, {0xffff, 0, 0, 0}, \
-   {-1, 0, 0, 0}, {0, -1, 0, 0}, {0, -1, -1, 0}, \
-   {-1, -1, 0, 0}, {-1, -1, -1, 0}, {-1, -1, -1, 0x1f}}
+#define REG_CLASS_CONTENTS                             \
+  {{0, 0, 0, 0},       /* NO_REGS */                   \
+   {0, 0, 0, 0xf},     /* FPCC_REGS */                 \
+   {0xffff, 0, 0, 0},  /* I64_REGS */                  \
+   {-1, 0, 0, 0x20},   /* GENERAL_REGS */              \
+   {0, -1, 0, 0},      /* FP_REGS */                   \
+   {0, -1, -1, 0},     /* EXTRA_FP_REGS */             \
+   {-1, -1, 0, 0x20},  /* GENERAL_OR_FP_REGS */        \
+   {-1, -1, -1, 0x20}, /* GENERAL_OR_EXTRA_FP_REGS */  \
+   {-1, -1, -1, 0x3f}} /* ALL_REGS */
 
 /* The same information, inverted:
    Return the class number of the smallest class containing
@@ -1306,18 +1244,33 @@ extern enum reg_class sparc_regno_reg_class[FIRST_PSEUDO_REGISTER];
 
 #define REGNO_REG_CLASS(REGNO) sparc_regno_reg_class[(REGNO)]
 
-/* 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
+/* This is the order in which to allocate registers normally.
+
+   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 */ \
@@ -1325,37 +1278,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}
+  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}
-  
+{ 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.  */
@@ -1396,7 +1367,8 @@ extern const char leaf_reg_remap[];
    `J' is used for the range which is just zero (since that is R0).
    `K' is used for constants which can be loaded with a single sethi insn.
    `L' is used for the range of constants supported by the movcc insns.
-   `M' is used for the range of constants supported by the movrcc insns.  */
+   `M' is used for the range of constants supported by the movrcc insns.
+   `N' is like K, but for constants wider than 32 bits.  */
 
 #define SPARC_SIMM10_P(X) ((unsigned HOST_WIDE_INT) (X) + 0x200 < 0x400)
 #define SPARC_SIMM11_P(X) ((unsigned HOST_WIDE_INT) (X) + 0x400 < 0x800)
@@ -1405,17 +1377,21 @@ extern const char leaf_reg_remap[];
    SMALL_INT is used throughout the port so we continue to use it.  */
 #define SMALL_INT(X) (SPARC_SIMM13_P (INTVAL (X)))
 /* 13 bit immediate, considering only the low 32 bits */
-#define SMALL_INT32(X) (SPARC_SIMM13_P ((int)INTVAL (X) & 0xffffffff))
+#define SMALL_INT32(X) (SPARC_SIMM13_P (trunc_int_for_mode \
+                                       (INTVAL (X), SImode)))
 #define SPARC_SETHI_P(X) \
-(((unsigned HOST_WIDE_INT) (X) & \
-  (TARGET_ARCH64 ? ~(unsigned HOST_WIDE_INT) 0xfffffc00 : 0x3ff)) == 0)
+  (((unsigned HOST_WIDE_INT) (X) \
+    & ((unsigned HOST_WIDE_INT) 0x3ff - GET_MODE_MASK (SImode) - 1)) == 0)
+#define SPARC_SETHI32_P(X) \
+  (SPARC_SETHI_P ((unsigned HOST_WIDE_INT) (X) & GET_MODE_MASK (SImode)))
 
 #define CONST_OK_FOR_LETTER_P(VALUE, C)  \
   ((C) == 'I' ? SPARC_SIMM13_P (VALUE)                 \
    : (C) == 'J' ? (VALUE) == 0                         \
-   : (C) == 'K' ? SPARC_SETHI_P (VALUE)                        \
+   : (C) == 'K' ? SPARC_SETHI32_P (VALUE)              \
    : (C) == 'L' ? SPARC_SIMM11_P (VALUE)               \
    : (C) == 'M' ? SPARC_SIMM10_P (VALUE)               \
+   : (C) == 'N' ? SPARC_SETHI_P (VALUE)                        \
    : 0)
 
 /* Similar, but for floating constants, and defining letters G and H.
@@ -1441,6 +1417,8 @@ extern const char leaf_reg_remap[];
 #define PREFERRED_RELOAD_CLASS(X,CLASS)                        \
   (CONSTANT_P (X)                                      \
    ? ((FP_REG_CLASS_P (CLASS)                          \
+       || (CLASS) == GENERAL_OR_FP_REGS                        \
+       || (CLASS) == GENERAL_OR_EXTRA_FP_REGS          \
        || (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \
           && ! TARGET_FPU)                             \
        || (GET_MODE (X) == TFmode                      \
@@ -1457,7 +1435,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)                                     \
@@ -1466,30 +1447,38 @@ 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)
-
-/* On SPARC it is not possible to directly move data between 
+   ? 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.  */
 #define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \
   (FP_REG_CLASS_P (CLASS1) != FP_REG_CLASS_P (CLASS2))
@@ -1552,7 +1541,7 @@ extern const char leaf_reg_remap[];
    of the first local allocated.  */
 /* This allows space for one TFmode floating point value.  */
 #define STARTING_FRAME_OFFSET \
-  (TARGET_ARCH64 ? (SPARC_STACK_BIAS - 16) \
+  (TARGET_ARCH64 ? -16 \
    : (-SPARC_STACK_ALIGN (LONG_DOUBLE_TYPE_SIZE / BITS_PER_UNIT)))
 
 /* If we generate an insn to push BYTES bytes,
@@ -1565,14 +1554,12 @@ extern const char leaf_reg_remap[];
    even if this function isn't going to use it.
    v9: This is 128 for the ins and locals.  */
 #define FIRST_PARM_OFFSET(FNDECL) \
-  (TARGET_ARCH64 ? (SPARC_STACK_BIAS + 16 * UNITS_PER_WORD) \
-   : (STRUCT_VALUE_OFFSET + UNITS_PER_WORD))
+  (TARGET_ARCH64 ? 16 * UNITS_PER_WORD : STRUCT_VALUE_OFFSET + UNITS_PER_WORD)
 
 /* Offset from the argument pointer register value to the CFA.
    This is different from FIRST_PARM_OFFSET because the register window
    comes between the CFA and the arguments.  */
-
-#define ARG_POINTER_CFA_OFFSET(FNDECL)  SPARC_STACK_BIAS
+#define ARG_POINTER_CFA_OFFSET(FNDECL)  0
 
 /* When a parameter is passed in a register, stack space is still
    allocated for it.
@@ -1585,6 +1572,38 @@ extern const char leaf_reg_remap[];
    all 6 slots even for v9.  */
 #define REG_PARM_STACK_SPACE(DECL) (6 * UNITS_PER_WORD)
 
+/* Definitions for register elimination.  */
+/* ??? In TARGET_FLAT mode we needn't have a hard frame pointer.  */
+
+#define ELIMINABLE_REGS \
+  {{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
+   { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM} }
+
+/* The way this is structured, we can't eliminate SFP in favor of SP
+   if the frame pointer is required: we want to use the SFP->HFP elimination
+   in that case.  But the test in update_eliminables doesn't know we are
+   assuming below that we only do the former elimination.  */
+#define CAN_ELIMINATE(FROM, TO) \
+  ((TO) == HARD_FRAME_POINTER_REGNUM || !FRAME_POINTER_REQUIRED)
+
+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
+  do {                                                         \
+    (OFFSET) = 0;                                              \
+    if ((TO) == STACK_POINTER_REGNUM)                          \
+      {                                                                \
+       /* Note, we always pretend that this is a leaf function \
+          because if it's not, there's no point in trying to   \
+          eliminate the frame pointer.  If it is a leaf        \
+          function, we guessed right!  */                      \
+       if (TARGET_FLAT)                                        \
+         (OFFSET) =                                            \
+           sparc_flat_compute_frame_size (get_frame_size ());  \
+       else                                                    \
+         (OFFSET) = compute_frame_size (get_frame_size (), 1); \
+      }                                                                \
+    (OFFSET) += SPARC_STACK_BIAS;                              \
+  } while (0)
+
 /* Keep the stack pointer constant throughout the function.
    This is both an optimization and a necessity: longjmp
    doesn't behave itself when the stack pointer moves within
@@ -1706,8 +1725,8 @@ extern const char leaf_reg_remap[];
 
 struct sparc_args {
   int words;       /* number of words passed so far */
-  int prototype_p; /* non-zero if a prototype is present */
-  int libcall_p;   /* non-zero if a library call */
+  int prototype_p; /* nonzero if a prototype is present */
+  int libcall_p;   /* nonzero if a library call */
 };
 #define CUMULATIVE_ARGS struct sparc_args
 
@@ -1715,8 +1734,8 @@ struct sparc_args {
    for a call to a function whose data type is FNTYPE.
    For a library call, FNTYPE is 0.  */
 
-#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT) \
-init_cumulative_args (& (CUM), (FNTYPE), (LIBNAME), (INDIRECT));
+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL) \
+init_cumulative_args (& (CUM), (FNTYPE), (LIBNAME), (FNDECL));
 
 /* Update the data in CUM to advance over an argument
    of mode MODE and data type TYPE.
@@ -1793,13 +1812,14 @@ 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
    it might need to know about the return value of a function.
 
-   For Sparc assemblers, we need to output a .proc pseudo-op which conveys
+   For SPARC assemblers, we need to output a .proc pseudo-op which conveys
    information to the assembler relating to peephole optimization (done in
    the assembler).  */
 
@@ -1807,7 +1827,7 @@ extern struct rtx_def *sparc_compare_op0, *sparc_compare_op1;
   fprintf ((FILE), "\t.proc\t0%lo\n", sparc_type_code (TREE_TYPE (RESULT)))
 
 /* Output the special assembly code needed to tell the assembler some
-   register is used as global register variable.  
+   register is used as global register variable.
 
    SPARC 64bit psABI declares registers %g2 and %g3 as application
    registers and %g6 and %g7 as OS registers.  Any object using them
@@ -1845,14 +1865,13 @@ do {                                                                    \
 #endif
 
 \f
-/* Output assembler code to FILE to increment profiler label # LABELNO
-   for profiling a function entry.  */
+/* Emit rtl for profiling.  */
+#define PROFILE_HOOK(LABEL)   sparc_profile_hook (LABEL)
 
-#define FUNCTION_PROFILER(FILE, LABELNO) \
-  sparc_function_profiler(FILE, LABELNO)
+/* All the work done in PROFILE_HOOK, but still required.  */
+#define FUNCTION_PROFILER(FILE, LABELNO) do { } while (0)
 
 /* Set the name of the mcount function for the system.  */
-
 #define MCOUNT_FUNCTION "*mcount"
 \f
 /* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
@@ -1895,8 +1914,8 @@ do {                                                                      \
 #define EXPAND_BUILTIN_SAVEREGS() sparc_builtin_saveregs ()
 
 /* Implement `va_start' for varargs and stdarg.  */
-#define EXPAND_BUILTIN_VA_START(stdarg, valist, nextarg) \
-  sparc_va_start (stdarg, valist, nextarg)
+#define EXPAND_BUILTIN_VA_START(valist, nextarg) \
+  sparc_va_start (valist, nextarg)
 
 /* Implement `va_arg'.  */
 #define EXPAND_BUILTIN_VA_ARG(valist, type) \
@@ -1915,10 +1934,6 @@ 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)
-
 /* Generate RTL to flush the register windows so as to make arbitrary frames
    available.  */
 #define SETUP_FRAME_ADDRESSES()                \
@@ -1928,7 +1943,8 @@ do {                                                                      \
    return an rtx for the address of the word in the frame
    that holds the dynamic chain--the previous frame's address.
    ??? -mflat support? */
-#define DYNAMIC_CHAIN_ADDRESS(frame) plus_constant (frame, 14 * UNITS_PER_WORD)
+#define DYNAMIC_CHAIN_ADDRESS(frame)   \
+  plus_constant (frame, 14 * UNITS_PER_WORD + SPARC_STACK_BIAS)
 
 /* The return address isn't on the stack, it is in a register, so we can't
    access it from the current frame pointer.  We can access it from the
@@ -1950,7 +1966,8 @@ do {                                                                      \
    ? gen_rtx_REG (Pmode, 31)                   \
    : gen_rtx_MEM (Pmode,                       \
                  memory_address (Pmode, plus_constant (frame, \
-                                                       15 * UNITS_PER_WORD))))
+                                                       15 * UNITS_PER_WORD \
+                                                       + SPARC_STACK_BIAS))))
 
 /* Before the prologue, the return address is %o7 + 8.  OK, sometimes it's
    +12, but always using +8 is close enough for frame unwind purposes.
@@ -1977,14 +1994,27 @@ do {                                                                    \
    If assembler and linker properly support .uaword %r_disp32(foo),
    then use PC relative 32-bit relocations instead of absolute relocs
    for shared libraries.  On sparc64, use pc relative 32-bit relocs even
-   for binaries, to save memory.  */
+   for binaries, to save memory.
+
+   binutils 2.12 would emit a R_SPARC_DISP32 dynamic relocation if the
+   symbol %r_disp32() is against was not local, but .hidden.  In that
+   case, we have to use DW_EH_PE_absptr for pic personality.  */
 #ifdef HAVE_AS_SPARC_UA_PCREL
+#ifdef HAVE_AS_SPARC_UA_PCREL_HIDDEN
 #define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL)                      \
   (flag_pic                                                            \
    ? (GLOBAL ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | DW_EH_PE_sdata4\
    : ((TARGET_ARCH64 && ! GLOBAL)                                      \
       ? (DW_EH_PE_pcrel | DW_EH_PE_sdata4)                             \
       : DW_EH_PE_absptr))
+#else
+#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL)                      \
+  (flag_pic                                                            \
+   ? (GLOBAL ? DW_EH_PE_absptr : (DW_EH_PE_pcrel | DW_EH_PE_sdata4))   \
+   : ((TARGET_ARCH64 && ! GLOBAL)                                      \
+      ? (DW_EH_PE_pcrel | DW_EH_PE_sdata4)                             \
+      : DW_EH_PE_absptr))
+#endif
 
 /* Emit a PC-relative relocation.  */
 #define ASM_OUTPUT_DWARF_PCREL(FILE, SIZE, LABEL)      \
@@ -1998,12 +2028,6 @@ do {                                                                     \
 \f
 /* Addressing modes, and classification of registers for them.  */
 
-/* #define HAVE_POST_INCREMENT 0 */
-/* #define HAVE_POST_DECREMENT 0 */
-
-/* #define HAVE_PRE_DECREMENT 0 */
-/* #define HAVE_PRE_INCREMENT 0 */
-
 /* Macros to check register numbers against specific register classes.  */
 
 /* These assume that REGNO is a hard or pseudo reg number.
@@ -2013,9 +2037,12 @@ do {                                                                     \
    has been allocated, which happens in local-alloc.c.  */
 
 #define REGNO_OK_FOR_INDEX_P(REGNO) \
-((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < (unsigned)32)
-#define REGNO_OK_FOR_BASE_P(REGNO) \
-((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < (unsigned)32)
+((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < (unsigned)32 \
+ || (REGNO) == FRAME_POINTER_REGNUM                            \
+ || reg_renumber[REGNO] == FRAME_POINTER_REGNUM)
+
+#define REGNO_OK_FOR_BASE_P(REGNO)  REGNO_OK_FOR_INDEX_P (REGNO)
+
 #define REGNO_OK_FOR_FP_P(REGNO) \
   (((unsigned) (REGNO) - 32 < (TARGET_V9 ? (unsigned)64 : (unsigned)32)) \
    || ((unsigned) reg_renumber[REGNO] - 32 < (TARGET_V9 ? (unsigned)64 : (unsigned)32)))
@@ -2096,34 +2123,32 @@ do {                                                                    \
        be at least 8 bytes.
 
    `U' handles all pseudo registers or a hard even numbered
-       integer register, needed for ldd/std instructions.  */
+       integer register, needed for ldd/std instructions.
 
-#define EXTRA_CONSTRAINT_BASE(OP, C)   \
-   ((C) == 'Q' ? fp_sethi_p(OP)        \
-    : (C) == 'R' ? fp_mov_p(OP)        \
-    : (C) == 'S' ? fp_high_losum_p(OP) \
-    : 0)
+   'W' handles the memory operand when moving operands in/out
+       of 'e' constraint floating point registers.  */
 
 #ifndef REG_OK_STRICT
 
 /* Nonzero if X is a hard reg that can be used as an index
    or if it is a pseudo reg.  */
 #define REG_OK_FOR_INDEX_P(X) \
-  (((unsigned) REGNO (X)) - 32 >= (FIRST_PSEUDO_REGISTER - 32))
+  (REGNO (X) < 32                              \
+   || REGNO (X) == FRAME_POINTER_REGNUM                \
+   || REGNO (X) >= FIRST_PSEUDO_REGISTER)
+
 /* Nonzero if X is a hard reg that can be used as a base reg
    or if it is a pseudo reg.  */
-#define REG_OK_FOR_BASE_P(X) \
-  (((unsigned) REGNO (X)) - 32 >= (FIRST_PSEUDO_REGISTER - 32))
+#define REG_OK_FOR_BASE_P(X)  REG_OK_FOR_INDEX_P (X)
+
+/* 'T', 'U' are for aligned memory loads which aren't needed for arch64.
+   'W' is like 'T' but is assumed true on arch64.
 
-/* 'T', 'U' are for aligned memory loads which aren't needed for arch64.  */
+   Remember to accept pseudo-registers for memory constraints if reload is
+   in progress.  */
 
-#define EXTRA_CONSTRAINT(OP, C)                                \
-   (EXTRA_CONSTRAINT_BASE(OP, C)                        \
-    || ((! TARGET_ARCH64 && (C) == 'T')                        \
-        ? (mem_min_alignment (OP, 8))                  \
-        : ((! TARGET_ARCH64 && (C) == 'U')             \
-            ? (register_ok_for_ldd (OP))               \
-            : 0)))
+#define EXTRA_CONSTRAINT(OP, C) \
+       sparc_extra_constraint_check(OP, C, 0)
 
 #else
 
@@ -2132,16 +2157,8 @@ do {                                                                     \
 /* Nonzero if X is a hard reg that can be used as a base reg.  */
 #define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
 
-#define EXTRA_CONSTRAINT(OP, C)                                \
-   (EXTRA_CONSTRAINT_BASE(OP, C)                        \
-    || ((! TARGET_ARCH64 && (C) == 'T')                        \
-        ? mem_min_alignment (OP, 8) && strict_memory_address_p (Pmode, XEXP (OP, 0)) \
-        : ((! TARGET_ARCH64 && (C) == 'U')             \
-           ? (GET_CODE (OP) == REG                     \
-              && (REGNO (OP) < FIRST_PSEUDO_REGISTER   \
-                 || reg_renumber[REGNO (OP)] >= 0)     \
-              && register_ok_for_ldd (OP))             \
-           : 0)))
+#define EXTRA_CONSTRAINT(OP, C) \
+       sparc_extra_constraint_check(OP, C, 1)
 
 #endif
 \f
@@ -2163,6 +2180,8 @@ do {                                                                      \
 
    If you change this, execute "rm explow.o recog.o reload.o".  */
 
+#define SYMBOLIC_CONST(X) symbolic_operand (X, VOIDmode)
+
 #define RTX_OK_FOR_BASE_P(X)                                           \
   ((GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X))                      \
   || (GET_CODE (X) == SUBREG                                           \
@@ -2177,7 +2196,7 @@ do {                                                                      \
 
 #define RTX_OK_FOR_OFFSET_P(X)                                         \
   (GET_CODE (X) == CONST_INT && INTVAL (X) >= -0x1000 && INTVAL (X) < 0x1000 - 8)
-  
+
 #define RTX_OK_FOR_OLO10_P(X)                                          \
   (GET_CODE (X) == CONST_INT && INTVAL (X) >= -0x1000 && INTVAL (X) < 0xc00 - 8)
 
@@ -2196,6 +2215,8 @@ do {                                                                      \
                   && GET_CODE (op1) != REG             \
                   && GET_CODE (op1) != LO_SUM          \
                   && GET_CODE (op1) != MEM             \
+                  && (! SYMBOLIC_CONST (op1)           \
+                      || MODE == Pmode)                \
                   && (GET_CODE (op1) != CONST_INT      \
                       || SMALL_INT (op1)))             \
            goto ADDR;                                  \
@@ -2283,6 +2304,34 @@ do {                                                                     \
   else if (GET_CODE (X) == CONST_INT && SMALL_INT (X)) \
     goto ADDR;                                         \
 }
+
+/* Go to LABEL if ADDR (a legitimate address expression)
+   has an effect that depends on the machine mode it is used for.
+
+   In PIC mode,
+
+      (mem:HI [%l7+a])
+
+   is not equivalent to
+   
+      (mem:QI [%l7+a]) (mem:QI [%l7+a+1])
+
+   because [%l7+a+1] is interpreted as the address of (a+1).  */
+
+#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL)      \
+{                                                      \
+  if (flag_pic == 1)                                   \
+    {                                                  \
+      if (GET_CODE (ADDR) == PLUS)                     \
+       {                                               \
+         rtx op0 = XEXP (ADDR, 0);                     \
+         rtx op1 = XEXP (ADDR, 1);                     \
+         if (op0 == pic_offset_table_rtx               \
+             && SYMBOLIC_CONST (op1))                  \
+           goto LABEL;                                 \
+       }                                               \
+    }                                                  \
+}
 \f
 /* Try machine-dependent ways of modifying an illegitimate address
    to be legitimate.  If we find one, return the new, valid address.
@@ -2331,8 +2380,8 @@ do {                                                                      \
    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. 
+   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.
 
    Do nothing when generating PIC code and the address is a
@@ -2343,12 +2392,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);           \
@@ -2359,22 +2409,6 @@ do {                                                                    \
     }                                                                  \
   /* ??? 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.  */
-
-#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) \
-  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.  */
@@ -2396,12 +2430,6 @@ do {                                                                    \
    Do not define this if the table should contain absolute addresses.  */
 /* #define CASE_VECTOR_PC_RELATIVE 1 */
 
-/* Specify the tree operation to be used to convert reals to integers.  */
-#define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR
-
-/* This is the kind of divide that is easiest to do in the general case.  */
-#define EASY_DIV_EXPR TRUNC_DIV_EXPR
-
 /* Define this as 1 if `char' should by default be signed; else as 0.  */
 #define DEFAULT_SIGNED_CHAR 1
 
@@ -2459,26 +2487,6 @@ do {                                                                    \
 /* Generate calls to memcpy, memcmp and memset.  */
 #define TARGET_MEM_FUNCTIONS
 
-/* Add any extra modes needed to represent the condition code.
-
-   On the Sparc, we have a "no-overflow" mode which is used when an add or
-   subtract insn is used to set the condition code.  Different branches are
-   used in this case for some operations.
-
-   We also have two modes to indicate that the relevant condition code is
-   in the floating-point condition code register.  One for comparisons which
-   will generate an exception if the result is unordered (CCFPEmode) and
-   one for comparisons which will never trap (CCFPmode).
-
-   CCXmode and CCX_NOOVmode are only used by v9.  */
-
-#define EXTRA_CC_MODES                 \
-    CC(CCXmode,             "CCX")             \
-    CC(CC_NOOVmode,  "CC_NOOV")                \
-    CC(CCX_NOOVmode, "CCX_NOOV")       \
-    CC(CCFPmode,     "CCFP")           \
-    CC(CCFPEmode,    "CCFPE")
-
 /* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
    return the mode to be used for the comparison.  For floating-point,
    CCFP[E]mode is used.  CC_NOOVmode should be used when the first operand
@@ -2486,8 +2494,8 @@ do {                                                                    \
    processing is needed.  */
 #define SELECT_CC_MODE(OP,X,Y)  select_cc_mode ((OP), (X), (Y))
 
-/* Return non-zero if MODE implies a floating point inequality can be
-   reversed.  For Sparc this is always true because we have a full
+/* Return nonzero if MODE implies a floating point inequality can be
+   reversed.  For SPARC this is always true because we have a full
    compliment of ordered and unordered comparisons, but until generic
    code knows how to reverse it correctly we keep the old definition.  */
 #define REVERSIBLE_CC_MODE(MODE) ((MODE) != CCFPEmode && (MODE) != CCFPmode)
@@ -2536,6 +2544,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
@@ -2572,6 +2585,17 @@ do {                                                                    \
          sqrt_optab->handlers[(int) TFmode].libfunc                    \
            = init_one_libfunc ("_Q_sqrt");                             \
       }                                                                        \
+    if (TARGET_ARCH64)                                                 \
+      {                                                                        \
+        /* In the SPARC 64bit ABI, these libfuncs do not exist in the  \
+           library.  Make sure the compiler does not emit calls to them        \
+          by accident.  */                                             \
+       sdiv_optab->handlers[(int) SImode].libfunc = NULL;              \
+       udiv_optab->handlers[(int) SImode].libfunc = NULL;              \
+       smod_optab->handlers[(int) SImode].libfunc = NULL;              \
+       umod_optab->handlers[(int) SImode].libfunc = NULL;              \
+        smul_optab->handlers[(int) SImode].libfunc = NULL;             \
+      }                                                                        \
     INIT_SUBTARGET_OPTABS;                                             \
   } while (0)
 
@@ -2583,33 +2607,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)
@@ -2617,42 +2614,36 @@ 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)
-
-/* 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.  */
-
-#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;
-
-/* Conditional branches with empty delay slots have a length of two.  */
-#define ADJUST_INSN_LENGTH(INSN, LENGTH)                               \
-do {                                                                   \
-  if (GET_CODE (INSN) == CALL_INSN                                     \
-      || (GET_CODE (INSN) == JUMP_INSN && ! simplejump_p (insn)))      \
-    LENGTH += 1;                                                       \
-} while (0)
+   ? ((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))
+
+#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.  */
 
@@ -2698,7 +2689,7 @@ do {                                                                      \
  "%f40", "%f41", "%f42", "%f43", "%f44", "%f45", "%f46", "%f47",       \
  "%f48", "%f49", "%f50", "%f51", "%f52", "%f53", "%f54", "%f55",       \
  "%f56", "%f57", "%f58", "%f59", "%f60", "%f61", "%f62", "%f63",       \
- "%fcc0", "%fcc1", "%fcc2", "%fcc3", "%icc"}
+ "%fcc0", "%fcc1", "%fcc2", "%fcc3", "%icc", "%sfp" }
 
 /* Define additional names for use in asm clobbers and asm declarations.  */
 
@@ -2713,28 +2704,16 @@ do {                                                                    \
    guess...  */
 #define DBX_CONTIN_LENGTH 1000
 
-/* This is how to output the definition of a user-level label named NAME,
-   such as the label on a static function or variable NAME.  */
-
-#define ASM_OUTPUT_LABEL(FILE,NAME)    \
-  do { assemble_name (FILE, NAME); fputs (":\n", FILE); } while (0)
-
 /* This is how to output a command to make the user-level label named NAME
    defined for reference from other files.  */
 
-#define ASM_GLOBALIZE_LABEL(FILE,NAME) \
-  do { fputs ("\t.global ", FILE); assemble_name (FILE, NAME); fputs ("\n", FILE);} while (0)
+/* Globalizing directive for a label.  */
+#define GLOBAL_ASM_OP "\t.global "
 
 /* The prefix to add to user-visible assembler symbols.  */
 
 #define USER_LABEL_PREFIX "_"
 
-/* This is how to output a definition of an internal numbered label where
-   PREFIX is the class of label and NUM is the number within the class.  */
-
-#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM)     \
-  fprintf (FILE, "%s%d:\n", PREFIX, NUM)
-
 /* This is how to store into the string LABEL
    the symbol_ref name of an internal numbered label where
    PREFIX is the class of label and NUM is the number within the class.
@@ -2805,6 +2784,13 @@ do {                                                                     \
   if ((LOG) != 0)                      \
     fprintf (FILE, "\t.align %d\n", (1<<(LOG)))
 
+/* This is how to output an assembler line that says to advance
+   the location counter to a multiple of 2**LOG bytes using the
+   "nop" instruction as padding.  */
+#define ASM_OUTPUT_ALIGN_WITH_NOP(FILE,LOG)   \
+  if ((LOG) != 0)                             \
+    fprintf (FILE, "\t.align %d,0x1000000\n", (1<<(LOG)))
+
 #define ASM_OUTPUT_SKIP(FILE,SIZE)  \
   fprintf (FILE, "\t.skip %u\n", (SIZE))
 
@@ -2832,20 +2818,9 @@ do {                                                                     \
 
 #define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN)  \
   do {                                                         \
-    fputs (".globl ", (FILE));                                 \
-    assemble_name ((FILE), (NAME));                            \
-    fputs ("\n", (FILE));                                      \
     ASM_OUTPUT_ALIGNED_LOCAL (FILE, NAME, SIZE, ALIGN);                \
   } while (0)
 
-/* Store in OUTPUT a string (made with alloca) containing
-   an assembler-name for a local static variable named NAME.
-   LABELNO is an integer which is different for each call.  */
-
-#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
-( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10),   \
-  sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))
-
 #define IDENT_ASM_OP "\t.ident\t"
 
 /* Output #ident as a .ident.  */
@@ -2853,27 +2828,6 @@ do {                                                                     \
 #define ASM_OUTPUT_IDENT(FILE, NAME) \
   fprintf (FILE, "%s\"%s\"\n", IDENT_ASM_OP, NAME);
 
-/* 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 PRINT_OPERAND_PUNCT_VALID_P(CHAR) \
   ((CHAR) == '#' || (CHAR) == '*' || (CHAR) == '^' || (CHAR) == '(' || (CHAR) == '_')
 
@@ -2966,9 +2920,12 @@ 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}},                                           \
 {"icc_or_fcc_reg_operand", {REG}},                                     \
 {"restore_operand", {REG}},                                            \
 {"call_operand", {MEM}},                                               \
@@ -2986,6 +2943,7 @@ do {                                                                      \
 {"eq_or_neq", {EQ, NE}},                                               \
 {"normal_comp_operator", {GE, GT, LE, LT, GTU, LEU}},                  \
 {"noov_compare_op", {NE, EQ, GE, GT, LE, LT, GEU, GTU, LEU, LTU}},     \
+{"noov_compare64_op", {NE, EQ, GE, GT, LE, LT, GEU, GTU, LEU, LTU}},   \
 {"v9_regcmp_op", {EQ, NE, GE, LT, LE, GT}},                            \
 {"extend_op", {SIGN_EXTEND, ZERO_EXTEND}},                             \
 {"cc_arithop", {AND, IOR, XOR}},                                       \
@@ -3011,4 +2969,3 @@ do {                                                                      \
 #define JMP_BUF_SIZE 12
 
 #define DONT_ACCESS_GBLS_AFTER_EPILOGUE (flag_pic)
-