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
 /* 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.
    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.  */
 /* 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 */
    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_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 \
 
 #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 ""
 
 #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
 #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
 
 
 #else
 
@@ -181,7 +187,7 @@ extern enum cmodel sparc_cmodel;
 #endif
 
 #if !defined(CPP_CPU32_DEFAULT_SPEC) || !defined(CPP_CPU64_DEFAULT_SPEC)
 #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
 #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=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)}}}}}}} \
 "
 
 %{!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.  */
 
    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"
 
 #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)
 
 #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}} \
 %{mv8plus:-Av8plus} \
 %{mcpu=v9:-Av9} \
 %{mcpu=ultrasparc:%{!mv8plus:-Av9a}} \
+%{mcpu=ultrasparc3:%{!mv8plus:-Av9b}} \
 %{!mcpu*:%{!mcypress:%{!msparclite:%{!mf930:%{!mf934:%{!mv8:%{!msupersparc:%(asm_cpu_default)}}}}}}} \
 "
 
 %{!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 "\
 /* 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)"
 
 %(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.
 /* 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
   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
 \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 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
 
 
 /* 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.  */
 
 
 /* Generate DBX debugging information.  */
 
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
 \f
 /* Run-time compilation parameters selecting different hardware subsets.  */
 
 \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)
 
 #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.  */
 /* 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)
 
 #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
    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)
 
 #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)
 
 #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)
 
 #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
    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)
 
 #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.  */
 /* ??? 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 */
 
 
 /* 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 */
 
    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_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_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.  */
 
 /* 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    \
 
 #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.
 
 
 /* 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 },         \
     {"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,                  \
     {"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,                                                   \
     {"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,                                                          \
     {"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,                                                  \
     {"supersparc", 0,                                                  \
-     N_("Optimize for SuperSparc processors") },                       \
+     N_("Optimize for SuperSPARC processors") },                       \
     /* End of deprecated options.  */                                  \
     {"ptr64", MASK_PTR64,                                              \
      N_("Pointers are 64-bit") },                                      \
     /* 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).  */
 /* 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
 
 /* 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_SPARCLET,
   PROCESSOR_TSC701,
   PROCESSOR_V9,
-  PROCESSOR_ULTRASPARC
+  PROCESSOR_ULTRASPARC,
+  PROCESSOR_ULTRASPARC3
 };
 
 /* This is set from -m{cpu,tune}=xxx.  */
 };
 
 /* 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)
 
    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,                          \
 #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,                          \
   { "tune=", &sparc_select[2].string,                          \
-    N_("Schedule code for given CPU") },                       \
+    N_("Schedule code for given CPU"), 0},                     \
   { "cmodel=", &sparc_cmodel_string,                           \
   { "cmodel=", &sparc_cmodel_string,                           \
-    N_("Use given Sparc code model") },                                \
+    N_("Use given SPARC code model"), 0},                      \
   SUBTARGET_OPTIONS                                            \
 }
 
   SUBTARGET_OPTIONS                                            \
 }
 
@@ -704,10 +656,6 @@ extern struct sparc_cpu_select sparc_select[];
 \f
 /* target machine storage layout */
 
 \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
 /* 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
 
 #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)
 #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
 #define MIN_UNITS_PER_WORD     4
+#endif
 
 /* Now define the sizes of the C data types.  */
 
 
 /* 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.  */
 #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
 
 #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
 
 /* 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.  */
 #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
 #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.  */
 
 \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.
    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.  */
 
 #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, 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
 
 /* 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, 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.  */
 
 /* 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                                                             \
   {                                                            \
 #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 */        \
       {                                                                \
        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)              \
     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 */        \
          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)                                    \
     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)                                           \
       {                                                                \
       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;                                     \
        /* 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);     \
        /* 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)
       }                                                                \
   }                                                            \
 while (0)
@@ -1079,9 +1015,9 @@ while (0)
 
 #define HARD_REGNO_NREGS(REGNO, MODE) \
   (TARGET_ARCH64                                                       \
 
 #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
    : ((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
 
 /* 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.  */
 /* 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.  */
 
 /* 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
 
 /* 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.  */
    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 ()))
 
    : ! (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
 
 /* 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.  */
 
 /* 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.
 
 /* 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
 
 
 #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.  */
    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.  */
 
    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
 
 /* 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)]
 
 
 #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
    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 \
 
 #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 */ \
   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 */ \
   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
 
 /* 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 \
 
 #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
 
 #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.  */
 #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.
    `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)
 
 #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 */
    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) \
 #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                         \
 
 #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) == '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.
    : 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)                          \
 #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                      \
        || (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
 
    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)                                     \
 
 #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                                              \
         || ((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)         \
 
 #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)))                      \
      && ((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))
    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 \
    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,
    : (-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) \
    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.  */
 
 /* 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.
 
 /* 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)
 
    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
 /* 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 */
 
 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
 
 };
 #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.  */
 
    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.
 
 /* 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!  */
 
    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.
 
 
 \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).  */
 
    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
   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
 
    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
 #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.  */
 
 /* 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,
 #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_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) \
 
 /* Implement `va_arg'.  */
 #define EXPAND_BUILTIN_VA_ARG(valist, type) \
@@ -1915,10 +1934,6 @@ do {                                                                     \
 
 #define STRICT_ARGUMENT_NAMING TARGET_V9
 
 
 #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()                \
 /* 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? */
    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
 
 /* 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, \
    ? 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.
 
 /* 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
    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
+#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))
 #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)      \
 
 /* 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.  */
 
 \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.
 /* 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) \
    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)))
 #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
        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) \
 
 #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.  */
 /* 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
 
 
 #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))
 
 /* 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
 
 #endif
 \f
@@ -2163,6 +2180,8 @@ do {                                                                      \
 
    If you change this, execute "rm explow.o recog.o reload.o".  */
 
 
    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                                           \
 #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_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)
 
 #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             \
                   && 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;                                  \
                   && (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;                                         \
 }
   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.
 \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.
 
    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
    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)                                                   \
   /* 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)                             \
       && 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);           \
     {                                                                  \
       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)
     }                                                                  \
   /* ??? 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.  */
 \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 */
 
    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
 
 /* 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
 
 /* 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
 /* 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))
 
    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)
    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"
 
 #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
 /* 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");                             \
       }                                                                        \
          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)
 
     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)
 
    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)
 /* 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)         \
   (((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.  */
 
 \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",       \
  "%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.  */
 
 
 /* Define additional names for use in asm clobbers and asm declarations.  */
 
@@ -2713,28 +2704,16 @@ do {                                                                    \
    guess...  */
 #define DBX_CONTIN_LENGTH 1000
 
    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.  */
 
 /* 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 "_"
 
 
 /* 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.
 /* 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)))
 
   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))
 
 #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 {                                                         \
 
 #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)
 
     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.  */
 #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);
 
 #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) == '_')
 
 #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}},          \
 
 #define PREDICATE_CODES                                                        \
 {"reg_or_0_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}},          \
+{"const1_operand", {CONST_INT}},                                       \
 {"fp_zero_operand", {CONST_DOUBLE}},                                   \
 {"fp_zero_operand", {CONST_DOUBLE}},                                   \
+{"fp_register_operand", {SUBREG, REG}},                                        \
 {"intreg_operand", {SUBREG, REG}},                                     \
 {"fcc_reg_operand", {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}},                                               \
 {"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}},     \
 {"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}},                                       \
 {"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)
 #define JMP_BUF_SIZE 12
 
 #define DONT_ACCESS_GBLS_AFTER_EPILOGUE (flag_pic)
-