OSDN Git Service

gcc/
[pf3gnuchains/gcc-fork.git] / gcc / config / sparc / sparc.h
index 595a0f5..3df1472 100644 (file)
@@ -1,6 +1,7 @@
 /* Definitions of target machine for GNU compiler, for Sun SPARC.
    Copyright (C) 1987, 1988, 1989, 1992, 1994, 1995, 1996, 1997, 1998, 1999
-   2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+   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.
@@ -9,7 +10,7 @@ This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
 any later version.
 
 GCC is distributed in the hope that it will be useful,
@@ -18,13 +19,92 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#include "config/vxworks-dummy.h"
 
 /* Note that some other tm.h files include this one and then override
    whatever definitions are necessary.  */
 
+/* Define the specific costs for a given cpu */
+
+struct processor_costs {
+  /* Integer load */
+  const int int_load;
+
+  /* Integer signed load */
+  const int int_sload;
+
+  /* Integer zeroed load */
+  const int int_zload;
+
+  /* Float load */
+  const int float_load;
+
+  /* fmov, fneg, fabs */
+  const int float_move;
+
+  /* fadd, fsub */
+  const int float_plusminus;
+
+  /* fcmp */
+  const int float_cmp;
+
+  /* fmov, fmovr */
+  const int float_cmove;
+
+  /* fmul */
+  const int float_mul;
+
+  /* fdivs */
+  const int float_div_sf;
+
+  /* fdivd */
+  const int float_div_df;
+
+  /* fsqrts */
+  const int float_sqrt_sf;
+
+  /* fsqrtd */
+  const int float_sqrt_df;
+
+  /* umul/smul */
+  const int int_mul;
+
+  /* mulX */
+  const int int_mulX;
+
+  /* integer multiply cost for each bit set past the most
+     significant 3, so the formula for multiply cost becomes:
+
+       if (rs1 < 0)
+         highest_bit = highest_clear_bit(rs1);
+       else
+         highest_bit = highest_set_bit(rs1);
+       if (highest_bit < 3)
+         highest_bit = 3;
+       cost = int_mul{,X} + ((highest_bit - 3) / int_mul_bit_factor);
+
+     A value of zero indicates that the multiply costs is fixed,
+     and not variable.  */
+  const int int_mul_bit_factor;
+
+  /* udiv/sdiv */
+  const int int_div;
+
+  /* divX */
+  const int int_divX;
+
+  /* movcc, movr */
+  const int int_cmove;
+
+  /* penalty for shifts, due to scheduling rules etc. */
+  const int shift_penalty;
+};
+
+extern const struct processor_costs *sparc_costs;
+
 /* Target CPU builtins.  FIXME: Defining sparc is for the benefit of
    Solaris only; otherwise just define __sparc__.  Sadly the headers
    are such a mess there is no Solaris-specific header.  */
@@ -113,8 +193,6 @@ enum cmodel {
   CM_EMBMEDANY
 };
 
-/* Value of -mcmodel specified by user.  */
-extern const char *sparc_cmodel_string;
 /* One of CM_FOO.  */
 extern enum cmodel sparc_cmodel;
 
@@ -126,6 +204,20 @@ extern enum cmodel sparc_cmodel;
 
 #define SPARC_DEFAULT_CMODEL CM_32
 
+/* The SPARC-V9 architecture defines a relaxed memory ordering model (RMO)
+   which requires the following macro to be true if enabled.  Prior to V9,
+   there are no instructions to even talk about memory synchronization.
+   Note that the UltraSPARC III processors don't implement RMO, unlike the
+   UltraSPARC II processors.  Niagara and Niagara-2 do not implement RMO
+   either.
+
+   Default to false; for example, Solaris never enables RMO, only ever uses
+   total memory ordering (TMO).  */
+#define SPARC_RELAXED_ORDERING false
+
+/* Do not use the .note.GNU-stack convention by default.  */
+#define NEED_INDICATE_EXEC_STACK 0
+
 /* This is call-clobbered in the normal ABI, but is reserved in the
    home grown (aka upward compatible) embedded ABI.  */
 #define EMBMEDANY_BASE_REG "%g4"
@@ -149,10 +241,14 @@ extern enum cmodel sparc_cmodel;
 #define TARGET_CPU_sparc64     7       /* alias */
 #define TARGET_CPU_ultrasparc  8
 #define TARGET_CPU_ultrasparc3 9
+#define TARGET_CPU_niagara     10
+#define TARGET_CPU_niagara2    11
 
 #if TARGET_CPU_DEFAULT == TARGET_CPU_v9 \
  || TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc \
- || TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc3
+ || TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc3 \
+ || TARGET_CPU_DEFAULT == TARGET_CPU_niagara \
+ || TARGET_CPU_DEFAULT == TARGET_CPU_niagara2
 
 #define CPP_CPU32_DEFAULT_SPEC ""
 #define ASM_CPU32_DEFAULT_SPEC ""
@@ -173,6 +269,14 @@ extern enum cmodel sparc_cmodel;
 #define CPP_CPU64_DEFAULT_SPEC "-D__sparc_v9__"
 #define ASM_CPU64_DEFAULT_SPEC "-Av9b"
 #endif
+#if TARGET_CPU_DEFAULT == TARGET_CPU_niagara
+#define CPP_CPU64_DEFAULT_SPEC "-D__sparc_v9__"
+#define ASM_CPU64_DEFAULT_SPEC "-Av9b"
+#endif
+#if TARGET_CPU_DEFAULT == TARGET_CPU_niagara2
+#define CPP_CPU64_DEFAULT_SPEC "-D__sparc_v9__"
+#define ASM_CPU64_DEFAULT_SPEC "-Av9b"
+#endif
 
 #else
 
@@ -263,6 +367,8 @@ extern enum cmodel sparc_cmodel;
 %{mcpu=v9:-D__sparc_v9__} \
 %{mcpu=ultrasparc:-D__sparc_v9__} \
 %{mcpu=ultrasparc3:-D__sparc_v9__} \
+%{mcpu=niagara:-D__sparc_v9__} \
+%{mcpu=niagara2:-D__sparc_v9__} \
 %{!mcpu*:%{!mcypress:%{!msparclite:%{!mf930:%{!mf934:%{!mv8:%{!msupersparc:%(cpp_cpu_default)}}}}}}} \
 "
 #define CPP_ARCH32_SPEC ""
@@ -312,6 +418,8 @@ extern enum cmodel sparc_cmodel;
 %{mcpu=v9:-Av9} \
 %{mcpu=ultrasparc:%{!mv8plus:-Av9a}} \
 %{mcpu=ultrasparc3:%{!mv8plus:-Av9b}} \
+%{mcpu=niagara:%{!mv8plus:-Av9b}} \
+%{mcpu=niagara2:%{!mv8plus:-Av9b}} \
 %{!mcpu*:%{!mcypress:%{!msparclite:%{!mf930:%{!mf934:%{!mv8:%{!msupersparc:%(asm_cpu_default)}}}}}}} \
 "
 
@@ -388,134 +496,15 @@ extern enum cmodel sparc_cmodel;
 /* ??? This should be 32 bits for v9 but what can we do?  */
 #define WCHAR_TYPE "short unsigned int"
 #define WCHAR_TYPE_SIZE 16
-
-/* Show we can debug even without a frame pointer.  */
-#define CAN_DEBUG_WITHOUT_FP
-
-#define OVERRIDE_OPTIONS  sparc_override_options ()
-
-/* Generate DBX debugging information.  */
-
-#define DBX_DEBUGGING_INFO 1
 \f
-/* Run-time compilation parameters selecting different hardware subsets.  */
-
-extern int target_flags;
-
-/* Nonzero if we should generate code to use the fpu.  */
-#define MASK_FPU 1
-#define TARGET_FPU (target_flags & MASK_FPU)
-
-/* 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.  */
-#define MASK_UNALIGNED_DOUBLES 4
-#define TARGET_UNALIGNED_DOUBLES (target_flags & MASK_UNALIGNED_DOUBLES)
-
-/* Nonzero means that we should generate code for a v8 sparc.  */
-#define MASK_V8 0x8
-#define TARGET_V8 (target_flags & MASK_V8)
-
-/* Nonzero means that we should generate code for a sparclite.
-   This enables the sparclite specific instructions, but does not affect
-   whether FPU instructions are emitted.  */
-#define MASK_SPARCLITE 0x10
-#define TARGET_SPARCLITE (target_flags & MASK_SPARCLITE)
-
-/* Nonzero if we're compiling for the sparclet.  */
-#define MASK_SPARCLET 0x20
-#define TARGET_SPARCLET (target_flags & MASK_SPARCLET)
-
-/* Nonzero if we're compiling for v9 sparc.
-   Note that v9's can run in 32 bit mode so this doesn't necessarily mean
-   the word size is 64.  */
-#define MASK_V9 0x40
-#define TARGET_V9 (target_flags & MASK_V9)
-
-/* 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
-   on 64 bit v9 systems.  */
-#define MASK_DEPRECATED_V8_INSNS 0x80
-#define TARGET_DEPRECATED_V8_INSNS (target_flags & MASK_DEPRECATED_V8_INSNS)
-
 /* Mask of all CPU selection flags.  */
 #define MASK_ISA \
 (MASK_V8 + MASK_SPARCLITE + MASK_SPARCLET + MASK_V9 + MASK_DEPRECATED_V8_INSNS)
 
-/* 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)
-
-/* 0x200 is unused */
-
-/* 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
-#define TARGET_APP_REGS (target_flags & MASK_APP_REGS)
-
-/* Option to select how quad word floating point is implemented.
-   When TARGET_HARD_QUAD is true, we use the hardware quad instructions.
-   Otherwise, we use the SPARC ABI quad library functions.  */
-#define MASK_HARD_QUAD 0x800
-#define TARGET_HARD_QUAD (target_flags & MASK_HARD_QUAD)
-
-/* Nonzero on little-endian machines.  */
-/* ??? Little endian support currently only exists for sparc86x-elf 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.  */
-#define MASK_LITTLE_ENDIAN 0x1000
-#define TARGET_LITTLE_ENDIAN (target_flags & MASK_LITTLE_ENDIAN)
-
-/* 0x2000, 0x4000 are unused */
-
-/* Nonzero if pointers are 64 bits.  */
-#define MASK_PTR64 0x8000
-#define TARGET_PTR64 (target_flags & MASK_PTR64)
-
-/* Nonzero if generating code to run in a 64 bit environment.
-   This is intended to only be used by TARGET_ARCH{32,64} as they are the
-   mechanism used to control compile time or run time selection.  */
-#define MASK_64BIT 0x10000
-#define TARGET_64BIT (target_flags & MASK_64BIT)
-
-/* 0x20000,0x40000 unused */
-
-/* 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 */
-
-/* Nonzero means -m{,no-}fpu was passed on the command line.  */
-#define MASK_FPU_SET 0x400000
-#define TARGET_FPU_SET (target_flags & MASK_FPU_SET)
-
-/* Use the UltraSPARC Visual Instruction Set extensions.  */
-#define MASK_VIS 0x1000000
-#define 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)
-
-/* Force a the fastest alignment on structures to take advantage of
-   faster copies.  */
-#define MASK_FASTER_STRUCTS 0x4000000
-#define TARGET_FASTER_STRUCTS (target_flags & MASK_FASTER_STRUCTS)
-
-/* Use IEEE quad long double.  */
-#define MASK_LONG_DOUBLE_128 0x8000000
-#define TARGET_LONG_DOUBLE_128 (target_flags & MASK_LONG_DOUBLE_128)
-
 /* TARGET_HARD_MUL: Use hardware multiply instructions but not %y.
    TARGET_HARD_MUL32: Use hardware multiply instructions with rd %y
    to get high 32 bits.  False in V8+ or V9 because multiply stores
-   a 64 bit result in a register.  */
+   a 64-bit result in a register.  */
 
 #define TARGET_HARD_MUL32                              \
   ((TARGET_V8 || TARGET_SPARCLITE                      \
@@ -526,79 +515,11 @@ extern int target_flags;
   (TARGET_V8 || TARGET_SPARCLITE || TARGET_SPARCLET    \
    || TARGET_DEPRECATED_V8_INSNS || TARGET_V8PLUS)
 
-
-/* Macro to define tables used to set the flags.
-   This is a list in braces of pairs in braces,
-   each pair being { "NAME", VALUE }
-   where VALUE is the bits to set or minus the bits to clear.
-   An empty string NAME is used to identify the default VALUE.  */
-
-#define TARGET_SWITCHES  \
-  { {"fpu", MASK_FPU | MASK_FPU_SET,                                   \
-     N_("Use hardware fp") },                                          \
-    {"no-fpu", -MASK_FPU,                                              \
-     N_("Do not use hardware fp") },                                   \
-    {"no-fpu", MASK_FPU_SET,                           NULL, },        \
-    {"hard-float", MASK_FPU | MASK_FPU_SET,                            \
-     N_("Use hardware fp") },                                          \
-    {"soft-float", -MASK_FPU,                                          \
-     N_("Do not use hardware fp") },                                   \
-    {"soft-float", MASK_FPU_SET,                       NULL },         \
-    {"unaligned-doubles", MASK_UNALIGNED_DOUBLES,                      \
-     N_("Assume possible double misalignment") },                      \
-    {"no-unaligned-doubles", -MASK_UNALIGNED_DOUBLES,                  \
-     N_("Assume all doubles are aligned") },                           \
-    {"impure-text", MASK_IMPURE_TEXT,                                  \
-     N_("Pass -assert pure-text to linker") },                                 \
-    {"no-impure-text", -MASK_IMPURE_TEXT,                              \
-     N_("Do not pass -assert pure-text to linker") },                  \
-    {"app-regs", MASK_APP_REGS,                                                \
-     N_("Use ABI reserved registers") },                               \
-    {"no-app-regs", -MASK_APP_REGS,                                    \
-     N_("Do not use ABI reserved registers") },                        \
-    {"hard-quad-float", MASK_HARD_QUAD,                                        \
-     N_("Use hardware quad fp instructions") },                        \
-    {"soft-quad-float", -MASK_HARD_QUAD,                               \
-     N_("Do not use hardware quad fp instructions") },                         \
-    {"v8plus", MASK_V8PLUS,                                            \
-     N_("Compile for v8plus ABI") },                                   \
-    {"no-v8plus", -MASK_V8PLUS,                                                \
-     N_("Do not compile for v8plus ABI") },                            \
-    {"vis", MASK_VIS,                                                  \
-     N_("Utilize Visual Instruction Set") },                           \
-    {"no-vis", -MASK_VIS,                                              \
-     N_("Do not utilize Visual Instruction Set") },                    \
-    {"ptr64", MASK_PTR64,                                              \
-     N_("Pointers are 64-bit") },                                      \
-    {"ptr32", -MASK_PTR64,                                             \
-     N_("Pointers are 32-bit") },                                      \
-    {"32", -MASK_64BIT,                                                        \
-     N_("Use 32-bit ABI") },                                           \
-    {"64", MASK_64BIT,                                                 \
-     N_("Use 64-bit ABI") },                                           \
-    {"stack-bias", MASK_STACK_BIAS,                                    \
-     N_("Use stack bias") },                                           \
-    {"no-stack-bias", -MASK_STACK_BIAS,                                        \
-     N_("Do not use stack bias") },                                    \
-    {"faster-structs", MASK_FASTER_STRUCTS,                            \
-     N_("Use structs on stronger alignment for double-word copies") },         \
-    {"no-faster-structs", -MASK_FASTER_STRUCTS,                                \
-     N_("Do not use structs on stronger alignment for double-word copies") }, \
-    {"relax", 0,                                                       \
-     N_("Optimize tail call instructions in assembler and linker") },  \
-    {"no-relax", 0,                                                    \
-     N_("Do not optimize tail call instructions in assembler or linker") }, \
-    SUBTARGET_SWITCHES                 \
-    { "", TARGET_DEFAULT, ""}}
-
 /* 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_FPU)
 
-/* This is meant to be redefined in target specific files.  */
-#define SUBTARGET_SWITCHES
-
 /* Processor type.
    These must match the values for the cpu attribute in sparc.md.  */
 enum processor_type {
@@ -615,7 +536,9 @@ enum processor_type {
   PROCESSOR_TSC701,
   PROCESSOR_V9,
   PROCESSOR_ULTRASPARC,
-  PROCESSOR_ULTRASPARC3
+  PROCESSOR_ULTRASPARC3,
+  PROCESSOR_NIAGARA,
+  PROCESSOR_NIAGARA2
 };
 
 /* This is set from -m{cpu,tune}=xxx.  */
@@ -625,20 +548,6 @@ 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)
 
-#define TARGET_OPTIONS \
-{                                                              \
-  { "cpu=",  &sparc_select[1].string,                          \
-    N_("Use features of and schedule code for given CPU"), 0}, \
-  { "tune=", &sparc_select[2].string,                          \
-    N_("Schedule code for given CPU"), 0},                     \
-  { "cmodel=", &sparc_cmodel_string,                           \
-    N_("Use given SPARC code model"), 0},                      \
-  SUBTARGET_OPTIONS                                            \
-}
-
-/* This is meant to be redefined in target specific files.  */
-#define SUBTARGET_OPTIONS
-
 /* Support for a compile-time default CPU, et cetera.  The rules are:
    --with-cpu is ignored if -mcpu is specified.
    --with-tune is ignored if -mtune is specified.
@@ -673,14 +582,6 @@ extern struct sparc_cpu_select sparc_select[];
    numbered.  */
 #define WORDS_BIG_ENDIAN 1
 
-/* Define this to set the endianness to use in libgcc2.c, which can
-   not depend on target_flags.  */
-#if defined (__LITTLE_ENDIAN__) || defined(__LITTLE_ENDIAN_DATA__)
-#define LIBGCC2_WORDS_BIG_ENDIAN 0
-#else
-#define LIBGCC2_WORDS_BIG_ENDIAN 1
-#endif
-
 #define MAX_BITS_PER_WORD      64
 
 /* Width of a word, in units (bytes).  */
@@ -699,39 +600,33 @@ extern struct sparc_cpu_select sparc_select[];
 #define LONG_LONG_TYPE_SIZE    64
 #define FLOAT_TYPE_SIZE                32
 #define DOUBLE_TYPE_SIZE       64
+
 /* LONG_DOUBLE_TYPE_SIZE is defined per OS even though the
    SPARC ABI says that it is 128-bit wide.  */
 /* #define LONG_DOUBLE_TYPE_SIZE       128 */
 
-/* Width in bits of a pointer.
-   See also the macro `Pmode' defined below.  */
+/* The widest floating-point format really supported by the hardware.  */
+#define WIDEST_HARDWARE_FP_SIZE 64
+
+/* Width in bits of a pointer.  This is the size of ptr_mode.  */
 #define POINTER_SIZE (TARGET_PTR64 ? 64 : 32)
 
+/* This is the machine mode used for addresses.  */
+#define Pmode (TARGET_ARCH64 ? DImode : SImode)
+
 /* If we have to extend pointers (only when TARGET_ARCH64 and not
    TARGET_PTR64), we want to do it unsigned.   This macro does nothing
    if ptr_mode and Pmode are the same.  */
 #define POINTERS_EXTEND_UNSIGNED 1
 
-/* For TARGET_ARCH64 we need this, as we don't have instructions
-   for arithmetic operations which do zero/sign extension at the same time,
-   so without this we end up with a srl/sra after every assignment to an
-   user variable,  which means very very bad code.  */
-#define PROMOTE_FUNCTION_MODE(MODE, UNSIGNEDP, TYPE) \
-if (TARGET_ARCH64                              \
-    && GET_MODE_CLASS (MODE) == MODE_INT       \
-    && GET_MODE_SIZE (MODE) < UNITS_PER_WORD)  \
-  (MODE) = word_mode;
-
 /* Allocation boundary (in *bits*) for storing arguments in argument list.  */
 #define PARM_BOUNDARY (TARGET_ARCH64 ? 64 : 32)
 
 /* Boundary (in *bits*) on which stack pointer should be aligned.  */
 /* FIXME, this is wrong when TARGET_ARCH64 and TARGET_STACK_BIAS, because
-   then sp+2047 is 128-bit aligned so sp is really only byte-aligned.  */
+   then %sp+2047 is 128-bit aligned so %sp is really only byte-aligned.  */
 #define STACK_BOUNDARY (TARGET_ARCH64 ? 128 : 64)
-/* Temporary hack until the FIXME above is fixed.  This macro is used
-   only in pad_to_arg_alignment in function.c; see the comment there
-   for details about what it does.  */
+/* Temporary hack until the FIXME above is fixed.  */
 #define SPARC_STACK_BOUNDARY_HACK (TARGET_ARCH64 && TARGET_STACK_BIAS)
 
 /* ALIGN FRAMES on double word boundaries */
@@ -786,6 +681,9 @@ if (TARGET_ARCH64                           \
    && TYPE_MODE (TREE_TYPE (TYPE)) == QImode   \
    && (ALIGN) < FASTEST_ALIGNMENT ? FASTEST_ALIGNMENT : (ALIGN))
 
+/* Make local arrays of chars word-aligned for the same reasons.  */
+#define LOCAL_ALIGNMENT(TYPE, ALIGN) DATA_ALIGNMENT (TYPE, ALIGN)
+
 /* Set this nonzero if move instructions will actually fail to work
    when given unaligned data.  */
 #define STRICT_ALIGNMENT 1
@@ -804,9 +702,9 @@ if (TARGET_ARCH64                           \
    even those that are not normally considered general registers.
 
    SPARC has 32 integer registers and 32 floating point registers.
-   64 bit SPARC has 32 additional fp regs, but the odd numbered ones are not
+   64-bit SPARC has 32 additional fp regs, but the odd numbered ones are not
    accessible.  We still account for them to simplify register computations
-   (eg: in CLASS_MAX_NREGS).  There are also 4 fp condition code registers, so
+   (e.g.: 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 101 is used as the soft frame pointer register.  */
@@ -989,6 +887,11 @@ extern int sparc_mode_class[];
 #define HARD_REGNO_MODE_OK(REGNO, MODE) \
   ((hard_regno_mode_classes[REGNO] & sparc_mode_class[MODE]) != 0)
 
+/* Value is 1 if it is OK to rename a hard register FROM to another hard
+   register TO.  We cannot rename %g1 as it may be used before the save
+   register window instruction in the prologue.  */
+#define HARD_REGNO_RENAME_OK(FROM, TO) ((FROM) != 1)
+
 /* Value is 1 if it is a good idea to tie two pseudo registers
    when one has mode MODE1 and one has mode MODE2.
    If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
@@ -1007,9 +910,6 @@ extern int sparc_mode_class[];
 /* Specify the registers used for certain standard purposes.
    The values of these macros are register numbers.  */
 
-/* SPARC pc isn't overloaded on a register that the compiler knows about.  */
-/* #define PC_REGNUM  */
-
 /* Register to use for pushing function arguments.  */
 #define STACK_POINTER_REGNUM 14
 
@@ -1033,21 +933,13 @@ extern int sparc_mode_class[];
 /* 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)    \
+    if (crtl->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
-   may be accessed via the stack pointer) in functions that seem suitable.
-   This is computed in `reload', in reload1.c.
-   Used in flow.c, global.c, and reload1.c.  */
-#define FRAME_POINTER_REQUIRED \
-  (! (leaf_function_p () && only_leaf_regs_used ()))
-
 /* Base register for access to arguments of the function.  */
 #define ARG_POINTER_REGNUM FRAME_POINTER_REGNUM
 
@@ -1062,9 +954,12 @@ extern int sparc_mode_class[];
 
 /* Pick a default value we can notice from override_options:
    !v9: Default is on.
-   v9: Default is off.  */
+   v9: Default is off.
+   Originally it was -1, but later on the container of options changed to
+   unsigned byte, so we decided to pick 127 as default value, which does
+   reflect an undefined default value in case of 0/1.  */
 
-#define DEFAULT_PCC_STRUCT_RETURN -1
+#define DEFAULT_PCC_STRUCT_RETURN 127
 
 /* Functions which return large structures get the address
    to place the wanted value at offset 64 from the frame.
@@ -1110,11 +1005,12 @@ extern int sparc_mode_class[];
    because reg_class_subunion[GENERAL_REGS][FP_REGS] will yield FP_REGS,
    because FP_REGS > GENERAL_REGS.
 
-   It is also important that one class contain all the general and all the
-   fp regs.  Otherwise when spilling a DFmode reg, it may be from EXTRA_FP_REGS
-   but find_reloads() may use class GENERAL_OR_FP_REGS. This will cause
-   allocate_reload_reg() to bypass it causing an abort because the compiler
-   thinks it doesn't have a spill reg when in fact it does.
+   It is also important that one class contain all the general and all
+   the fp regs.  Otherwise when spilling a DFmode reg, it may be from
+   EXTRA_FP_REGS but find_reloads() may use class
+   GENERAL_OR_FP_REGS. This will cause allocate_reload_reg() to die
+   because the compiler thinks it doesn't have a spill reg when in
+   fact it does.
 
    v9 also has 4 floating point condition code registers.  Since we don't
    have a class that is the union of FPCC_REGS with either of the others,
@@ -1155,6 +1051,28 @@ enum reg_class { NO_REGS, FPCC_REGS, I64_REGS, GENERAL_REGS, 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
+   reg number REGNO.  This could be a conditional expression
+   or could index an array.  */
+
+extern enum reg_class sparc_regno_reg_class[FIRST_PSEUDO_REGISTER];
+
+#define REGNO_REG_CLASS(REGNO) sparc_regno_reg_class[(REGNO)]
+
+/* The following macro defines cover classes for Integrated Register
+   Allocator.  Cover classes is a set of non-intersected register
+   classes covering all hard registers used for register allocation
+   purpose.  Any move between two registers of a cover class should be
+   cheaper than load or store of the registers.  The macro value is
+   array of register classes with LIM_REG_CLASSES used as the end
+   marker.  */
+
+#define IRA_COVER_CLASSES                                                   \
+{                                                                           \
+  GENERAL_REGS, EXTRA_FP_REGS, FPCC_REGS, LIM_REG_CLASSES                   \
+}
+
 /* Defines invalid mode changes.  Borrowed from pa64-regs.h.
 
    SImode loads to floating-point registers are not zero-extended.
@@ -1169,15 +1087,6 @@ enum reg_class { NO_REGS, FPCC_REGS, I64_REGS, GENERAL_REGS, FP_REGS,
    && GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO)               \
    ? reg_classes_intersect_p (CLASS, FP_REGS) : 0)
 
-/* The same information, inverted:
-   Return the class number of the smallest class containing
-   reg number REGNO.  This could be a conditional expression
-   or could index an array.  */
-
-extern enum reg_class sparc_regno_reg_class[FIRST_PSEUDO_REGISTER];
-
-#define REGNO_REG_CLASS(REGNO) sparc_regno_reg_class[(REGNO)]
-
 /* This is the order in which to allocate registers normally.
 
    We put %f0-%f7 last among the float registers, so as to make it more
@@ -1255,7 +1164,7 @@ extern enum reg_class sparc_regno_reg_class[FIRST_PSEUDO_REGISTER];
   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 ()
+#define ADJUST_REG_ALLOC_ORDER order_regs_for_local_alloc ()
 
 extern char sparc_leaf_regs[];
 #define LEAF_REGISTERS sparc_leaf_regs
@@ -1270,75 +1179,32 @@ extern char leaf_reg_remap[];
 /* Local macro to handle the two v9 classes of FP regs.  */
 #define FP_REG_CLASS_P(CLASS) ((CLASS) == FP_REGS || (CLASS) == EXTRA_FP_REGS)
 
-/* Get reg_class from a letter such as appears in the machine description.
-   In the not-v9 case, coerce v9's 'e' class to 'f', so we can use 'e' in the
-   .md file for v8 and v9.
-   'd' and 'b' are used for single and double precision VIS operations,
-   if TARGET_VIS.
-   'h' is used for V8+ 64 bit global and out registers.  */
-
-#define REG_CLASS_FROM_LETTER(C)               \
-(TARGET_V9                                     \
- ? ((C) == 'f' ? FP_REGS                       \
-    : (C) == 'e' ? EXTRA_FP_REGS               \
-    : (C) == 'c' ? FPCC_REGS                   \
-    : ((C) == 'd' && TARGET_VIS) ? FP_REGS\
-    : ((C) == 'b' && TARGET_VIS) ? EXTRA_FP_REGS\
-    : ((C) == 'h' && TARGET_V8PLUS) ? I64_REGS\
-    : NO_REGS)                                 \
- : ((C) == 'f' ? FP_REGS                       \
-    : (C) == 'e' ? FP_REGS                     \
-    : (C) == 'c' ? FPCC_REGS                   \
-    : NO_REGS))
-
-/* The letters I, J, K, L and M in a register constraint string
-   can be used to stand for particular ranges of immediate operands.
-   This macro defines what the ranges are.
-   C is the letter, and VALUE is a constant value.
-   Return 1 if VALUE is in the range specified by C.
-
-   `I' is used for the range of constants an insn can actually contain.
-   `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.
-   `N' is like K, but for constants wider than 32 bits.
-   `O' is used for the range which is just 4096.  */
-
+/* Predicates for 10-bit, 11-bit and 13-bit signed constants.  */
 #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_SIMM13_P(X) ((unsigned HOST_WIDE_INT) (X) + 0x1000 < 0x2000)
-/* 10 and 11 bit immediates are only used for a few specific insns.
+
+/* 10- and 11-bit immediates are only used for a few specific insns.
    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 (trunc_int_for_mode \
-                                       (INTVAL (X), SImode)))
+
+/* Predicate for constants that can be loaded with a sethi instruction.
+   This is the general, 64-bit aware, bitwise version that ensures that
+   only constants whose representation fits in the mask
+
+     0x00000000fffffc00
+
+   are accepted.  It will reject, for example, negative SImode constants
+   on 64-bit hosts, so correct handling is to mask the value beforehand
+   according to the mode of the instruction.  */
 #define SPARC_SETHI_P(X) \
   (((unsigned HOST_WIDE_INT) (X) \
     & ((unsigned HOST_WIDE_INT) 0x3ff - GET_MODE_MASK (SImode) - 1)) == 0)
+
+/* Version of the above predicate for SImode constants and below.  */
 #define SPARC_SETHI32_P(X) \
   (SPARC_SETHI_P ((unsigned HOST_WIDE_INT) (X) & GET_MODE_MASK (SImode)))
 
-#define CONST_OK_FOR_LETTER_P(VALUE, C)  \
-  ((C) == 'I' ? SPARC_SIMM13_P (VALUE)                 \
-   : (C) == 'J' ? (VALUE) == 0                         \
-   : (C) == 'K' ? SPARC_SETHI32_P (VALUE)              \
-   : (C) == 'L' ? SPARC_SIMM11_P (VALUE)               \
-   : (C) == 'M' ? SPARC_SIMM10_P (VALUE)               \
-   : (C) == 'N' ? SPARC_SETHI_P (VALUE)                        \
-   : (C) == 'O' ? (VALUE) == 4096                      \
-   : 0)
-
-/* Similar, but for floating constants, and defining letters G and H.
-   Here VALUE is the CONST_DOUBLE rtx itself.  */
-
-#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
-  ((C) == 'G' ? fp_zero_operand (VALUE, GET_MODE (VALUE))      \
-   : (C) == 'H' ? arith_double_operand (VALUE, DImode)         \
-   : (C) == 'O' ? arith_double_4096_operand (VALUE, DImode)    \
-   : 0)
-
 /* Given an rtx X being reloaded into a reg required to be
    in class CLASS, return the class of reg to actually use.
    In general this is just CLASS; but on some machines
@@ -1359,7 +1225,7 @@ extern char leaf_reg_remap[];
        || (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \
           && ! TARGET_FPU)                             \
        || (GET_MODE (X) == TFmode                      \
-          && ! fp_zero_operand (X, TFmode)))           \
+          && ! const_zero_operand (X, TFmode)))        \
       ? NO_REGS                                                \
       : (!FP_REG_CLASS_P (CLASS)                       \
          && GET_MODE_CLASS (GET_MODE (X)) == MODE_INT) \
@@ -1420,16 +1286,6 @@ extern char leaf_reg_remap[];
 #define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \
   (FP_REG_CLASS_P (CLASS1) != FP_REG_CLASS_P (CLASS2))
 
-/* Return the stack location to use for secondary memory needed reloads.
-   We want to use the reserved location just below the frame pointer.
-   However, we must ensure that there is a frame, so use assign_stack_local
-   if the frame size is zero.  */
-#define SECONDARY_MEMORY_NEEDED_RTX(MODE) \
-  (get_frame_size () == 0                                              \
-   ? assign_stack_local (MODE, GET_MODE_SIZE (MODE), 0)                        \
-   : gen_rtx_MEM (MODE, plus_constant (frame_pointer_rtx,              \
-                                      STARTING_FRAME_OFFSET)))
-
 /* Get_secondary_mem widens its argument to BITS_PER_WORD which loses on v9
    because the movsi and movsf patterns don't handle r/f moves.
    For v8 we copy the default definition.  */
@@ -1455,25 +1311,17 @@ extern char leaf_reg_remap[];
    makes the stack pointer a smaller address.  */
 #define STACK_GROWS_DOWNWARD
 
-/* Define this if the nominal address of the stack frame
+/* Define this to nonzero if the nominal address of the stack frame
    is at the high-address end of the local variables;
    that is, each additional local variable allocated
    goes at a more negative offset in the frame.  */
-#define FRAME_GROWS_DOWNWARD
+#define FRAME_GROWS_DOWNWARD 1
 
 /* Offset within stack frame to start allocating local variables at.
    If FRAME_GROWS_DOWNWARD, this is the offset to the END of the
    first local allocated.  Otherwise, it is the offset to the BEGINNING
    of the first local allocated.  */
-/* This allows space for one TFmode floating point value.  */
-#define STARTING_FRAME_OFFSET \
-  (TARGET_ARCH64 ? -16 \
-   : (-SPARC_STACK_ALIGN (LONG_DOUBLE_TYPE_SIZE / BITS_PER_UNIT)))
-
-/* If we generate an insn to push BYTES bytes,
-   this says how many the stack pointer really advances by.
-   On SPARC, don't define this because there are no push insns.  */
-/*  #define PUSH_ROUNDING(BYTES) */
+#define STARTING_FRAME_OFFSET 0
 
 /* Offset of first parameter from the argument pointer register value.
    !v9: This is 64 for the ins and locals, plus 4 for the struct-return reg
@@ -1504,21 +1352,15 @@ extern char leaf_reg_remap[];
   {{ 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)
-
 /* 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_ELIMINATION_OFFSET(FROM, TO, OFFSET)                   \
   do {                                                                 \
-    (OFFSET) = 0;                                                      \
     if ((TO) == STACK_POINTER_REGNUM)                                  \
       (OFFSET) = sparc_compute_frame_size (get_frame_size (), 1);      \
+    else                                                               \
+      (OFFSET) = 0;                                                    \
     (OFFSET) += SPARC_STACK_BIAS;                                      \
   } while (0)
 
@@ -1528,15 +1370,6 @@ extern char leaf_reg_remap[];
    the function!  */
 #define ACCUMULATE_OUTGOING_ARGS 1
 
-/* Value is the number of bytes of arguments automatically
-   popped when returning from a subroutine call.
-   FUNDECL is the declaration node of the function (as a tree),
-   FUNTYPE is the data type of the function (as a tree),
-   or for a library call it is an identifier node for the subroutine name.
-   SIZE is the number of bytes of arguments passed on the stack.  */
-
-#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0
-
 /* Define this macro if the target machine has "register windows".  This
    C expression returns the register number as seen by the called function
    corresponding to register number OUT as seen by the calling function.
@@ -1560,38 +1393,10 @@ extern char leaf_reg_remap[];
 #define LOCAL_REGNO(REGNO) \
   ((REGNO) >= 16 && (REGNO) <= 31)
 
-/* Define how to find the value returned by a function.
-   VALTYPE is the data type of the value (as a tree).
-   If the precise function being called is known, FUNC is its FUNCTION_DECL;
-   otherwise, FUNC is 0.  */
-
-/* On SPARC the value is found in the first "output" register.  */
-
-#define FUNCTION_VALUE(VALTYPE, FUNC) \
-  function_value ((VALTYPE), TYPE_MODE (VALTYPE), 1)
-
-/* But the called function leaves it in the first "input" register.  */
-
-#define FUNCTION_OUTGOING_VALUE(VALTYPE, FUNC) \
-  function_value ((VALTYPE), TYPE_MODE (VALTYPE), 0)
-
-/* Define how to find the value returned by a library function
-   assuming the value has mode MODE.  */
-
-#define LIBCALL_VALUE(MODE) \
-  function_value (NULL_TREE, (MODE), 1)
-
-/* 1 if N is a possible register number for a function value
-   as seen by the caller.
-   On SPARC, the first "output" reg is used for integer values,
-   and the first floating point register is used for floating point values.  */
-
-#define FUNCTION_VALUE_REGNO_P(N) ((N) == 8 || (N) == 32)
-
 /* Define the size of space to allocate for the return value of an
    untyped_call.  */
 
-#define APPLY_RESULT_SIZE 16
+#define APPLY_RESULT_SIZE (TARGET_ARCH64 ? 24 : 16)
 
 /* 1 if N is a possible register number for function argument passing.
    On SPARC, these are the "output" registers.  v9 also uses %f0-%f31.  */
@@ -1628,58 +1433,6 @@ struct sparc_args {
 #define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS) \
 init_cumulative_args (& (CUM), (FNTYPE), (LIBNAME), (FNDECL));
 
-/* Update the data in CUM to advance over an argument
-   of mode MODE and data type TYPE.
-   TYPE is null for libcalls where that information may not be available.  */
-
-#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
-function_arg_advance (& (CUM), (MODE), (TYPE), (NAMED))
-
-/* Nonzero if we do not know how to pass TYPE solely in registers.  */
-
-#define MUST_PASS_IN_STACK(MODE,TYPE)                  \
-  ((TYPE) != 0                                         \
-   && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST     \
-       || TREE_ADDRESSABLE (TYPE)))
-
-/* Determine where to put an argument to a function.
-   Value is zero to push the argument on the stack,
-   or a hard register in which to store the argument.
-
-   MODE is the argument's machine mode.
-   TYPE is the data type of the argument (as a tree).
-    This is null for libcalls where that information may
-    not be available.
-   CUM is a variable of type CUMULATIVE_ARGS which gives info about
-    the preceding args and about the function being called.
-   NAMED is nonzero if this argument is a named parameter
-    (otherwise it is an extra parameter matching an ellipsis).  */
-
-#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
-function_arg (& (CUM), (MODE), (TYPE), (NAMED), 0)
-
-/* Define where a function finds its arguments.
-   This is different from FUNCTION_ARG because of register windows.  */
-
-#define FUNCTION_INCOMING_ARG(CUM, MODE, TYPE, NAMED) \
-function_arg (& (CUM), (MODE), (TYPE), (NAMED), 1)
-
-/* For an arg passed partly in registers and partly in memory,
-   this is the number of registers used.
-   For args passed entirely in registers or entirely in memory, zero.  */
-
-#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
-function_arg_partial_nregs (& (CUM), (MODE), (TYPE), (NAMED))
-
-/* A C expression that indicates when an argument must be passed by reference.
-   If nonzero for an argument, a copy of that argument is made in memory and a
-   pointer to the argument is passed instead of the argument itself.
-   The pointer is passed in whatever way is appropriate for passing a pointer
-   to that type.  */
-
-#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
-function_arg_pass_by_reference (& (CUM), (MODE), (TYPE), (NAMED))
-
 /* If defined, a C expression which determines whether, and in which direction,
    to pad out an argument with extra space.  The value should be of type
    `enum direction': either `upward' to pad above the argument,
@@ -1698,13 +1451,6 @@ function_arg_padding ((MODE), (TYPE))
   && (GET_MODE_ALIGNMENT (MODE) == 128         \
       || ((TYPE) && TYPE_ALIGN (TYPE) == 128)))        \
  ? 128 : PARM_BOUNDARY)
-\f
-/* Define the information needed to generate branch and scc insns.  This is
-   stored from the compare operation.  Note that we can't use "rtx" here
-   since it hasn't been defined!  */
-
-extern GTY(()) rtx sparc_compare_op0;
-extern GTY(()) rtx sparc_compare_op1;
 
 \f
 /* Generate the special assembly code needed to tell the assembler whatever
@@ -1732,7 +1478,7 @@ extern GTY(()) rtx sparc_compare_op1;
    case of a global register variable occupying more than one register
    we prefix the second and following registers with .gnu.part1. etc.  */
 
-extern char sparc_hard_reg_printed[8];
+extern GTY(()) char sparc_hard_reg_printed[8];
 
 #ifdef HAVE_AS_REGISTER_PSEUDO_OP
 #define ASM_DECLARE_REGISTER_GLOBAL(FILE, DECL, REGNO, NAME)           \
@@ -1772,35 +1518,18 @@ do {                                                                    \
 
 #define EXIT_IGNORE_STACK      \
  (get_frame_size () != 0       \
-  || current_function_calls_alloca || current_function_outgoing_args_size)
+  || cfun->calls_alloca || crtl->outgoing_args_size)
 
 /* Define registers used by the epilogue and return instruction.  */
 #define EPILOGUE_USES(REGNO) ((REGNO) == 31 \
-  || (current_function_calls_eh_return && (REGNO) == 1))
+  || (crtl->calls_eh_return && (REGNO) == 1))
 \f
 /* Length in units of the trampoline for entering a nested function.  */
 
 #define TRAMPOLINE_SIZE (TARGET_ARCH64 ? 32 : 16)
 
 #define TRAMPOLINE_ALIGNMENT 128 /* 16 bytes */
-
-/* Emit RTL insns to initialize the variable parts of a trampoline.
-   FNADDR is an RTX for the address of the function's pure code.
-   CXT is an RTX for the static chain value for the function.  */
-
-#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
-    if (TARGET_ARCH64)                                         \
-      sparc64_initialize_trampoline (TRAMP, FNADDR, CXT);      \
-    else                                                       \
-      sparc_initialize_trampoline (TRAMP, FNADDR, CXT)
 \f
-/* Implement `va_start' for varargs and stdarg.  */
-#define EXPAND_BUILTIN_VA_START(valist, nextarg) \
-  sparc_va_start (valist, nextarg)
-
-/* Implement `va_arg'.  */
-#define EXPAND_BUILTIN_VA_ARG(valist, type) (abort (), NULL_RTX)
-
 /* Generate RTL to flush the register windows so as to make arbitrary frames
    available.  */
 #define SETUP_FRAME_ADDRESSES()                \
@@ -1812,6 +1541,10 @@ do {                                                                     \
 #define DYNAMIC_CHAIN_ADDRESS(frame)   \
   plus_constant (frame, 14 * UNITS_PER_WORD + SPARC_STACK_BIAS)
 
+/* Given an rtx for the frame pointer,
+   return an rtx for the address of the frame.  */
+#define FRAME_ADDR_RTX(frame) plus_constant (frame, 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
    previous frame pointer though by reading a value from the register window
@@ -1821,7 +1554,7 @@ do {                                                                      \
 /* This is the offset of the return address to the true next instruction to be
    executed for the current function.  */
 #define RETURN_ADDR_OFFSET \
-  (8 + 4 * (! TARGET_ARCH64 && current_function_returns_struct))
+  (8 + 4 * (! TARGET_ARCH64 && cfun->returns_struct))
 
 /* The current return address is in %i7.  The return address of anything
    farther back is in the register window save area at [%fp+60].  */
@@ -1965,26 +1698,6 @@ do {                                                                     \
    After reload, it makes no difference, since pseudo regs have
    been eliminated by then.  */
 
-/* Optional extra constraints for this machine.
-
-   'Q' handles floating point constants which can be moved into
-       an integer register with a single sethi instruction.
-
-   'R' handles floating point constants which can be moved into
-       an integer register with a single mov instruction.
-
-   'S' handles floating point constants which can be moved into
-       an integer register using a high/lo_sum sequence.
-
-   'T' handles memory addresses where the alignment is known to
-       be at least 8 bytes.
-
-   `U' handles all pseudo registers or a hard even numbered
-       integer register, needed for ldd/std instructions.
-
-   '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
@@ -1998,15 +1711,6 @@ do {                                                                     \
    or if it is a pseudo reg.  */
 #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.
-
-   Remember to accept pseudo-registers for memory constraints if reload is
-   in progress.  */
-
-#define EXTRA_CONSTRAINT(OP, C) \
-       sparc_extra_constraint_check(OP, C, 0)
-
 #else
 
 /* Nonzero if X is a hard reg that can be used as an index.  */
@@ -2014,9 +1718,6 @@ do {                                                                      \
 /* Nonzero if X is a hard reg that can be used as a base reg.  */
 #define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
 
-#define EXTRA_CONSTRAINT(OP, C) \
-       sparc_extra_constraint_check(OP, C, 1)
-
 #endif
 \f
 /* Should gcc use [%reg+%lo(xx)+offset] addresses?  */
@@ -2027,15 +1728,9 @@ do {                                                                     \
 #define USE_AS_OFFSETABLE_LO10 0
 #endif
 \f
-/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
-   that is a valid memory address for an instruction.
-   The MODE argument is the machine mode for the MEM expression
-   that wants to use this address.
-
-   On SPARC, the actual legitimate addresses must be REG+REG or REG+SMALLINT
-   ordinarily.  This changes a bit when generating PIC.
-
-   If you change this, execute "rm explow.o recog.o reload.o".  */
+/* On SPARC, the actual legitimate addresses must be REG+REG or REG+SMALLINT
+   ordinarily.  This changes a bit when generating PIC.  The details are
+   in sparc.c's implementation of TARGET_LEGITIMATE_ADDRESS_P.  */
 
 #define SYMBOLIC_CONST(X) symbolic_operand (X, VOIDmode)
 
@@ -2057,101 +1752,17 @@ do {                                                                   \
 #define RTX_OK_FOR_OLO10_P(X)                                          \
   (GET_CODE (X) == CONST_INT && INTVAL (X) >= -0x1000 && INTVAL (X) < 0xc00 - 8)
 
-#ifdef REG_OK_STRICT
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)                \
-{                                                      \
-  if (legitimate_address_p (MODE, X, 1))               \
-    goto ADDR;                                         \
-}
-#else
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)                \
-{                                                      \
-  if (legitimate_address_p (MODE, X, 0))               \
-    goto ADDR;                                         \
-}
-#endif
-
-/* 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.
-   This macro is used in only one place: `memory_address' in explow.c.
-
-   OLDX is the address as it was before break_out_memory_refs was called.
-   In some cases it is useful to look at this to decide what needs to be done.
-
-   MODE and WIN are passed so that this macro can use
-   GO_IF_LEGITIMATE_ADDRESS.
-
-   It is always safe for this macro to do nothing.  It exists to recognize
-   opportunities to optimize the output.  */
-
-/* On SPARC, change REG+N into REG+REG, and REG+(X*Y) into REG+REG.  */
-#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN)    \
-{                                              \
-  (X) = legitimize_address (X, OLDX, MODE);    \
-  if (memory_address_p (MODE, X))              \
-    goto WIN;                                  \
-}
-
 /* Try a machine-dependent way of reloading an illegitimate address
    operand.  If we find one, push the reload and jump to WIN.  This
-   macro is used in only one place: `find_reloads_address' in reload.c.
-
-   For SPARC 32, we wish to handle addresses by splitting them into
-   HIGH+LO_SUM pairs, retaining the LO_SUM in the memory reference.
-   This cuts the number of extra insns by one.
-
-   Do nothing when generating PIC code and the address is a
-   symbolic operand or requires a scratch register.  */
-
-#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN)     \
-do {                                                                    \
-  /* Decompose SImode constants into hi+lo_sum.  We do have to                 \
-     rerecognize what we produce, so be careful.  */                   \
-  if (CONSTANT_P (X)                                                   \
-      && (MODE != TFmode || TARGET_ARCH64)                             \
-      && GET_MODE (X) == SImode                                                \
-      && GET_CODE (X) != LO_SUM && GET_CODE (X) != HIGH                        \
-      && ! (flag_pic                                                   \
-           && (symbolic_operand (X, Pmode)                             \
-               || pic_address_needs_scratch (X)))                      \
-      && sparc_cmodel <= CM_MEDLOW)                                    \
-    {                                                                  \
-      X = gen_rtx_LO_SUM (GET_MODE (X),                                        \
-                         gen_rtx_HIGH (GET_MODE (X), X), X);           \
-      push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL,          \
-                   BASE_REG_CLASS, GET_MODE (X), VOIDmode, 0, 0,       \
-                   OPNUM, TYPE);                                       \
-      goto WIN;                                                                \
-    }                                                                  \
-  /* ??? 64-bit reloads.  */                                           \
+   macro is used in only one place: `find_reloads_address' in reload.c.  */
+#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN)       \
+do {                                                                      \
+  int win;                                                                \
+  (X) = sparc_legitimize_reload_address ((X), (MODE), (OPNUM),            \
+                                        (int)(TYPE), (IND_LEVELS), &win); \
+  if (win)                                                                \
+    goto WIN;                                                             \
 } while (0)
 \f
 /* Specify the machine mode that this machine uses
@@ -2176,9 +1787,9 @@ do {                                                                    \
 #define MOVE_MAX 8
 
 /* If a memory-to-memory move would take MOVE_RATIO or more simple
-   move-instruction pairs, we will do a movstr or libcall instead.  */
+   move-instruction pairs, we will do a movmem or libcall instead.  */
 
-#define MOVE_RATIO (optimize_size ? 3 : 8)
+#define MOVE_RATIO(speed) ((speed) ? 8 : 3)
 
 /* Define if operations between registers always perform the operation
    on the full register even if a narrower mode is specified.  */
@@ -2187,7 +1798,7 @@ do {                                                                    \
 /* Define if loading in MODE, an integral mode narrower than BITS_PER_WORD
    will either zero-extend or sign-extend.  The value of this macro should
    be the code that says which one of the two operations is implicitly
-   done, NIL if none.  */
+   done, UNKNOWN if none.  */
 #define LOAD_EXTEND_OP(MODE) ZERO_EXTEND
 
 /* Nonzero if access to memory by bytes is slow and undesirable.
@@ -2204,12 +1815,6 @@ do {                                                                    \
    is done just by pretending it is already truncated.  */
 #define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
 
-/* Specify the machine mode used for addresses.  */
-#define Pmode (TARGET_ARCH64 ? DImode : SImode)
-
-/* Generate calls to memcpy, memcmp and memset.  */
-#define TARGET_MEM_FUNCTIONS
-
 /* 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
@@ -2258,7 +1863,9 @@ do {                                                                    \
     || (GENERAL_OR_I64 (CLASS1) && FP_REG_CLASS_P (CLASS2)) \
     || (CLASS1) == FPCC_REGS || (CLASS2) == FPCC_REGS)         \
    ? ((sparc_cpu == PROCESSOR_ULTRASPARC \
-       || sparc_cpu == PROCESSOR_ULTRASPARC3) ? 12 : 6) : 2)
+       || sparc_cpu == PROCESSOR_ULTRASPARC3 \
+       || sparc_cpu == PROCESSOR_NIAGARA \
+       || sparc_cpu == PROCESSOR_NIAGARA2) ? 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
@@ -2268,25 +1875,25 @@ do {                                                                    \
 
    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.  */
+   mispredicted branch.
 
-#define BRANCH_COST \
+   On Niagara, normal branches insert 3 bubbles into the pipe
+   and annulled branches insert 4 bubbles.
+
+   On Niagara-2, a not-taken branch costs 1 cycle whereas a taken
+   branch costs 6 cycles.  */
+
+#define BRANCH_COST(speed_p, predictable_p) \
        ((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))
+            ? 9 \
+        : (sparc_cpu == PROCESSOR_NIAGARA \
+           ? 4 \
+        : (sparc_cpu == PROCESSOR_NIAGARA2 \
+           ? 5 \
+        : 3))))
 \f
 /* Control the assembler format that we output.  */
 
@@ -2461,16 +2068,22 @@ do {                                                                    \
 #define ASM_OUTPUT_IDENT(FILE, NAME) \
   fprintf (FILE, "%s\"%s\"\n", IDENT_ASM_OP, NAME);
 
-/* Emit a dtp-relative reference to a TLS variable.  */
+/* Prettify the assembly.  */
 
-#ifdef HAVE_AS_TLS
-#define ASM_OUTPUT_DWARF_DTPREL(FILE, SIZE, X) \
-  sparc_output_dwarf_dtprel (FILE, SIZE, X)
-#endif
+extern int sparc_indent_opcode;
+
+#define ASM_OUTPUT_OPCODE(FILE, PTR)   \
+  do {                                 \
+    if (sparc_indent_opcode)           \
+      {                                        \
+       putc (' ', FILE);               \
+       sparc_indent_opcode = 0;        \
+      }                                        \
+  } while (0)
 
 #define PRINT_OPERAND_PUNCT_VALID_P(CHAR) \
-  ((CHAR) == '#' || (CHAR) == '*' || (CHAR) == '^'             \
-   || (CHAR) == '(' || (CHAR) == '_' || (CHAR) == '&')
+  ((CHAR) == '#' || (CHAR) == '*' || (CHAR) == '('             \
+   || (CHAR) == ')' || (CHAR) == '_' || (CHAR) == '&')
 
 /* Print operand X (an rtx) in assembler syntax to file FILE.
    CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
@@ -2496,10 +2109,9 @@ do {                                                                     \
        base = XEXP (addr, 0), index = XEXP (addr, 1);          \
       if (GET_CODE (base) == LO_SUM)                           \
        {                                                       \
-         if (! USE_AS_OFFSETABLE_LO10                          \
-             || TARGET_ARCH32                                  \
-             || TARGET_CM_MEDMID)                              \
-           abort ();                                           \
+         gcc_assert (USE_AS_OFFSETABLE_LO10                    \
+                     && TARGET_ARCH64                          \
+                     && ! TARGET_CM_MEDMID);                   \
          output_operand (XEXP (base, 0), 0);                   \
          fputs ("+%lo(", FILE);                                \
          output_address (XEXP (base, 1));                      \
@@ -2513,9 +2125,10 @@ do {                                                                     \
          else if (GET_CODE (index) == REG)                     \
            fprintf (FILE, "+%s", reg_names[REGNO (index)]);    \
          else if (GET_CODE (index) == SYMBOL_REF               \
+                  || GET_CODE (index) == LABEL_REF             \
                   || GET_CODE (index) == CONST)                \
            fputc ('+', FILE), output_addr_const (FILE, index); \
-         else abort ();                                        \
+         else gcc_unreachable ();                              \
        }                                                       \
     }                                                          \
   else if (GET_CODE (addr) == MINUS                            \
@@ -2557,68 +2170,19 @@ do {                                                                    \
     }                                                          \
 }
 
+/* TLS support defaulting to original Sun flavor.  GNU extensions
+   must be activated in separate configuration files.  */
 #ifdef HAVE_AS_TLS
 #define TARGET_TLS 1
 #else
 #define TARGET_TLS 0
 #endif
+
 #define TARGET_SUN_TLS TARGET_TLS
 #define TARGET_GNU_TLS 0
 
-/* Define the codes that are matched by predicates in sparc.c.  */
-
-#define PREDICATE_CODES                                                        \
-{"reg_or_0_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}},          \
-{"const1_operand", {CONST_INT}},                                       \
-{"fp_zero_operand", {CONST_DOUBLE}},                                   \
-{"fp_register_operand", {SUBREG, REG}},                                        \
-{"intreg_operand", {SUBREG, REG}},                                     \
-{"fcc_reg_operand", {REG}},                                            \
-{"fcc0_reg_operand", {REG}},                                           \
-{"icc_or_fcc_reg_operand", {REG}},                                     \
-{"call_operand", {MEM}},                                               \
-{"call_operand_address", {SYMBOL_REF, LABEL_REF, CONST, CONST_DOUBLE,  \
-       SUBREG, REG, PLUS, LO_SUM, CONST_INT}},                         \
-{"symbolic_operand", {SYMBOL_REF, LABEL_REF, CONST}},                  \
-{"symbolic_memory_operand", {SUBREG, MEM}},                            \
-{"label_ref_operand", {LABEL_REF}},                                    \
-{"sp64_medium_pic_operand", {CONST}},                                  \
-{"data_segment_operand", {SYMBOL_REF, PLUS, CONST}},                   \
-{"text_segment_operand", {LABEL_REF, SYMBOL_REF, PLUS, CONST}},                \
-{"reg_or_nonsymb_mem_operand", {SUBREG, REG, MEM}},                    \
-{"splittable_symbolic_memory_operand", {MEM}},                         \
-{"splittable_immediate_memory_operand", {MEM}},                                \
-{"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}},                                       \
-{"cc_arithopn", {AND, IOR}},                                           \
-{"arith_operand", {SUBREG, REG, CONST_INT}},                           \
-{"arith_add_operand", {SUBREG, REG, CONST_INT}},                       \
-{"arith11_operand", {SUBREG, REG, CONST_INT}},                         \
-{"arith10_operand", {SUBREG, REG, CONST_INT}},                         \
-{"arith_double_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}},      \
-{"arith_double_add_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}},  \
-{"arith11_double_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}},    \
-{"arith10_double_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}},    \
-{"small_int", {CONST_INT}},                                            \
-{"small_int_or_double", {CONST_INT, CONST_DOUBLE}},                    \
-{"uns_small_int", {CONST_INT}},                                                \
-{"uns_arith_operand", {SUBREG, REG, CONST_INT}},                       \
-{"clobbered_register", {REG}},                                         \
-{"input_operand", {SUBREG, REG, CONST_INT, MEM, CONST}},               \
-{"compare_operand", {SUBREG, REG, ZERO_EXTRACT}},                      \
-{"const64_operand", {CONST_INT, CONST_DOUBLE}},                                \
-{"const64_high_operand", {CONST_INT, CONST_DOUBLE}},                   \
-{"tgd_symbolic_operand", {SYMBOL_REF}},                                        \
-{"tld_symbolic_operand", {SYMBOL_REF}},                                        \
-{"tie_symbolic_operand", {SYMBOL_REF}},                                        \
-{"tle_symbolic_operand", {SYMBOL_REF}},
-
 /* The number of Pmode words for the setjmp buffer.  */
 #define JMP_BUF_SIZE 12
 
-#define DONT_ACCESS_GBLS_AFTER_EPILOGUE (flag_pic)
+/* We use gcc _mcount for profiling.  */
+#define NO_PROFILE_COUNTERS 0