OSDN Git Service

* doc/invoke.texi: Add cpu_type power6.
[pf3gnuchains/gcc-fork.git] / gcc / config / rs6000 / rs6000.h
index 3b14ce6..3465992 100644 (file)
@@ -1,6 +1,7 @@
 /* Definitions of target machine for GNU compiler, for IBM RS/6000.
    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+   2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
    Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
 
    This file is part of GCC.
@@ -17,8 +18,8 @@
 
    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.  */
+   Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
 
 /* Note that some other tm.h files include this one and then override
    many of the definitions.  */
 #define TARGET_AIX 0
 #endif
 
+/* Control whether function entry points use a "dot" symbol when
+   ABI_AIX.  */
+#define DOT_SYMBOLS 1
+
 /* Default string to use for cpu if not specified.  */
 #ifndef TARGET_CPU_DEFAULT
 #define TARGET_CPU_DEFAULT ((char *)0)
 #endif
 
+/* If configured for PPC405, support PPC405CR Erratum77.  */
+#ifdef CONFIG_PPC405CR
+#define PPC405_ERRATUM77 (rs6000_cpu == PROCESSOR_PPC405)
+#else
+#define PPC405_ERRATUM77 0
+#endif
+
 /* Common ASM definitions used by ASM_SPEC among the various targets
    for handling -mcpu=xxx switches.  */
 #define ASM_CPU_SPEC \
 "%{!mcpu*: \
   %{mpower: %{!mpower2: -mpwr}} \
   %{mpower2: -mpwrx} \
-  %{mpowerpc*: -mppc} \
+  %{mpowerpc64*: -mppc64} \
+  %{!mpowerpc64*: %{mpowerpc*: -mppc}} \
   %{mno-power: %{!mpowerpc*: -mcom}} \
-  %{!mno-power: %{!mpower2: %(asm_default)}}} \
+  %{!mno-power: %{!mpower*: %(asm_default)}}} \
 %{mcpu=common: -mcom} \
 %{mcpu=power: -mpwr} \
 %{mcpu=power2: -mpwrx} \
-%{mcpu=power3: -m604} \
+%{mcpu=power3: -mppc64} \
 %{mcpu=power4: -mpower4} \
+%{mcpu=power5: -mpower4} \
+%{mcpu=power5+: -mpower4} \
+%{mcpu=power6: -mpower4 -maltivec} \
 %{mcpu=powerpc: -mppc} \
 %{mcpu=rios: -mpwr} \
 %{mcpu=rios1: -mpwr} \
 %{mcpu=rios2: -mpwrx} \
 %{mcpu=rsc: -mpwr} \
 %{mcpu=rsc1: -mpwr} \
+%{mcpu=rs64a: -mppc64} \
 %{mcpu=401: -mppc} \
 %{mcpu=403: -m403} \
 %{mcpu=405: -m405} \
 %{mcpu=ec603e: -mppc} \
 %{mcpu=604: -mppc} \
 %{mcpu=604e: -mppc} \
-%{mcpu=620: -mppc} \
-%{mcpu=630: -m604} \
+%{mcpu=620: -mppc64} \
+%{mcpu=630: -mppc64} \
 %{mcpu=740: -mppc} \
-%{mcpu=7400: -mppc} \
-%{mcpu=7450: -mppc} \
-%{mcpu=G4: -mppc} \
 %{mcpu=750: -mppc} \
 %{mcpu=G3: -mppc} \
+%{mcpu=7400: -mppc -maltivec} \
+%{mcpu=7450: -mppc -maltivec} \
+%{mcpu=G4: -mppc -maltivec} \
 %{mcpu=801: -mppc} \
 %{mcpu=821: -mppc} \
 %{mcpu=823: -mppc} \
 %{mcpu=860: -mppc} \
-%{mcpu=970: -mpower4} \
-%{mcpu=G5: -mpower4} \
+%{mcpu=970: -mpower4 -maltivec} \
+%{mcpu=G5: -mpower4 -maltivec} \
 %{mcpu=8540: -me500} \
-%{maltivec: -maltivec}"
+%{maltivec: -maltivec} \
+-many"
 
 #define CPP_DEFAULT_SPEC ""
 
 
 /* Architecture type.  */
 
-extern int target_flags;
-
-/* Use POWER architecture instructions and MQ register.  */
-#define MASK_POWER             0x00000001
-
-/* Use POWER2 extensions to POWER architecture.  */
-#define MASK_POWER2            0x00000002
-
-/* Use PowerPC architecture instructions.  */
-#define MASK_POWERPC           0x00000004
-
-/* Use PowerPC General Purpose group optional instructions, e.g. fsqrt.  */
-#define MASK_PPC_GPOPT         0x00000008
-
-/* Use PowerPC Graphics group optional instructions, e.g. fsel.  */
-#define MASK_PPC_GFXOPT                0x00000010
-
-/* Use PowerPC-64 architecture instructions.  */
-#define MASK_POWERPC64         0x00000020
-
-/* Use revised mnemonic names defined for PowerPC architecture.  */
-#define MASK_NEW_MNEMONICS     0x00000040
-
-/* Disable placing fp constants in the TOC; can be turned on when the
-   TOC overflows.  */
-#define MASK_NO_FP_IN_TOC      0x00000080
-
-/* Disable placing symbol+offset constants in the TOC; can be turned on when
-   the TOC overflows.  */
-#define MASK_NO_SUM_IN_TOC     0x00000100
-
-/* Output only one TOC entry per module.  Normally linking fails if
-   there are more than 16K unique variables/constants in an executable.  With
-   this option, linking fails only if there are more than 16K modules, or
-   if there are more than 16K unique variables/constant in a single module.
+/* Define TARGET_MFCRF if the target assembler does not support the
+   optional field operand for mfcr.  */
 
-   This is at the cost of having 2 extra loads and one extra store per
-   function, and one less allocable register.  */
-#define MASK_MINIMAL_TOC       0x00000200
-
-/* Nonzero for the 64bit model: longs and pointers are 64 bits.  */
-#define MASK_64BIT             0x00000400
-
-/* Disable use of FPRs.  */
-#define MASK_SOFT_FLOAT                0x00000800
-
-/* Enable load/store multiple, even on PowerPC */
-#define MASK_MULTIPLE          0x00001000
-
-/* Use string instructions for block moves */
-#define MASK_STRING            0x00002000
-
-/* Disable update form of load/store */
-#define MASK_NO_UPDATE         0x00004000
-
-/* Disable fused multiply/add operations */
-#define MASK_NO_FUSED_MADD     0x00008000
-
-/* Nonzero if we need to schedule the prolog and epilog.  */
-#define MASK_SCHED_PROLOG      0x00010000
-
-/* Use AltiVec instructions.  */
-#define MASK_ALTIVEC           0x00020000
-
-/* Return small structures in memory (as the AIX ABI requires).  */
-#define MASK_AIX_STRUCT_RET    0x00040000
-
-/* Use single field mfcr instruction.  */
-#define MASK_MFCRF             0x00080000
+#ifndef HAVE_AS_MFCRF
+#undef  TARGET_MFCRF
+#define TARGET_MFCRF 0
+#endif
 
-/* The only remaining free bits are 0x00700000. sysv4.h uses
-   0x00800000 -> 0x40000000, and 0x80000000 is not available
-   because target_flags is signed.  */
+/* Define TARGET_POPCNTB if the target assembler does not support the
+   popcount byte instruction.  */
 
-#define TARGET_POWER           (target_flags & MASK_POWER)
-#define TARGET_POWER2          (target_flags & MASK_POWER2)
-#define TARGET_POWERPC         (target_flags & MASK_POWERPC)
-#define TARGET_PPC_GPOPT       (target_flags & MASK_PPC_GPOPT)
-#define TARGET_PPC_GFXOPT      (target_flags & MASK_PPC_GFXOPT)
-#define TARGET_NEW_MNEMONICS   (target_flags & MASK_NEW_MNEMONICS)
-#define TARGET_NO_FP_IN_TOC    (target_flags & MASK_NO_FP_IN_TOC)
-#define TARGET_NO_SUM_IN_TOC   (target_flags & MASK_NO_SUM_IN_TOC)
-#define TARGET_MINIMAL_TOC     (target_flags & MASK_MINIMAL_TOC)
-#define TARGET_64BIT           (target_flags & MASK_64BIT)
-#define TARGET_SOFT_FLOAT      (target_flags & MASK_SOFT_FLOAT)
-#define TARGET_MULTIPLE                (target_flags & MASK_MULTIPLE)
-#define TARGET_STRING          (target_flags & MASK_STRING)
-#define TARGET_NO_UPDATE       (target_flags & MASK_NO_UPDATE)
-#define TARGET_NO_FUSED_MADD   (target_flags & MASK_NO_FUSED_MADD)
-#define TARGET_SCHED_PROLOG    (target_flags & MASK_SCHED_PROLOG)
-#define TARGET_ALTIVEC         (target_flags & MASK_ALTIVEC)
-#define TARGET_AIX_STRUCT_RET  (target_flags & MASK_AIX_STRUCT_RET)
+#ifndef HAVE_AS_POPCNTB
+#undef  TARGET_POPCNTB
+#define TARGET_POPCNTB 0
+#endif
 
-/* Define TARGET_MFCRF if the target assembler supports the optional
-   field operand for mfcr and the target processor supports the
-   instruction.  */
+/* Define TARGET_FPRND if the target assembler does not support the
+   fp rounding instructions.  */
 
-#ifdef HAVE_AS_MFCRF
-#define TARGET_MFCRF           (target_flags & MASK_MFCRF)
-#else
-#define TARGET_MFCRF 0
+#ifndef HAVE_AS_FPRND
+#undef  TARGET_FPRND
+#define TARGET_FPRND 0
 #endif
 
+#ifndef TARGET_SECURE_PLT
+#define TARGET_SECURE_PLT 0
+#endif
 
 #define TARGET_32BIT           (! TARGET_64BIT)
-#define TARGET_HARD_FLOAT      (! TARGET_SOFT_FLOAT)
-#define TARGET_UPDATE          (! TARGET_NO_UPDATE)
-#define TARGET_FUSED_MADD      (! TARGET_NO_FUSED_MADD)
 
 #ifndef HAVE_AS_TLS
 #define HAVE_AS_TLS 0
 #endif
 
+/* Return 1 for a symbol ref for a thread-local storage symbol.  */
+#define RS6000_SYMBOL_REF_TLS_P(RTX) \
+  (GET_CODE (RTX) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (RTX) != 0)
+
 #ifdef IN_LIBGCC2
 /* For libgcc2 we make sure this is a compile time constant */
 #if defined (__64BIT__) || defined (__powerpc64__)
+#undef TARGET_POWERPC64
 #define TARGET_POWERPC64       1
 #else
+#undef TARGET_POWERPC64
 #define TARGET_POWERPC64       0
 #endif
 #else
-#define TARGET_POWERPC64       (target_flags & MASK_POWERPC64)
+    /* The option machinery will define this.  */
 #endif
 
-#define TARGET_XL_CALL 0
-
-/* Run-time compilation parameters selecting different hardware subsets.
-
-   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                                                        \
- {{"power",            MASK_POWER  | MASK_MULTIPLE | MASK_STRING,      \
-                       N_("Use POWER instruction set")},               \
-  {"power2",           (MASK_POWER | MASK_MULTIPLE | MASK_STRING       \
-                        | MASK_POWER2),                                \
-                       N_("Use POWER2 instruction set")},              \
-  {"no-power2",                - MASK_POWER2,                                  \
-                       N_("Do not use POWER2 instruction set")},       \
-  {"no-power",         - (MASK_POWER | MASK_POWER2 | MASK_MULTIPLE     \
-                          | MASK_STRING),                              \
-                       N_("Do not use POWER instruction set")},        \
-  {"powerpc",          MASK_POWERPC,                                   \
-                       N_("Use PowerPC instruction set")},             \
-  {"no-powerpc",       - (MASK_POWERPC | MASK_PPC_GPOPT                \
-                          | MASK_PPC_GFXOPT | MASK_POWERPC64),         \
-                       N_("Do not use PowerPC instruction set")},      \
-  {"powerpc-gpopt",    MASK_POWERPC | MASK_PPC_GPOPT,                  \
-                       N_("Use PowerPC General Purpose group optional instructions")},\
-  {"no-powerpc-gpopt", - MASK_PPC_GPOPT,                               \
-                       N_("Do not use PowerPC General Purpose group optional instructions")},\
-  {"powerpc-gfxopt",   MASK_POWERPC | MASK_PPC_GFXOPT,                 \
-                       N_("Use PowerPC Graphics group optional instructions")},\
-  {"no-powerpc-gfxopt",        - MASK_PPC_GFXOPT,                              \
-                       N_("Do not use PowerPC Graphics group optional instructions")},\
-  {"powerpc64",                MASK_POWERPC64,                                 \
-                       N_("Use PowerPC-64 instruction set")},          \
-  {"no-powerpc64",     - MASK_POWERPC64,                               \
-                       N_("Do not use PowerPC-64 instruction set")},   \
-  {"altivec",          MASK_ALTIVEC ,                                  \
-                       N_("Use AltiVec instructions")},                \
-  {"no-altivec",       - MASK_ALTIVEC ,                                        \
-                       N_("Do not use AltiVec instructions")}, \
-  {"new-mnemonics",    MASK_NEW_MNEMONICS,                             \
-                       N_("Use new mnemonics for PowerPC architecture")},\
-  {"old-mnemonics",    -MASK_NEW_MNEMONICS,                            \
-                       N_("Use old mnemonics for PowerPC architecture")},\
-  {"full-toc",         - (MASK_NO_FP_IN_TOC | MASK_NO_SUM_IN_TOC       \
-                          | MASK_MINIMAL_TOC),                         \
-                       N_("Put everything in the regular TOC")},       \
-  {"fp-in-toc",                - MASK_NO_FP_IN_TOC,                            \
-                       N_("Place floating point constants in TOC")},   \
-  {"no-fp-in-toc",     MASK_NO_FP_IN_TOC,                              \
-                       N_("Do not place floating point constants in TOC")},\
-  {"sum-in-toc",       - MASK_NO_SUM_IN_TOC,                           \
-                       N_("Place symbol+offset constants in TOC")},    \
-  {"no-sum-in-toc",    MASK_NO_SUM_IN_TOC,                             \
-                       N_("Do not place symbol+offset constants in TOC")},\
-  {"minimal-toc",      MASK_MINIMAL_TOC,                               \
-                       "Use only one TOC entry per procedure"},        \
-  {"minimal-toc",      - (MASK_NO_FP_IN_TOC | MASK_NO_SUM_IN_TOC),     \
-                       ""},                                            \
-  {"no-minimal-toc",   - MASK_MINIMAL_TOC,                             \
-                       N_("Place variable addresses in the regular TOC")},\
-  {"hard-float",       - MASK_SOFT_FLOAT,                              \
-                       N_("Use hardware floating point")},             \
-  {"soft-float",       MASK_SOFT_FLOAT,                                \
-                       N_("Do not use hardware floating point")},      \
-  {"multiple",         MASK_MULTIPLE,                                  \
-                       N_("Generate load/store multiple instructions")},       \
-  {"no-multiple",      - MASK_MULTIPLE,                                \
-                       N_("Do not generate load/store multiple instructions")},\
-  {"string",           MASK_STRING,                                    \
-                       N_("Generate string instructions for block moves")},\
-  {"no-string",                - MASK_STRING,                                  \
-                       N_("Do not generate string instructions for block moves")},\
-  {"update",           - MASK_NO_UPDATE,                               \
-                       N_("Generate load/store with update instructions")},\
-  {"no-update",                MASK_NO_UPDATE,                                 \
-                       N_("Do not generate load/store with update instructions")},\
-  {"fused-madd",       - MASK_NO_FUSED_MADD,                           \
-                       N_("Generate fused multiply/add instructions")},\
-  {"no-fused-madd",    MASK_NO_FUSED_MADD,                             \
-                       N_("Do not generate fused multiply/add instructions")},\
-  {"sched-prolog",      MASK_SCHED_PROLOG,                              \
-                       ""},                                            \
-  {"no-sched-prolog",   -MASK_SCHED_PROLOG,                             \
-                       N_("Do not schedule the start and end of the procedure")},\
-  {"sched-epilog",      MASK_SCHED_PROLOG,                              \
-                       ""},                                            \
-  {"no-sched-epilog",   -MASK_SCHED_PROLOG,                             \
-                       ""},                                            \
-  {"aix-struct-return",        MASK_AIX_STRUCT_RET,                            \
-                       N_("Return all structures in memory (AIX default)")},\
-  {"svr4-struct-return", - MASK_AIX_STRUCT_RET,                                \
-                       N_("Return small structures in registers (SVR4 default)")},\
-  {"no-aix-struct-return", - MASK_AIX_STRUCT_RET,                      \
-                       ""},                                            \
-  {"no-svr4-struct-return", MASK_AIX_STRUCT_RET,                       \
-                       ""},                                            \
-  {"mfcrf",            MASK_MFCRF,                                     \
-                       N_("Generate single field mfcr instruction")},  \
-  {"no-mfcrf",         - MASK_MFCRF,                                   \
-                       N_("Do not generate single field mfcr instruction")},\
-  SUBTARGET_SWITCHES                                                   \
-  {"",                 TARGET_DEFAULT | MASK_SCHED_PROLOG,             \
-                       ""}}
-
 #define TARGET_DEFAULT (MASK_POWER | MASK_MULTIPLE | MASK_STRING)
 
-/* This is meant to be redefined in the host dependent files */
-#define SUBTARGET_SWITCHES
-
 /* Processor type.  Order must match cpu attribute in MD file.  */
 enum processor_type
  {
@@ -376,7 +211,8 @@ enum processor_type
    PROCESSOR_PPC7400,
    PROCESSOR_PPC7450,
    PROCESSOR_PPC8540,
-   PROCESSOR_POWER4
+   PROCESSOR_POWER4,
+   PROCESSOR_POWER5
 };
 
 extern enum processor_type rs6000_cpu;
@@ -423,43 +259,6 @@ enum group_termination
     previous_group
   };
 
-/* This is meant to be overridden in target specific files.  */
-#define        SUBTARGET_OPTIONS
-
-#define TARGET_OPTIONS                                                 \
-{                                                                      \
-   {"cpu=",  &rs6000_select[1].string,                                 \
-    N_("Use features of and schedule code for given CPU"), 0},         \
-   {"tune=", &rs6000_select[2].string,                                 \
-    N_("Schedule code for given CPU"), 0},                             \
-   {"debug=", &rs6000_debug_name, N_("Enable debug output"), 0},       \
-   {"traceback=", &rs6000_traceback_name,                              \
-    N_("Select full, part, or no traceback table"), 0},                        \
-   {"abi=", &rs6000_abi_string, N_("Specify ABI to use"), 0},          \
-   {"long-double-", &rs6000_long_double_size_string,                   \
-    N_("Specify size of long double (64 or 128 bits)"), 0},            \
-   {"isel=", &rs6000_isel_string,                                       \
-    N_("Specify yes/no if isel instructions should be generated"), 0},  \
-   {"spe=", &rs6000_spe_string,                                         \
-    N_("Specify yes/no if SPE SIMD instructions should be generated"), 0},\
-   {"float-gprs=", &rs6000_float_gprs_string,                           \
-    N_("Specify yes/no if using floating point in the GPRs"), 0},       \
-   {"vrsave=", &rs6000_altivec_vrsave_string,                           \
-    N_("Specify yes/no if VRSAVE instructions should be generated for AltiVec"), 0}, \
-   {"longcall", &rs6000_longcall_switch,                               \
-    N_("Avoid all range limits on call instructions"), 0},             \
-   {"no-longcall", &rs6000_longcall_switch, "", 0},                    \
-   {"sched-costly-dep=", &rs6000_sched_costly_dep_str,                  \
-    N_("Determine which dependences between insns are considered costly"), 0}, \
-   {"insert-sched-nops=", &rs6000_sched_insert_nops_str,                \
-    N_("Specify which post scheduling nop insertion scheme to apply"), 0}, \
-   {"align-", &rs6000_alignment_string,                                        \
-    N_("Specify alignment of structure fields default/natural"), 0},   \
-   {"prioritize-restricted-insns=", &rs6000_sched_restricted_insns_priority_str, \
-    N_("Specify scheduling priority for dispatch slot restricted insns"), 0}, \
-   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.
@@ -483,7 +282,6 @@ extern struct rs6000_cpu_select rs6000_select[];
 
 /* Debug support */
 extern const char *rs6000_debug_name;  /* Name for -mdebug-xxxx option */
-extern const char *rs6000_abi_string;  /* for -mabi={sysv,darwin,eabi,aix,altivec} */
 extern int rs6000_debug_stack;         /* debug stack applications */
 extern int rs6000_debug_arg;           /* debug argument handling */
 
@@ -494,26 +292,12 @@ extern const char *rs6000_traceback_name; /* Type of traceback table.  */
 
 /* These are separate from target_flags because we've run out of bits
    there.  */
-extern const char *rs6000_long_double_size_string;
 extern int rs6000_long_double_type_size;
+extern int rs6000_ieeequad;
 extern int rs6000_altivec_abi;
 extern int rs6000_spe_abi;
-extern int rs6000_isel;
-extern int rs6000_spe;
 extern int rs6000_float_gprs;
-extern const char *rs6000_float_gprs_string;
-extern const char *rs6000_isel_string;
-extern const char *rs6000_spe_string;
-extern const char *rs6000_altivec_vrsave_string;
-extern int rs6000_altivec_vrsave;
-extern const char *rs6000_longcall_switch;
-extern int rs6000_default_long_calls;
-extern const char* rs6000_alignment_string;
 extern int rs6000_alignment_flags;
-extern const char *rs6000_sched_restricted_insns_priority_str;
-extern int rs6000_sched_restricted_insns_priority;
-extern const char *rs6000_sched_costly_dep_str;
-extern enum rs6000_dependence_cost rs6000_sched_costly_dep;
 extern const char *rs6000_sched_insert_nops_str;
 extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
 
@@ -525,7 +309,7 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
    Override the macro definitions when compiling libobjc to avoid undefined
    reference to rs6000_alignment_flags due to library's use of GCC alignment
    macros which use the macros below.  */
-   
+
 #ifndef IN_TARGET_LIBS
 #define MASK_ALIGN_POWER   0x00000000
 #define MASK_ALIGN_NATURAL 0x00000001
@@ -534,28 +318,17 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
 #define TARGET_ALIGN_NATURAL 0
 #endif
 
-/* Set a default value for DEFAULT_SCHED_COSTLY_DEP used by target hook
-   is_costly_dependence.  */ 
-#define DEFAULT_SCHED_COSTLY_DEP                           \
-  (rs6000_cpu == PROCESSOR_POWER4 ? store_to_load_dep_costly : no_dep_costly)
-
-/* Define if the target has restricted dispatch slot instructions.  */
-#define DEFAULT_RESTRICTED_INSNS_PRIORITY (rs6000_cpu == PROCESSOR_POWER4 ? 1 : 0)
-
-/* Set a default value for post scheduling nop insertion scheme
-   (used by taget hook sched_finish).  */
-#define DEFAULT_SCHED_FINISH_NOP_INSERTION_SCHEME          \
-  (rs6000_cpu == PROCESSOR_POWER4 ? sched_finish_regroup_exact : sched_finish_none)
-
 #define TARGET_LONG_DOUBLE_128 (rs6000_long_double_type_size == 128)
+#define TARGET_IEEEQUAD rs6000_ieeequad
 #define TARGET_ALTIVEC_ABI rs6000_altivec_abi
-#define TARGET_ALTIVEC_VRSAVE rs6000_altivec_vrsave
 
 #define TARGET_SPE_ABI 0
 #define TARGET_SPE 0
 #define TARGET_E500 0
 #define TARGET_ISEL 0
 #define TARGET_FPRS 1
+#define TARGET_E500_SINGLE 0
+#define TARGET_E500_DOUBLE 0
 
 /* Sometimes certain combinations of command options do not make sense
    on a particular target machine.  You can define a macro
@@ -579,6 +352,7 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
 /* Target pragma.  */
 #define REGISTER_TARGET_PRAGMAS() do {                         \
   c_register_pragma (0, "longcall", rs6000_pragma_longcall);   \
+  targetm.resolve_overloaded_builtin = altivec_resolve_overloaded_builtin; \
 } while (0)
 
 /* Target #defines.  */
@@ -674,7 +448,6 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
    target machine.  If you don't define this, the default is one
    word.  */
 #define LONG_TYPE_SIZE (TARGET_32BIT ? 32 : 64)
-#define MAX_LONG_TYPE_SIZE 64
 
 /* A C expression for the size in bits of the type `long long' on the
    target machine.  If you don't define this, the default is two
@@ -696,9 +469,6 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
    words.  */
 #define LONG_DOUBLE_TYPE_SIZE rs6000_long_double_type_size
 
-/* Constant which presents upper bound of the above value.  */
-#define MAX_LONG_DOUBLE_TYPE_SIZE 128
-
 /* Define this to set long double type size to use in libgcc2.c, which can
    not depend on target_flags.  */
 #ifdef __LONG_DOUBLE_128__
@@ -718,7 +488,8 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
 #define PARM_BOUNDARY (TARGET_32BIT ? 32 : 64)
 
 /* Boundary (in *bits*) on which stack pointer should be aligned.  */
-#define STACK_BOUNDARY ((TARGET_32BIT && !TARGET_ALTIVEC_ABI) ? 64 : 128)
+#define STACK_BOUNDARY \
+  ((TARGET_32BIT && !TARGET_ALTIVEC && !TARGET_ALTIVEC_ABI) ? 64 : 128)
 
 /* Allocation boundary (in *bits*) for the code of a function.  */
 #define FUNCTION_BOUNDARY 32
@@ -731,6 +502,7 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
    that the object would ordinarily have.  */
 #define LOCAL_ALIGNMENT(TYPE, ALIGN)                           \
   ((TARGET_ALTIVEC && TREE_CODE (TYPE) == VECTOR_TYPE) ? 128 : \
+    (TARGET_E500_DOUBLE && TYPE_MODE (TYPE) == DFmode) ? 64 : \
     (TARGET_SPE && TREE_CODE (TYPE) == VECTOR_TYPE) ? 64 : ALIGN)
 
 /* Alignment of field after `int : 0' in a structure.  */
@@ -747,9 +519,13 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
    store_bit_field() will force (subreg:DI (reg:V2SI x))'s to the
    back-end.  Because a single GPR can hold a V2SI, but not a DI, the
    best thing to do is set structs to BLKmode and avoid Severe Tire
-   Damage.  */
+   Damage.
+
+   On e500 v2, DF and DI modes suffer from the same anomaly.  DF can
+   fit into 1, whereas DI still needs two.  */
 #define MEMBER_TYPE_FORCES_BLK(FIELD, MODE) \
-  (TARGET_SPE && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE)
+  ((TARGET_SPE && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE) \
+   || (TARGET_E500_DOUBLE && (MODE) == DFmode))
 
 /* A bit-field declared as `int' forces `int' alignment for the struct.  */
 #define PCC_BITFIELD_TYPE_MATTERS 1
@@ -763,9 +539,11 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
    : (ALIGN))
 
 /* Make arrays of chars word-aligned for the same reasons.
-   Align vectors to 128 bits.  */
+   Align vectors to 128 bits.  Align SPE vectors and E500 v2 doubles to
+   64 bits.  */
 #define DATA_ALIGNMENT(TYPE, ALIGN)            \
   (TREE_CODE (TYPE) == VECTOR_TYPE ? (TARGET_SPE_ABI ? 64 : 128)       \
+   : (TARGET_E500_DOUBLE && TYPE_MODE (TYPE) == DFmode) ? 64 \
    : TREE_CODE (TYPE) == ARRAY_TYPE            \
    && TYPE_MODE (TREE_TYPE (TYPE)) == QImode   \
    && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
@@ -804,26 +582,37 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
    We also create a pseudo register for float/int conversions, that will
    really represent the memory location used.  It is represented here as
    a register, in order to work around problems in allocating stack storage
-   in inline functions.  */
+   in inline functions.
+
+   Another pseudo (not included in DWARF_FRAME_REGISTERS) is soft frame
+   pointer, which is eventually eliminated in favor of SP or FP.  */
 
-#define FIRST_PSEUDO_REGISTER 113
+#define FIRST_PSEUDO_REGISTER 114
 
 /* This must be included for pre gcc 3.0 glibc compatibility.  */
 #define PRE_GCC3_DWARF_FRAME_REGISTERS 77
 
-/* Add 32 dwarf columns for synthetic SPE registers.  The SPE
-   synthetic registers are 113 through 145.  */
-#define DWARF_FRAME_REGISTERS (FIRST_PSEUDO_REGISTER + 32)
+/* Add 32 dwarf columns for synthetic SPE registers.  */
+#define DWARF_FRAME_REGISTERS ((FIRST_PSEUDO_REGISTER - 1) + 32)
 
-/* The SPE has an additional 32 synthetic registers starting at 1200.
-   We must map them here to sane values in the unwinder to avoid a
-   huge hole in the unwind tables.
+/* The SPE has an additional 32 synthetic registers, with DWARF debug
+   info numbering for these registers starting at 1200.  While eh_frame
+   register numbering need not be the same as the debug info numbering,
+   we choose to number these regs for eh_frame at 1200 too.  This allows
+   future versions of the rs6000 backend to add hard registers and
+   continue to use the gcc hard register numbering for eh_frame.  If the
+   extra SPE registers in eh_frame were numbered starting from the
+   current value of FIRST_PSEUDO_REGISTER, then if FIRST_PSEUDO_REGISTER
+   changed we'd need to introduce a mapping in DWARF_FRAME_REGNUM to
+   avoid invalidating older SPE eh_frame info.
 
-   FIXME: the AltiVec ABI has AltiVec registers being 1124-1155, and
-   the VRSAVE SPR (SPR256) assigned to register 356.  When AltiVec EH
-   is verified to be working, this macro should be changed
-   accordingly.  */
-#define DWARF_REG_TO_UNWIND_COLUMN(r) ((r) > 1200 ? ((r) - 1200 + 113) : (r))
+   We must map them here to avoid huge unwinder tables mostly consisting
+   of unused space.  */
+#define DWARF_REG_TO_UNWIND_COLUMN(r) \
+  ((r) > 1200 ? ((r) - 1200 + FIRST_PSEUDO_REGISTER - 1) : (r))
+
+/* Use gcc hard register numbering for eh_frame.  */
+#define DWARF_FRAME_REGNUM(REGNO) (REGNO)
 
 /* 1 for registers that have pervasive standard uses
    and are not available for the register allocator.
@@ -845,7 +634,7 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
    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                                                   \
-   , 1, 1                                          \
+   , 1, 1, 1                                       \
 }
 
 /* 1 for registers not available across function calls.
@@ -865,7 +654,7 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
    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                                                   \
-   , 1, 1                                          \
+   , 1, 1, 1                                       \
 }
 
 /* Like `CALL_USED_REGISTERS' except this macro doesn't require that
@@ -873,7 +662,7 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
    (`CALL_USED_REGISTERS' must be a superset of `FIXED_REGISTERS').
    This macro is optional.  If not specified, it defaults to the value
    of `CALL_USED_REGISTERS'.  */
-                      
+
 #define CALL_REALLY_USED_REGISTERS  \
   {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, FIXED_R13, 0, 0, \
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
@@ -884,7 +673,7 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
    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                                       \
 }
 
 #define MQ_REGNO     64
@@ -903,6 +692,10 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
 #define SPE_ACC_REGNO          111
 #define SPEFSCR_REGNO          112
 
+#define FIRST_SAVED_ALTIVEC_REGNO (FIRST_ALTIVEC_REGNO+20)
+#define FIRST_SAVED_FP_REGNO    (14+32)
+#define FIRST_SAVED_GP_REGNO 13
+
 /* List the order in which to allocate registers.  Each register must be
    listed once, even those in FIXED_REGISTERS.
 
@@ -910,31 +703,31 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
        fp0             (not saved or used for anything)
        fp13 - fp2      (not saved; incoming fp arg registers)
        fp1             (not saved; return value)
-       fp31 - fp14     (saved; order given to save least number)
+       fp31 - fp14     (saved; order given to save least number)
        cr7, cr6        (not saved or special)
        cr1             (not saved, but used for FP operations)
        cr0             (not saved, but used for arithmetic operations)
        cr4, cr3, cr2   (saved)
-        r0             (not saved; cannot be base reg)
+       r0              (not saved; cannot be base reg)
        r9              (not saved; best for TImode)
        r11, r10, r8-r4 (not saved; highest used first to make less conflict)
-       r3              (not saved; return value register)
+       r3              (not saved; return value register)
        r31 - r13       (saved; order given to save least number)
        r12             (not saved; if used for DImode or DFmode would use r13)
        mq              (not saved; best to use it if we can)
        ctr             (not saved; when we have the choice ctr is better)
        lr              (saved)
-        cr5, r1, r2, ap, xer, vrsave, vscr (fixed)
+       cr5, r1, r2, ap, xer (fixed)
+       v0 - v1         (not saved or used for anything)
+       v13 - v3        (not saved; incoming vector arg registers)
+       v2              (not saved; incoming vector arg reg; return value)
+       v19 - v14       (not saved or used for anything)
+       v31 - v20       (saved; order given to save least number)
+       vrsave, vscr    (fixed)
        spe_acc, spefscr (fixed)
-
-       AltiVec registers:
-       v0 - v1         (not saved or used for anything)
-       v13 - v3        (not saved; incoming vector arg registers)
-       v2              (not saved; incoming vector arg reg; return value)
-       v19 - v14       (not saved or used for anything)
-       v31 - v20       (saved; order given to save least number)
+       sfp             (fixed)
 */
-                                               
+
 #if FIXED_R2 == 1
 #define MAYBE_R2_AVAILABLE
 #define MAYBE_R2_FIXED 2,
@@ -943,28 +736,28 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
 #define MAYBE_R2_FIXED
 #endif
 
-#define REG_ALLOC_ORDER                                        \
-  {32,                                                         \
-   45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34,     \
-   33,                                                 \
-   63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, \
-   50, 49, 48, 47, 46,                                         \
-   75, 74, 69, 68, 72, 71, 70,                         \
-   0, MAYBE_R2_AVAILABLE                               \
-   9, 11, 10, 8, 7, 6, 5, 4,                           \
-   3,                                                  \
-   31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, \
-   18, 17, 16, 15, 14, 13, 12,                         \
-   64, 66, 65,                                                 \
-   73, 1, MAYBE_R2_FIXED 67, 76,                       \
-   /* AltiVec registers.  */                           \
-   77, 78,                                             \
-   90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80,         \
-   79,                                                 \
-   96, 95, 94, 93, 92, 91,                             \
-   108, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98,        \
-   97, 109, 110                                                \
-   , 111, 112                                              \
+#define REG_ALLOC_ORDER                                                \
+  {32,                                                         \
+   45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34,             \
+   33,                                                         \
+   63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51,         \
+   50, 49, 48, 47, 46,                                         \
+   75, 74, 69, 68, 72, 71, 70,                                 \
+   0, MAYBE_R2_AVAILABLE                                       \
+   9, 11, 10, 8, 7, 6, 5, 4,                                   \
+   3,                                                          \
+   31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19,         \
+   18, 17, 16, 15, 14, 13, 12,                                 \
+   64, 66, 65,                                                 \
+   73, 1, MAYBE_R2_FIXED 67, 76,                               \
+   /* AltiVec registers.  */                                   \
+   77, 78,                                                     \
+   90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80,                 \
+   79,                                                         \
+   96, 95, 94, 93, 92, 91,                                     \
+   108, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, 97,    \
+   109, 110,                                                   \
+   111, 112, 113                                               \
 }
 
 /* True if register is floating-point.  */
@@ -977,7 +770,8 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
 #define CR_REGNO_NOT_CR0_P(N) ((N) >= 69 && (N) <= 75)
 
 /* True if register is an integer register.  */
-#define INT_REGNO_P(N) ((N) <= 31 || (N) == ARG_POINTER_REGNUM)
+#define INT_REGNO_P(N) \
+  ((N) <= 31 || (N) == ARG_POINTER_REGNUM || (N) == FRAME_POINTER_REGNUM)
 
 /* SPE SIMD registers are just the GPRs.  */
 #define SPE_SIMD_REGNO_P(N) ((N) <= 31)
@@ -989,29 +783,13 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
 #define ALTIVEC_REGNO_P(N) ((N) >= FIRST_ALTIVEC_REGNO && (N) <= LAST_ALTIVEC_REGNO)
 
 /* Return number of consecutive hard regs needed starting at reg REGNO
-   to hold something of mode MODE.
-   This is ordinarily the length in words of a value of mode MODE
-   but can be less for certain modes in special long registers.
-
-   For the SPE, GPRs are 64 bits but only 32 bits are visible in
-   scalar instructions.  The upper 32 bits are only available to the
-   SIMD instructions.
-
-   POWER and PowerPC GPRs hold 32 bits worth;
-   PowerPC64 GPRs and FPRs point register holds 64 bits worth.  */
-
-#define HARD_REGNO_NREGS(REGNO, MODE)                                  \
-  (FP_REGNO_P (REGNO)                                                  \
-   ? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \
-   : (SPE_SIMD_REGNO_P (REGNO) && TARGET_SPE && SPE_VECTOR_MODE (MODE))   \
-   ? ((GET_MODE_SIZE (MODE) + UNITS_PER_SPE_WORD - 1) / UNITS_PER_SPE_WORD) \
-   : ALTIVEC_REGNO_P (REGNO)                                           \
-   ? ((GET_MODE_SIZE (MODE) + UNITS_PER_ALTIVEC_WORD - 1) / UNITS_PER_ALTIVEC_WORD) \
-   : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
+   to hold something of mode MODE.  */
+
+#define HARD_REGNO_NREGS(REGNO, MODE) rs6000_hard_regno_nregs ((REGNO), (MODE))
 
 #define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE)    \
   ((TARGET_32BIT && TARGET_POWERPC64                   \
-    && (MODE == DImode || MODE == DFmode)              \
+    && (GET_MODE_SIZE (MODE) > 4)  \
     && INT_REGNO_P (REGNO)) ? 1 : 0)
 
 #define ALTIVEC_VECTOR_MODE(MODE)      \
@@ -1026,43 +804,24 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
          || (MODE) == V1DImode          \
          || (MODE) == V2SImode)
 
-/* Define this macro to be nonzero if the port is prepared to handle
-   insns involving vector mode MODE.  At the very least, it must have
-   move patterns for this mode.  */
-
-#define VECTOR_MODE_SUPPORTED_P(MODE)                  \
-        ((TARGET_SPE && SPE_VECTOR_MODE (MODE))                \
-        || (TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (MODE)))
-
-/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
-   For POWER and PowerPC, the GPRs can hold any mode, but values bigger
-   than one register cannot go past R31.  The float
-   registers only can hold floating modes and DImode, and CR register only
-   can hold CC modes.  We cannot put TImode anywhere except general
-   register and it must be able to fit within the register set.  */
-
-#define HARD_REGNO_MODE_OK(REGNO, MODE)                                        \
-  (INT_REGNO_P (REGNO) ?                                               \
-     INT_REGNO_P (REGNO + HARD_REGNO_NREGS (REGNO, MODE) - 1)          \
-   : FP_REGNO_P (REGNO) ?                                              \
-     (GET_MODE_CLASS (MODE) == MODE_FLOAT                              \
-      || (GET_MODE_CLASS (MODE) == MODE_INT                            \
-         && GET_MODE_SIZE (MODE) == UNITS_PER_FP_WORD))                \
-   : ALTIVEC_REGNO_P (REGNO) ? ALTIVEC_VECTOR_MODE (MODE)              \
-   : SPE_SIMD_REGNO_P (REGNO) && TARGET_SPE && SPE_VECTOR_MODE (MODE) ? 1 \
-   : CR_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_CC             \
-   : XER_REGNO_P (REGNO) ? (MODE) == PSImode                           \
-   : GET_MODE_SIZE (MODE) <= UNITS_PER_WORD)
+#define UNITS_PER_SIMD_WORD                                    \
+        (TARGET_ALTIVEC ? UNITS_PER_ALTIVEC_WORD               \
+        : (TARGET_SPE ? UNITS_PER_SPE_WORD : UNITS_PER_WORD))
+
+/* Value is TRUE if hard register REGNO can hold a value of
+   machine-mode MODE.  */
+#define HARD_REGNO_MODE_OK(REGNO, MODE) \
+  rs6000_hard_regno_mode_ok_p[(int)(MODE)][REGNO]
 
 /* 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,
    for any hard reg, then this must be 0 for correct output.  */
 #define MODES_TIEABLE_P(MODE1, MODE2) \
-  (GET_MODE_CLASS (MODE1) == MODE_FLOAT                \
-   ? GET_MODE_CLASS (MODE2) == MODE_FLOAT      \
-   : GET_MODE_CLASS (MODE2) == MODE_FLOAT      \
-   ? GET_MODE_CLASS (MODE1) == MODE_FLOAT      \
+  (SCALAR_FLOAT_MODE_P (MODE1)                 \
+   ? SCALAR_FLOAT_MODE_P (MODE2)               \
+   : SCALAR_FLOAT_MODE_P (MODE2)               \
+   ? SCALAR_FLOAT_MODE_P (MODE1)               \
    : GET_MODE_CLASS (MODE1) == MODE_CC         \
    ? GET_MODE_CLASS (MODE2) == MODE_CC         \
    : GET_MODE_CLASS (MODE2) == MODE_CC         \
@@ -1102,9 +861,9 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
 #define BRANCH_COST 3
 
 /* Override BRANCH_COST heuristic which empirically produces worse
-   performance for fold_range_test().  */
+   performance for removing short circuiting from the logical ops.  */
 
-#define RANGE_TEST_NON_SHORT_CIRCUIT 0
+#define LOGICAL_OP_NON_SHORT_CIRCUIT 0
 
 /* A fixed register used at prologue and epilogue generation to fix
    addressing modes.  The SPE needs heavy addressing fixes at the last
@@ -1119,59 +878,10 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
 
 #define FIXED_SCRATCH (TARGET_SPE ? 14 : 11)
 
-/* Define this macro to change register usage conditional on target flags.
-   Set MQ register fixed (already call_used) if not POWER architecture
-   (RIOS1, RIOS2, RSC, and PPC601) so that it will not be allocated.
-   64-bit AIX reserves GPR13 for thread-private data.
-   Conditionally disable FPRs.  */
+/* Define this macro to change register usage conditional on target
+   flags.  */
 
-#define CONDITIONAL_REGISTER_USAGE                                     \
-{                                                                      \
-  int i;                                                               \
-  if (! TARGET_POWER)                                                  \
-    fixed_regs[64] = 1;                                                        \
-  if (TARGET_64BIT)                                                    \
-    fixed_regs[13] = call_used_regs[13]                                        \
-      = call_really_used_regs[13] = 1;                                         \
-  if (TARGET_SOFT_FLOAT || !TARGET_FPRS)                               \
-    for (i = 32; i < 64; i++)                                          \
-      fixed_regs[i] = call_used_regs[i]                                        \
-        = call_really_used_regs[i] = 1;                                        \
-  if (DEFAULT_ABI == ABI_V4                                            \
-      && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM                     \
-      && flag_pic == 2)                                                        \
-    fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;                    \
-  if (DEFAULT_ABI == ABI_V4                                            \
-      && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM                     \
-      && flag_pic == 1)                                                        \
-    fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]                         \
-      = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]                 \
-      = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;     \
-  if (DEFAULT_ABI == ABI_DARWIN                                                \
-      && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)                    \
-    global_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]                                \
-      = fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]                     \
-      = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]                 \
-      = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;     \
-  if (TARGET_ALTIVEC)                                                   \
-    global_regs[VSCR_REGNO] = 1;                                        \
-  if (TARGET_SPE)                                                      \
-    {                                                                   \
-      global_regs[SPEFSCR_REGNO] = 1;                                  \
-      fixed_regs[FIXED_SCRATCH]                                                \
-        = call_used_regs[FIXED_SCRATCH]                                        \
-       = call_really_used_regs[FIXED_SCRATCH] = 1;                     \
-    }                                                                   \
-  if (! TARGET_ALTIVEC)                                                        \
-    {                                                                  \
-      for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)      \
-       fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1; \
-      call_really_used_regs[VRSAVE_REGNO] = 1;                         \
-    }                                                                  \
-  if (TARGET_ALTIVEC_ABI)                                              \
-    for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)   \
-      call_used_regs[i] = call_really_used_regs[i] = 1;                        \
-}
+#define CONDITIONAL_REGISTER_USAGE rs6000_conditional_register_usage ()
 
 /* Specify the registers used for certain standard purposes.
    The values of these macros are register numbers.  */
@@ -1183,7 +893,10 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
 #define STACK_POINTER_REGNUM 1
 
 /* Base register for access to local variables of the function.  */
-#define FRAME_POINTER_REGNUM 31
+#define HARD_FRAME_POINTER_REGNUM 31
+
+/* Base register for access to local variables of the function.  */
+#define FRAME_POINTER_REGNUM 113
 
 /* Value should be nonzero if functions must have frame pointers.
    Zero means the frame pointer need not be set up (and parms
@@ -1295,26 +1008,26 @@ enum reg_class
 #define REG_CLASS_CONTENTS                                                  \
 {                                                                           \
   { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* NO_REGS */         \
-  { 0xfffffffe, 0x00000000, 0x00000008, 0x00000000 }, /* BASE_REGS */       \
-  { 0xffffffff, 0x00000000, 0x00000008, 0x00000000 }, /* GENERAL_REGS */     \
+  { 0xfffffffe, 0x00000000, 0x00000008, 0x00020000 }, /* BASE_REGS */       \
+  { 0xffffffff, 0x00000000, 0x00000008, 0x00020000 }, /* GENERAL_REGS */     \
   { 0x00000000, 0xffffffff, 0x00000000, 0x00000000 }, /* FLOAT_REGS */       \
   { 0x00000000, 0x00000000, 0xffffe000, 0x00001fff }, /* ALTIVEC_REGS */     \
   { 0x00000000, 0x00000000, 0x00000000, 0x00002000 }, /* VRSAVE_REGS */             \
   { 0x00000000, 0x00000000, 0x00000000, 0x00004000 }, /* VSCR_REGS */       \
   { 0x00000000, 0x00000000, 0x00000000, 0x00008000 }, /* SPE_ACC_REGS */     \
   { 0x00000000, 0x00000000, 0x00000000, 0x00010000 }, /* SPEFSCR_REGS */     \
-  { 0xffffffff, 0xffffffff, 0x00000008, 0x00000000 }, /* NON_SPECIAL_REGS */ \
+  { 0xffffffff, 0xffffffff, 0x00000008, 0x00020000 }, /* NON_SPECIAL_REGS */ \
   { 0x00000000, 0x00000000, 0x00000001, 0x00000000 }, /* MQ_REGS */         \
   { 0x00000000, 0x00000000, 0x00000002, 0x00000000 }, /* LINK_REGS */       \
   { 0x00000000, 0x00000000, 0x00000004, 0x00000000 }, /* CTR_REGS */        \
   { 0x00000000, 0x00000000, 0x00000006, 0x00000000 }, /* LINK_OR_CTR_REGS */ \
   { 0x00000000, 0x00000000, 0x00000007, 0x00002000 }, /* SPECIAL_REGS */     \
-  { 0xffffffff, 0x00000000, 0x0000000f, 0x00000000 }, /* SPEC_OR_GEN_REGS */ \
+  { 0xffffffff, 0x00000000, 0x0000000f, 0x00022000 }, /* SPEC_OR_GEN_REGS */ \
   { 0x00000000, 0x00000000, 0x00000010, 0x00000000 }, /* CR0_REGS */        \
   { 0x00000000, 0x00000000, 0x00000ff0, 0x00000000 }, /* CR_REGS */         \
-  { 0xffffffff, 0x00000000, 0x0000efff, 0x00000000 }, /* NON_FLOAT_REGS */   \
+  { 0xffffffff, 0x00000000, 0x0000efff, 0x00020000 }, /* NON_FLOAT_REGS */   \
   { 0x00000000, 0x00000000, 0x00001000, 0x00000000 }, /* XER_REGS */        \
-  { 0xffffffff, 0xffffffff, 0xffffffff, 0x00003fff }  /* ALL_REGS */        \
+  { 0xffffffff, 0xffffffff, 0xffffffff, 0x0003ffff }  /* ALL_REGS */        \
 }
 
 /* The same information, inverted:
@@ -1335,106 +1048,27 @@ enum reg_class
   : (REGNO) == ARG_POINTER_REGNUM ? BASE_REGS  \
   : (REGNO) == XER_REGNO ? XER_REGS            \
   : (REGNO) == VRSAVE_REGNO ? VRSAVE_REGS      \
-  : (REGNO) == VSCR_REGNO ? VRSAVE_REGS        \
+  : (REGNO) == VSCR_REGNO ? VRSAVE_REGS                \
   : (REGNO) == SPE_ACC_REGNO ? SPE_ACC_REGS    \
   : (REGNO) == SPEFSCR_REGNO ? SPEFSCR_REGS    \
+  : (REGNO) == FRAME_POINTER_REGNUM ? BASE_REGS        \
   : NO_REGS)
 
 /* The class value for index registers, and the one for base regs.  */
 #define INDEX_REG_CLASS GENERAL_REGS
 #define BASE_REG_CLASS BASE_REGS
 
-/* Get reg_class from a letter such as appears in the machine description.  */
-
-#define REG_CLASS_FROM_LETTER(C) \
-  ((C) == 'f' ? FLOAT_REGS     \
-   : (C) == 'b' ? BASE_REGS    \
-   : (C) == 'h' ? SPECIAL_REGS \
-   : (C) == 'q' ? MQ_REGS      \
-   : (C) == 'c' ? CTR_REGS     \
-   : (C) == 'l' ? LINK_REGS    \
-   : (C) == 'v' ? ALTIVEC_REGS \
-   : (C) == 'x' ? CR0_REGS     \
-   : (C) == 'y' ? CR_REGS      \
-   : (C) == 'z' ? XER_REGS     \
-   : NO_REGS)
-
-/* The letters I, J, K, L, M, N, and P 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 a signed 16-bit constant
-   `J' is a constant with only the high-order 16 bits nonzero
-   `K' is a constant with only the low-order 16 bits nonzero
-   `L' is a signed 16-bit constant shifted left 16 bits
-   `M' is a constant that is greater than 31
-   `N' is a positive constant that is an exact power of two
-   `O' is the constant zero
-   `P' is a constant whose negation is a signed 16-bit constant */
-
-#define CONST_OK_FOR_LETTER_P(VALUE, C)                                        \
-   ( (C) == 'I' ? (unsigned HOST_WIDE_INT) ((VALUE) + 0x8000) < 0x10000        \
-   : (C) == 'J' ? ((VALUE) & (~ (unsigned HOST_WIDE_INT) 0xffff0000)) == 0 \
-   : (C) == 'K' ? ((VALUE) & (~ (HOST_WIDE_INT) 0xffff)) == 0          \
-   : (C) == 'L' ? (((VALUE) & 0xffff) == 0                             \
-                  && ((VALUE) >> 31 == -1 || (VALUE) >> 31 == 0))      \
-   : (C) == 'M' ? (VALUE) > 31                                         \
-   : (C) == 'N' ? (VALUE) > 0 && exact_log2 (VALUE) >= 0               \
-   : (C) == 'O' ? (VALUE) == 0                                         \
-   : (C) == 'P' ? (unsigned HOST_WIDE_INT) ((- (VALUE)) + 0x8000) < 0x10000 \
-   : 0)
-
-/* Similar, but for floating constants, and defining letters G and H.
-   Here VALUE is the CONST_DOUBLE rtx itself.
-
-   We flag for special constants when we can copy the constant into
-   a general register in two insns for DF/DI and one insn for SF.
-
-   'H' is used for DI/DF constants that take 3 insns.  */
-
-#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C)                         \
-  (  (C) == 'G' ? (num_insns_constant (VALUE, GET_MODE (VALUE))                \
-                  == ((GET_MODE (VALUE) == SFmode) ? 1 : 2))           \
-   : (C) == 'H' ? (num_insns_constant (VALUE, GET_MODE (VALUE)) == 3)  \
-   : 0)
-
-/* Optional extra constraints for this machine.
-
-   'Q' means that is a memory operand that is just an offset from a reg.
-   'R' is for AIX TOC entries.
-   'S' is a constant that can be placed into a 64-bit mask operand
-   'T' is a constant that can be placed into a 32-bit mask operand
-   'U' is for V.4 small data references.
-   'W' is a vector constant that can be easily generated (no mem refs).
-   't' is for AND masks that can be performed by two rldic{l,r} insns.  */
-
-#define EXTRA_CONSTRAINT(OP, C)                                                \
-  ((C) == 'Q' ? GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == REG \
-   : (C) == 'R' ? legitimate_constant_pool_address_p (OP)              \
-   : (C) == 'S' ? mask64_operand (OP, DImode)                          \
-   : (C) == 'T' ? mask_operand (OP, SImode)                            \
-   : (C) == 'U' ? (DEFAULT_ABI == ABI_V4                               \
-                  && small_data_operand (OP, GET_MODE (OP)))           \
-   : (C) == 't' ? (mask64_2_operand (OP, DImode)                       \
-                  && (fixed_regs[CR0_REGNO]                            \
-                      || !logical_operand (OP, DImode))                \
-                  && !mask64_operand (OP, DImode))                     \
-   : (C) == 'W' ? (easy_vector_constant (OP, GET_MODE (OP)))           \
-   : 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
    in some cases it is preferable to use a more restrictive class.
 
    On the RS/6000, we have to return NO_REGS when we want to reload a
-   floating-point CONST_DOUBLE to force it to be copied to memory.  
+   floating-point CONST_DOUBLE to force it to be copied to memory.
 
    We also don't want to reload integer values into floating-point
    registers if we can at all help it.  In fact, this can
-   cause reload to abort, if it tries to generate a reload of CTR
+   cause reload to die, if it tries to generate a reload of CTR
    into a FP register and discovers it doesn't have the memory location
    required.
 
@@ -1443,20 +1077,20 @@ enum reg_class
  */
 
 #define PREFERRED_RELOAD_CLASS(X,CLASS)                        \
-  (((GET_CODE (X) == CONST_DOUBLE                      \
-     && GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT)   \
-    ? NO_REGS                                          \
-    : (GET_MODE_CLASS (GET_MODE (X)) == MODE_INT       \
-       && (CLASS) == NON_SPECIAL_REGS)                 \
-    ? GENERAL_REGS                                     \
-    : (CLASS)))
+  ((CONSTANT_P (X)                                     \
+    && reg_classes_intersect_p ((CLASS), FLOAT_REGS))  \
+   ? NO_REGS                                           \
+   : (GET_MODE_CLASS (GET_MODE (X)) == MODE_INT        \
+      && (CLASS) == NON_SPECIAL_REGS)                  \
+   ? GENERAL_REGS                                      \
+   : (CLASS))
 
 /* Return the register class of a scratch register needed to copy IN into
    or out of a register in CLASS in MODE.  If it can be done directly,
    NO_REGS is returned.  */
 
 #define SECONDARY_RELOAD_CLASS(CLASS,MODE,IN) \
-  secondary_reload_class (CLASS, MODE, IN)
+  rs6000_secondary_reload_class (CLASS, MODE, IN)
 
 /* If we are copying between FP or AltiVec registers and anything
    else, we need a memory location.  */
@@ -1475,20 +1109,23 @@ enum reg_class
 #define CLASS_MAX_NREGS(CLASS, MODE)                                   \
  (((CLASS) == FLOAT_REGS)                                              \
   ? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \
+  : (TARGET_E500_DOUBLE && (CLASS) == GENERAL_REGS && (MODE) == DFmode) \
+  ? 1                                                                   \
   : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
 
+/* Return nonzero if for CLASS a mode change from FROM to TO is invalid.  */
 
-/* Return a class of registers that cannot change FROM mode to TO mode.  */
-
-#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS)                        \
-  (((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)                \
-    && GET_MODE_SIZE (FROM) >= 8 && GET_MODE_SIZE (TO) >= 8)             \
-   ? 0                                                                   \
-   : GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO)                                  \
-   ? reg_classes_intersect_p (FLOAT_REGS, CLASS)                         \
-   : (TARGET_SPE && (SPE_VECTOR_MODE (FROM) + SPE_VECTOR_MODE (TO)) == 1) \
-   ? reg_classes_intersect_p (GENERAL_REGS, CLASS)                       \
-   : 0)
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS)                      \
+  (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO)                          \
+   ? ((GET_MODE_SIZE (FROM) < 8 || GET_MODE_SIZE (TO) < 8              \
+       || TARGET_IEEEQUAD)                                             \
+      && reg_classes_intersect_p (FLOAT_REGS, CLASS))                  \
+   : (((TARGET_E500_DOUBLE                                             \
+       && ((((TO) == DFmode) + ((FROM) == DFmode)) == 1                \
+           || (((TO) == DImode) + ((FROM) == DImode)) == 1))           \
+       || (TARGET_SPE                                                  \
+          && (SPE_VECTOR_MODE (FROM) + SPE_VECTOR_MODE (TO)) == 1))    \
+      && reg_classes_intersect_p (GENERAL_REGS, CLASS)))
 
 /* Stack layout; function entry, exit and calling.  */
 
@@ -1506,14 +1143,17 @@ extern enum rs6000_abi rs6000_current_abi;      /* available for use by subtarget */
    makes the stack pointer a smaller address.  */
 #define STACK_GROWS_DOWNWARD
 
-/* Define this if the nominal address of the stack frame
+/* Offsets recorded in opcodes are a multiple of this alignment factor.  */
+#define DWARF_CIE_DATA_ALIGNMENT (-((int) (TARGET_32BIT ? 4 : 8)))
+
+/* 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.
 
    On the RS/6000, we grow upwards, from the area after the outgoing
    arguments.  */
-/* #define FRAME_GROWS_DOWNWARD */
+#define FRAME_GROWS_DOWNWARD (flag_stack_protect != 0)
 
 /* Size of the outgoing register save area */
 #define RS6000_REG_SAVE ((DEFAULT_ABI == ABI_AIX                       \
@@ -1531,16 +1171,9 @@ extern enum rs6000_abi rs6000_current_abi;       /* available for use by subtarget */
                                     plus_constant (stack_pointer_rtx, \
                                                    (TARGET_32BIT ? 20 : 40)))
 
-/* Size of the V.4 varargs area if needed */
-#define RS6000_VARARGS_AREA 0
-
 /* Align an address */
 #define RS6000_ALIGN(n,a) (((n) + (a) - 1) & ~((a) - 1))
 
-/* Size of V.4 varargs area in bytes */
-#define RS6000_VARARGS_SIZE \
-  ((GP_ARG_NUM_REG * (TARGET_32BIT ? 4 : 8)) + (FP_ARG_NUM_REG * 8) + 8)
-
 /* 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
@@ -1551,10 +1184,11 @@ extern enum rs6000_abi rs6000_current_abi;      /* available for use by subtarget */
    outgoing parameter area.  */
 
 #define STARTING_FRAME_OFFSET                                          \
-  (RS6000_ALIGN (current_function_outgoing_args_size,                  \
-                TARGET_ALTIVEC ? 16 : 8)                               \
-   + RS6000_VARARGS_AREA                                               \
-   + RS6000_SAVE_AREA)
+  (FRAME_GROWS_DOWNWARD                                                        \
+   ? 0                                                                 \
+   : (RS6000_ALIGN (current_function_outgoing_args_size,               \
+                   TARGET_ALTIVEC ? 16 : 8)                            \
+      + RS6000_SAVE_AREA))
 
 /* Offset from the stack pointer register to an item dynamically
    allocated on the stack, e.g., by `alloca'.
@@ -1625,7 +1259,7 @@ extern enum rs6000_abi rs6000_current_abi;        /* available for use by subtarget */
 /* DRAFT_V4_STRUCT_RET defaults off.  */
 #define DRAFT_V4_STRUCT_RET 0
 
-/* Let RETURN_IN_MEMORY control what happens.  */
+/* Let TARGET_RETURN_IN_MEMORY control what happens.  */
 #define DEFAULT_PCC_STRUCT_RETURN 0
 
 /* Mode of stack savearea.
@@ -1668,14 +1302,18 @@ extern enum rs6000_abi rs6000_current_abi;      /* available for use by subtarget */
 #define CALL_LONG              0x00000008      /* always call indirect */
 #define CALL_LIBCALL           0x00000010      /* libcall */
 
+/* We don't have prologue and epilogue functions to save/restore
+   everything for most ABIs.  */
+#define WORLD_SAVE_P(INFO) 0
+
 /* 1 if N is a possible register number for a function value
    as seen by the caller.
 
    On RS/6000, this is r3, fp1, and v2 (for AltiVec).  */
 #define FUNCTION_VALUE_REGNO_P(N)                                      \
   ((N) == GP_ARG_RETURN                                                        \
-   || ((N) == FP_ARG_RETURN && TARGET_HARD_FLOAT)                      \
-   || ((N) == ALTIVEC_ARG_RETURN && TARGET_ALTIVEC))
+   || ((N) == FP_ARG_RETURN && TARGET_HARD_FLOAT && TARGET_FPRS)       \
+   || ((N) == ALTIVEC_ARG_RETURN && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI))
 
 /* 1 if N is a possible register number for function argument passing.
    On RS/6000, these are r3-r10 and fp1-fp13.
@@ -1683,26 +1321,10 @@ extern enum rs6000_abi rs6000_current_abi;      /* available for use by subtarget */
 #define FUNCTION_ARG_REGNO_P(N)                                                \
   ((unsigned) (N) - GP_ARG_MIN_REG < GP_ARG_NUM_REG                    \
    || ((unsigned) (N) - ALTIVEC_ARG_MIN_REG < ALTIVEC_ARG_NUM_REG      \
-       && TARGET_ALTIVEC)                                              \
+       && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)                                \
    || ((unsigned) (N) - FP_ARG_MIN_REG < FP_ARG_NUM_REG                        \
-       && TARGET_HARD_FLOAT))
+       && TARGET_HARD_FLOAT && TARGET_FPRS))
 \f
-/* A C structure for machine-specific, per-function data.
-   This is added to the cfun structure.  */
-typedef struct machine_function GTY(())
-{
-  /* Whether a System V.4 varargs area was created.  */
-  int sysv_varargs_p;
-  /* Flags if __builtin_return_address (n) with n >= 1 was used.  */
-  int ra_needs_full_frame;
-  /* Some local-dynamic symbol.  */
-  const char *some_ld_name;
-  /* Whether the instruction chain has been scanned already.  */
-  int insn_chain_scanned_p;
-  /* Flags if __builtin_return_address (0) was used.  */
-  int ra_need_lr;
-} machine_function;
-
 /* Define a data type for recording info about an argument list
    during the scan of that argument list.  This data type should
    hold all necessary information about the function itself
@@ -1731,42 +1353,35 @@ typedef struct rs6000_args
   int stdarg;                  /* Whether function is a stdarg function.  */
   int call_cookie;             /* Do special things for this call */
   int sysv_gregno;             /* next available GP register */
+  int intoffset;               /* running offset in struct (darwin64) */
+  int use_stack;               /* any part of struct on stack (darwin64) */
+  int named;                   /* false for varargs params */
 } CUMULATIVE_ARGS;
 
-/* Define intermediate macro to compute the size (in registers) of an argument
-   for the RS/6000.  */
-
-#define UNITS_PER_ARG (TARGET_32BIT ? 4 : 8)
-
-#define RS6000_ARG_SIZE(MODE, TYPE)                                    \
-((MODE) != BLKmode                                                     \
- ? (GET_MODE_SIZE (MODE) + (UNITS_PER_ARG - 1)) / UNITS_PER_ARG                \
- : (int_size_in_bytes (TYPE) + (UNITS_PER_ARG - 1)) / UNITS_PER_ARG)
-
 /* Initialize a variable CUM of type CUMULATIVE_ARGS
    for a call to a function whose data type is FNTYPE.
    For a library call, FNTYPE is 0.  */
 
-#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT) \
-  init_cumulative_args (&CUM, FNTYPE, LIBNAME, FALSE, FALSE)
+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
+  init_cumulative_args (&CUM, FNTYPE, LIBNAME, FALSE, FALSE, N_NAMED_ARGS)
 
 /* Similar, but when scanning the definition of a procedure.  We always
    set NARGS_PROTOTYPE large so we never return an EXPR_LIST.  */
 
-#define INIT_CUMULATIVE_INCOMING_ARGS(CUM,FNTYPE,LIBNAME) \
-  init_cumulative_args (&CUM, FNTYPE, LIBNAME, TRUE, FALSE)
+#define INIT_CUMULATIVE_INCOMING_ARGS(CUM, FNTYPE, LIBNAME) \
+  init_cumulative_args (&CUM, FNTYPE, LIBNAME, TRUE, FALSE, 1000)
 
 /* Like INIT_CUMULATIVE_ARGS' but only used for outgoing libcalls.  */
 
 #define INIT_CUMULATIVE_LIBCALL_ARGS(CUM, MODE, LIBNAME) \
-  init_cumulative_args (&CUM, NULL_TREE, LIBNAME, FALSE, TRUE)
+  init_cumulative_args (&CUM, NULL_TREE, LIBNAME, FALSE, TRUE, 0)
 
 /* 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)
+  function_arg_advance (&CUM, MODE, TYPE, NAMED, 0)
 
 /* Determine where to put an argument to a function.
    Value is zero to push the argument on the stack,
@@ -1793,22 +1408,6 @@ typedef struct rs6000_args
 #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
   function_arg (&CUM, MODE, TYPE, NAMED)
 
-/* 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
@@ -1824,28 +1423,13 @@ typedef struct rs6000_args
 #define FUNCTION_ARG_BOUNDARY(MODE, TYPE) \
   function_arg_boundary (MODE, TYPE)
 
-/* Define to nonzero if complex arguments should be split into their
-   corresponding components.
-
-   This should be set for Linux and Darwin as well, but we can't break
-   the ABIs at the moment.  For now, only AIX gets fixed.  */
-#define SPLIT_COMPLEX_ARGS (DEFAULT_ABI == ABI_AIX)
-
 /* Implement `va_start' for varargs and stdarg.  */
 #define EXPAND_BUILTIN_VA_START(valist, nextarg) \
   rs6000_va_start (valist, nextarg)
 
-/* Implement `va_arg'.  */
-#define EXPAND_BUILTIN_VA_ARG(valist, type) \
-  rs6000_va_arg (valist, type)
-
 #define PAD_VARARGS_DOWN \
    (FUNCTION_ARG_PADDING (TYPE_MODE (type), type) == downward)
 
-/* Define this macro to be a nonzero value if the location where a function
-   argument is passed depends on whether or not it is a named argument.  */
-#define STRICT_ARGUMENT_NAMING 1
-
 /* Output assembler code to FILE to increment profiler label # LABELNO
    for profiling a function entry.  */
 
@@ -1928,10 +1512,12 @@ typedef struct rs6000_args
    of eliminable registers.  The "from" register number is given first,
    followed by "to".  Eliminations of the same "from" register are listed
    in order of preference.  */
-#define ELIMINABLE_REGS                                \
-{{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM},        \
- { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM},  \
- { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM},  \
+#define ELIMINABLE_REGS                                        \
+{{ HARD_FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM},   \
+ { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM},                \
+ { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM},   \
+ { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM},          \
+ { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM},     \
  { RS6000_PIC_OFFSET_TABLE_REGNUM, RS6000_PIC_OFFSET_TABLE_REGNUM } }
 
 /* Given FROM and TO register numbers, say whether this elimination is allowed.
@@ -1971,14 +1557,18 @@ typedef struct rs6000_args
 #define REGNO_OK_FOR_INDEX_P(REGNO)                            \
 ((REGNO) < FIRST_PSEUDO_REGISTER                               \
  ? (REGNO) <= 31 || (REGNO) == 67                              \
+   || (REGNO) == FRAME_POINTER_REGNUM                          \
  : (reg_renumber[REGNO] >= 0                                   \
-    && (reg_renumber[REGNO] <= 31 || reg_renumber[REGNO] == 67)))
+    && (reg_renumber[REGNO] <= 31 || reg_renumber[REGNO] == 67 \
+       || reg_renumber[REGNO] == FRAME_POINTER_REGNUM)))
 
 #define REGNO_OK_FOR_BASE_P(REGNO)                             \
 ((REGNO) < FIRST_PSEUDO_REGISTER                               \
  ? ((REGNO) > 0 && (REGNO) <= 31) || (REGNO) == 67             \
+   || (REGNO) == FRAME_POINTER_REGNUM                          \
  : (reg_renumber[REGNO] > 0                                    \
-    && (reg_renumber[REGNO] <= 31 || reg_renumber[REGNO] == 67)))
+    && (reg_renumber[REGNO] <= 31 || reg_renumber[REGNO] == 67 \
+       || reg_renumber[REGNO] == FRAME_POINTER_REGNUM)))
 \f
 /* Maximum number of registers that can appear in a valid memory address.  */
 
@@ -2007,6 +1597,11 @@ typedef struct rs6000_args
     || easy_vector_constant (X, GET_MODE (X)))                 \
    && !rs6000_tls_referenced_p (X))
 
+#define EASY_VECTOR_15(n) ((n) >= -16 && (n) <= 15)
+#define EASY_VECTOR_15_ADD_SELF(n) (!EASY_VECTOR_15((n))       \
+                                   && EASY_VECTOR_15((n) >> 1) \
+                                   && ((n) & 1) == 0)
+
 /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
    and check its validity for a certain class.
    We have two alternate definitions for each of them.
@@ -2029,16 +1624,14 @@ typedef struct rs6000_args
 /* Nonzero if X is a hard reg that can be used as an index
    or if it is a pseudo reg in the non-strict case.  */
 #define INT_REG_OK_FOR_INDEX_P(X, STRICT)                      \
-  ((! (STRICT)                                                 \
-    && (REGNO (X) <= 31                                                \
-       || REGNO (X) == ARG_POINTER_REGNUM                      \
-       || REGNO (X) >= FIRST_PSEUDO_REGISTER))                 \
-   || ((STRICT) && REGNO_OK_FOR_INDEX_P (REGNO (X))))
+  ((!(STRICT) && REGNO (X) >= FIRST_PSEUDO_REGISTER)           \
+   || REGNO_OK_FOR_INDEX_P (REGNO (X)))
 
 /* Nonzero if X is a hard reg that can be used as a base reg
    or if it is a pseudo reg in the non-strict case.  */
 #define INT_REG_OK_FOR_BASE_P(X, STRICT)                       \
-  (REGNO (X) > 0 && INT_REG_OK_FOR_INDEX_P (X, (STRICT)))
+  ((!(STRICT) && REGNO (X) >= FIRST_PSEUDO_REGISTER)           \
+   || REGNO_OK_FOR_BASE_P (REGNO (X)))
 
 #define REG_OK_FOR_INDEX_P(X) INT_REG_OK_FOR_INDEX_P (X, REG_OK_STRICT_FLAG)
 #define REG_OK_FOR_BASE_P(X)  INT_REG_OK_FOR_BASE_P (X, REG_OK_STRICT_FLAG)
@@ -2048,7 +1641,7 @@ typedef struct rs6000_args
    The MODE argument is the machine mode for the MEM expression
    that wants to use this address.
 
-   On the RS/6000, there are four valid address: a SYMBOL_REF that
+   On the RS/6000, there are four valid addresses: a SYMBOL_REF that
    refers to a constant pool entry of an address (or the sum of it
    plus a constant), a short (16-bit signed) constant plus a register,
    the sum of two registers, or a register indirect, possibly with an
@@ -2102,9 +1695,9 @@ typedef struct rs6000_args
    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.
 
-   Implemented on rs6000 by rs6000_legitimize_reload_address.  
+   Implemented on rs6000 by rs6000_legitimize_reload_address.
    Note that (X) is evaluated twice; this is safe in current usage.  */
-   
+
 #define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN)         \
 do {                                                                        \
   int win;                                                                  \
@@ -2142,23 +1735,6 @@ do {                                                             \
 
 /* #define PIC_OFFSET_TABLE_REG_CALL_CLOBBERED */
 
-/* By generating position-independent code, when two different
-   programs (A and B) share a common library (libC.a), the text of
-   the library can be shared whether or not the library is linked at
-   the same address for both programs.  In some of these
-   environments, position-independent code requires not only the use
-   of different addressing modes, but also special code to enable the
-   use of these addressing modes.
-
-   The `FINALIZE_PIC' macro serves as a hook to emit these special
-   codes once the function is being compiled into assembly code, but
-   not before.  (It is not done before, because in the case of
-   compiling an inline function, it would lead to multiple PIC
-   prologues being included in functions which used inline functions
-   and were compiled to assembly language.)  */
-
-/* #define FINALIZE_PIC */
-
 /* A C expression that is nonzero if X is a legitimate immediate
    operand on the target machine when generating position independent
    code.  You can assume that X satisfies `CONSTANT_P', so you need
@@ -2192,6 +1768,12 @@ do {                                                             \
 
 /* #define FIXUNS_TRUNC_LIKE_FIX_TRUNC */
 
+/* An integer expression for the size in bits of the largest integer machine
+   mode that should actually be used.  */
+
+/* Allow pairs of registers to be used, which is the intent of the default.  */
+#define MAX_FIXED_MODE_SIZE GET_MODE_BITSIZE (TARGET_POWERPC64 ? TImode : DImode)
+
 /* Max number of bytes we can move from memory to memory
    in one reasonably fast instruction.  */
 #define MOVE_MAX (! TARGET_POWERPC64 ? 4 : 8)
@@ -2209,7 +1791,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
 
 /* Define if loading short immediate values into registers sign extends.  */
@@ -2267,9 +1849,9 @@ do {                                                              \
    comparison.  CCmode should be used in all other cases.  */
 
 #define SELECT_CC_MODE(OP,X,Y) \
-  (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT ? CCFPmode      \
+  (SCALAR_FLOAT_MODE_P (GET_MODE (X)) ? CCFPmode       \
    : (OP) == GTU || (OP) == LTU || (OP) == GEU || (OP) == LEU ? CCUNSmode \
-   : (((OP) == EQ || (OP) == NE) && GET_RTX_CLASS (GET_CODE (X)) == '<'   \
+   : (((OP) == EQ || (OP) == NE) && COMPARISON_P (X)                     \
       ? CCEQmode : CCmode))
 
 /* Can the condition code MODE be safely reversed?  This is safe in
@@ -2294,10 +1876,6 @@ extern int rs6000_compare_fp_p;
    the end of the line.  */
 #define ASM_COMMENT_START " #"
 
-/* Implicit library calls should use memcpy, not bcopy, etc.  */
-
-#define TARGET_MEM_FUNCTIONS
-
 /* Flag to say the TOC is initialized */
 extern int toc_initialized;
 
@@ -2326,9 +1904,9 @@ extern int toc_initialized;
   do                                                                   \
     {                                                                  \
       fputs ("\t.weak\t", (FILE));                                     \
-      RS6000_OUTPUT_BASENAME ((FILE), (NAME));                         \
+      RS6000_OUTPUT_BASENAME ((FILE), (NAME));                                 \
       if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL                  \
-         && DEFAULT_ABI == ABI_AIX)                                    \
+         && DEFAULT_ABI == ABI_AIX && DOT_SYMBOLS)                     \
        {                                                               \
          if (TARGET_XCOFF)                                             \
            fputs ("[DS]", (FILE));                                     \
@@ -2340,7 +1918,7 @@ extern int toc_initialized;
        {                                                               \
          ASM_OUTPUT_DEF ((FILE), (NAME), (VAL));                       \
          if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL               \
-             && DEFAULT_ABI == ABI_AIX)                                \
+             && DEFAULT_ABI == ABI_AIX && DOT_SYMBOLS)                 \
            {                                                           \
              fputs ("\t.set\t.", (FILE));                              \
              RS6000_OUTPUT_BASENAME ((FILE), (NAME));                  \
@@ -2353,6 +1931,26 @@ extern int toc_initialized;
   while (0)
 #endif
 
+#if HAVE_GAS_WEAKREF
+#define ASM_OUTPUT_WEAKREF(FILE, DECL, NAME, VALUE)                    \
+  do                                                                   \
+    {                                                                  \
+      fputs ("\t.weakref\t", (FILE));                                  \
+      RS6000_OUTPUT_BASENAME ((FILE), (NAME));                                 \
+      fputs (", ", (FILE));                                            \
+      RS6000_OUTPUT_BASENAME ((FILE), (VALUE));                                \
+      if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL                  \
+         && DEFAULT_ABI == ABI_AIX && DOT_SYMBOLS)                     \
+       {                                                               \
+         fputs ("\n\t.weakref\t.", (FILE));                            \
+         RS6000_OUTPUT_BASENAME ((FILE), (NAME));                      \
+         fputs (", .", (FILE));                                        \
+         RS6000_OUTPUT_BASENAME ((FILE), (VALUE));                     \
+       }                                                               \
+      fputc ('\n', (FILE));                                            \
+    } while (0)
+#endif
+
 /* This implements the `alias' attribute.  */
 #undef ASM_OUTPUT_DEF_FROM_DECLS
 #define        ASM_OUTPUT_DEF_FROM_DECLS(FILE, DECL, TARGET)                   \
@@ -2361,7 +1959,7 @@ extern int toc_initialized;
       const char *alias = XSTR (XEXP (DECL_RTL (DECL), 0), 0);         \
       const char *name = IDENTIFIER_POINTER (TARGET);                  \
       if (TREE_CODE (DECL) == FUNCTION_DECL                            \
-         && DEFAULT_ABI == ABI_AIX)                                    \
+         && DEFAULT_ABI == ABI_AIX && DOT_SYMBOLS)                     \
        {                                                               \
          if (TREE_PUBLIC (DECL))                                       \
            {                                                           \
@@ -2525,6 +2123,7 @@ extern char rs6000_reg_names[][8];        /* register names (0 vs. %r0).  */
   &rs6000_reg_names[110][0],   /* vscr  */                             \
   &rs6000_reg_names[111][0],   /* spe_acc */                           \
   &rs6000_reg_names[112][0],   /* spefscr */                           \
+  &rs6000_reg_names[113][0],   /* sfp  */                              \
 }
 
 /* Table of additional register names to use in user input.  */
@@ -2612,80 +2211,6 @@ extern char rs6000_reg_names[][8];       /* register names (0 vs. %r0).  */
 
 #define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR)
 
-/* Define the codes that are matched by predicates in rs6000.c.  */
-
-#define PREDICATE_CODES                                                           \
-  {"any_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,            \
-                  LABEL_REF, SUBREG, REG, MEM, PARALLEL}},                \
-  {"zero_constant", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,          \
-                   LABEL_REF, SUBREG, REG, MEM}},                         \
-  {"short_cint_operand", {CONST_INT}},                                    \
-  {"u_short_cint_operand", {CONST_INT}},                                  \
-  {"non_short_cint_operand", {CONST_INT}},                                \
-  {"exact_log2_cint_operand", {CONST_INT}},                               \
-  {"gpc_reg_operand", {SUBREG, REG}},                                     \
-  {"cc_reg_operand", {SUBREG, REG}},                                      \
-  {"cc_reg_not_cr0_operand", {SUBREG, REG}},                              \
-  {"reg_or_short_operand", {SUBREG, REG, CONST_INT}},                     \
-  {"reg_or_neg_short_operand", {SUBREG, REG, CONST_INT}},                 \
-  {"reg_or_aligned_short_operand", {SUBREG, REG, CONST_INT}},             \
-  {"reg_or_u_short_operand", {SUBREG, REG, CONST_INT}},                           \
-  {"reg_or_cint_operand", {SUBREG, REG, CONST_INT}},                      \
-  {"reg_or_arith_cint_operand", {SUBREG, REG, CONST_INT}},                \
-  {"reg_or_add_cint64_operand", {SUBREG, REG, CONST_INT}},                \
-  {"reg_or_sub_cint64_operand", {SUBREG, REG, CONST_INT}},                \
-  {"reg_or_logical_cint_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}}, \
-  {"got_operand", {SYMBOL_REF, CONST, LABEL_REF}},                        \
-  {"got_no_const_operand", {SYMBOL_REF, LABEL_REF}},                      \
-  {"rs6000_tls_symbol_ref", {SYMBOL_REF}},                                \
-  {"easy_fp_constant", {CONST_DOUBLE}},                                           \
-  {"easy_vector_constant", {CONST_VECTOR}},                               \
-  {"easy_vector_constant_add_self", {CONST_VECTOR}},                      \
-  {"zero_fp_constant", {CONST_DOUBLE}},                                           \
-  {"reg_or_mem_operand", {SUBREG, MEM, REG}},                             \
-  {"lwa_operand", {SUBREG, MEM, REG}},                                    \
-  {"volatile_mem_operand", {MEM}},                                        \
-  {"offsettable_mem_operand", {MEM}},                                     \
-  {"mem_or_easy_const_operand", {SUBREG, MEM, CONST_DOUBLE}},             \
-  {"add_operand", {SUBREG, REG, CONST_INT}},                              \
-  {"non_add_cint_operand", {CONST_INT}},                                  \
-  {"and_operand", {SUBREG, REG, CONST_INT}},                              \
-  {"and64_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}},              \
-  {"and64_2_operand", {SUBREG, REG, CONST_INT}},                          \
-  {"logical_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}},            \
-  {"non_logical_cint_operand", {CONST_INT, CONST_DOUBLE}},                \
-  {"mask_operand", {CONST_INT}},                                          \
-  {"mask_operand_wrap", {CONST_INT}},                                     \
-  {"mask64_operand", {CONST_INT}},                                        \
-  {"mask64_2_operand", {CONST_INT}},                                      \
-  {"count_register_operand", {REG}},                                      \
-  {"xer_operand", {REG}},                                                 \
-  {"symbol_ref_operand", {SYMBOL_REF}},                                           \
-  {"rs6000_tls_symbol_ref", {SYMBOL_REF}},                                \
-  {"call_operand", {SYMBOL_REF, REG}},                                    \
-  {"current_file_function_operand", {SYMBOL_REF}},                        \
-  {"input_operand", {SUBREG, MEM, REG, CONST_INT,                         \
-                    CONST_DOUBLE, SYMBOL_REF}},                           \
-  {"load_multiple_operation", {PARALLEL}},                                \
-  {"store_multiple_operation", {PARALLEL}},                               \
-  {"vrsave_operation", {PARALLEL}},                                       \
-  {"branch_comparison_operator", {EQ, NE, LE, LT, GE,                     \
-                                 GT, LEU, LTU, GEU, GTU,                  \
-                                 UNORDERED, ORDERED,                      \
-                                 UNGE, UNLE }},                           \
-  {"branch_positive_comparison_operator", {EQ, LT, GT, LTU, GTU,          \
-                                          UNORDERED }},                   \
-  {"scc_comparison_operator", {EQ, NE, LE, LT, GE,                        \
-                              GT, LEU, LTU, GEU, GTU,                     \
-                              UNORDERED, ORDERED,                         \
-                              UNGE, UNLE }},                              \
-  {"trap_comparison_operator", {EQ, NE, LE, LT, GE,                       \
-                               GT, LEU, LTU, GEU, GTU}},                  \
-  {"boolean_operator", {AND, IOR, XOR}},                                  \
-  {"boolean_or_operator", {IOR, XOR}},                                    \
-  {"altivec_register_operand", {REG}},                                    \
-  {"min_max_operator", {SMIN, SMAX, UMIN, UMAX}},
-
 /* uncomment for disabling the corresponding default options */
 /* #define  MACHINE_no_sched_interblock */
 /* #define  MACHINE_no_sched_speculative */
@@ -2900,9 +2425,240 @@ enum rs6000_builtins
   ALTIVEC_BUILTIN_ABS_V4SI,
   ALTIVEC_BUILTIN_ABS_V4SF,
   ALTIVEC_BUILTIN_ABS_V8HI,
-  ALTIVEC_BUILTIN_ABS_V16QI
+  ALTIVEC_BUILTIN_ABS_V16QI,
+  ALTIVEC_BUILTIN_MASK_FOR_LOAD,
+  ALTIVEC_BUILTIN_MASK_FOR_STORE,
+  ALTIVEC_BUILTIN_VEC_INIT_V4SI,
+  ALTIVEC_BUILTIN_VEC_INIT_V8HI,
+  ALTIVEC_BUILTIN_VEC_INIT_V16QI,
+  ALTIVEC_BUILTIN_VEC_INIT_V4SF,
+  ALTIVEC_BUILTIN_VEC_SET_V4SI,
+  ALTIVEC_BUILTIN_VEC_SET_V8HI,
+  ALTIVEC_BUILTIN_VEC_SET_V16QI,
+  ALTIVEC_BUILTIN_VEC_SET_V4SF,
+  ALTIVEC_BUILTIN_VEC_EXT_V4SI,
+  ALTIVEC_BUILTIN_VEC_EXT_V8HI,
+  ALTIVEC_BUILTIN_VEC_EXT_V16QI,
+  ALTIVEC_BUILTIN_VEC_EXT_V4SF,
+
+  /* Altivec overloaded builtins.  */
+  ALTIVEC_BUILTIN_VCMPEQ_P,
+  ALTIVEC_BUILTIN_OVERLOADED_FIRST = ALTIVEC_BUILTIN_VCMPEQ_P,
+  ALTIVEC_BUILTIN_VCMPGT_P,
+  ALTIVEC_BUILTIN_VCMPGE_P,
+  ALTIVEC_BUILTIN_VEC_ABS,
+  ALTIVEC_BUILTIN_VEC_ABSS,
+  ALTIVEC_BUILTIN_VEC_ADD,
+  ALTIVEC_BUILTIN_VEC_ADDC,
+  ALTIVEC_BUILTIN_VEC_ADDS,
+  ALTIVEC_BUILTIN_VEC_AND,
+  ALTIVEC_BUILTIN_VEC_ANDC,
+  ALTIVEC_BUILTIN_VEC_AVG,
+  ALTIVEC_BUILTIN_VEC_CEIL,
+  ALTIVEC_BUILTIN_VEC_CMPB,
+  ALTIVEC_BUILTIN_VEC_CMPEQ,
+  ALTIVEC_BUILTIN_VEC_CMPEQUB,
+  ALTIVEC_BUILTIN_VEC_CMPEQUH,
+  ALTIVEC_BUILTIN_VEC_CMPEQUW,
+  ALTIVEC_BUILTIN_VEC_CMPGE,
+  ALTIVEC_BUILTIN_VEC_CMPGT,
+  ALTIVEC_BUILTIN_VEC_CMPLE,
+  ALTIVEC_BUILTIN_VEC_CMPLT,
+  ALTIVEC_BUILTIN_VEC_CTF,
+  ALTIVEC_BUILTIN_VEC_CTS,
+  ALTIVEC_BUILTIN_VEC_CTU,
+  ALTIVEC_BUILTIN_VEC_DST,
+  ALTIVEC_BUILTIN_VEC_DSTST,
+  ALTIVEC_BUILTIN_VEC_DSTSTT,
+  ALTIVEC_BUILTIN_VEC_DSTT,
+  ALTIVEC_BUILTIN_VEC_EXPTE,
+  ALTIVEC_BUILTIN_VEC_FLOOR,
+  ALTIVEC_BUILTIN_VEC_LD,
+  ALTIVEC_BUILTIN_VEC_LDE,
+  ALTIVEC_BUILTIN_VEC_LDL,
+  ALTIVEC_BUILTIN_VEC_LOGE,
+  ALTIVEC_BUILTIN_VEC_LVEBX,
+  ALTIVEC_BUILTIN_VEC_LVEHX,
+  ALTIVEC_BUILTIN_VEC_LVEWX,
+  ALTIVEC_BUILTIN_VEC_LVSL,
+  ALTIVEC_BUILTIN_VEC_LVSR,
+  ALTIVEC_BUILTIN_VEC_MADD,
+  ALTIVEC_BUILTIN_VEC_MADDS,
+  ALTIVEC_BUILTIN_VEC_MAX,
+  ALTIVEC_BUILTIN_VEC_MERGEH,
+  ALTIVEC_BUILTIN_VEC_MERGEL,
+  ALTIVEC_BUILTIN_VEC_MIN,
+  ALTIVEC_BUILTIN_VEC_MLADD,
+  ALTIVEC_BUILTIN_VEC_MPERM,
+  ALTIVEC_BUILTIN_VEC_MRADDS,
+  ALTIVEC_BUILTIN_VEC_MRGHB,
+  ALTIVEC_BUILTIN_VEC_MRGHH,
+  ALTIVEC_BUILTIN_VEC_MRGHW,
+  ALTIVEC_BUILTIN_VEC_MRGLB,
+  ALTIVEC_BUILTIN_VEC_MRGLH,
+  ALTIVEC_BUILTIN_VEC_MRGLW,
+  ALTIVEC_BUILTIN_VEC_MSUM,
+  ALTIVEC_BUILTIN_VEC_MSUMS,
+  ALTIVEC_BUILTIN_VEC_MTVSCR,
+  ALTIVEC_BUILTIN_VEC_MULE,
+  ALTIVEC_BUILTIN_VEC_MULO,
+  ALTIVEC_BUILTIN_VEC_NMSUB,
+  ALTIVEC_BUILTIN_VEC_NOR,
+  ALTIVEC_BUILTIN_VEC_OR,
+  ALTIVEC_BUILTIN_VEC_PACK,
+  ALTIVEC_BUILTIN_VEC_PACKPX,
+  ALTIVEC_BUILTIN_VEC_PACKS,
+  ALTIVEC_BUILTIN_VEC_PACKSU,
+  ALTIVEC_BUILTIN_VEC_PERM,
+  ALTIVEC_BUILTIN_VEC_RE,
+  ALTIVEC_BUILTIN_VEC_RL,
+  ALTIVEC_BUILTIN_VEC_ROUND,
+  ALTIVEC_BUILTIN_VEC_RSQRTE,
+  ALTIVEC_BUILTIN_VEC_SEL,
+  ALTIVEC_BUILTIN_VEC_SL,
+  ALTIVEC_BUILTIN_VEC_SLD,
+  ALTIVEC_BUILTIN_VEC_SLL,
+  ALTIVEC_BUILTIN_VEC_SLO,
+  ALTIVEC_BUILTIN_VEC_SPLAT,
+  ALTIVEC_BUILTIN_VEC_SPLAT_S16,
+  ALTIVEC_BUILTIN_VEC_SPLAT_S32,
+  ALTIVEC_BUILTIN_VEC_SPLAT_S8,
+  ALTIVEC_BUILTIN_VEC_SPLAT_U16,
+  ALTIVEC_BUILTIN_VEC_SPLAT_U32,
+  ALTIVEC_BUILTIN_VEC_SPLAT_U8,
+  ALTIVEC_BUILTIN_VEC_SPLTB,
+  ALTIVEC_BUILTIN_VEC_SPLTH,
+  ALTIVEC_BUILTIN_VEC_SPLTW,
+  ALTIVEC_BUILTIN_VEC_SR,
+  ALTIVEC_BUILTIN_VEC_SRA,
+  ALTIVEC_BUILTIN_VEC_SRL,
+  ALTIVEC_BUILTIN_VEC_SRO,
+  ALTIVEC_BUILTIN_VEC_ST,
+  ALTIVEC_BUILTIN_VEC_STE,
+  ALTIVEC_BUILTIN_VEC_STL,
+  ALTIVEC_BUILTIN_VEC_STVEBX,
+  ALTIVEC_BUILTIN_VEC_STVEHX,
+  ALTIVEC_BUILTIN_VEC_STVEWX,
+  ALTIVEC_BUILTIN_VEC_SUB,
+  ALTIVEC_BUILTIN_VEC_SUBC,
+  ALTIVEC_BUILTIN_VEC_SUBS,
+  ALTIVEC_BUILTIN_VEC_SUM2S,
+  ALTIVEC_BUILTIN_VEC_SUM4S,
+  ALTIVEC_BUILTIN_VEC_SUMS,
+  ALTIVEC_BUILTIN_VEC_TRUNC,
+  ALTIVEC_BUILTIN_VEC_UNPACKH,
+  ALTIVEC_BUILTIN_VEC_UNPACKL,
+  ALTIVEC_BUILTIN_VEC_VADDFP,
+  ALTIVEC_BUILTIN_VEC_VADDSBS,
+  ALTIVEC_BUILTIN_VEC_VADDSHS,
+  ALTIVEC_BUILTIN_VEC_VADDSWS,
+  ALTIVEC_BUILTIN_VEC_VADDUBM,
+  ALTIVEC_BUILTIN_VEC_VADDUBS,
+  ALTIVEC_BUILTIN_VEC_VADDUHM,
+  ALTIVEC_BUILTIN_VEC_VADDUHS,
+  ALTIVEC_BUILTIN_VEC_VADDUWM,
+  ALTIVEC_BUILTIN_VEC_VADDUWS,
+  ALTIVEC_BUILTIN_VEC_VAVGSB,
+  ALTIVEC_BUILTIN_VEC_VAVGSH,
+  ALTIVEC_BUILTIN_VEC_VAVGSW,
+  ALTIVEC_BUILTIN_VEC_VAVGUB,
+  ALTIVEC_BUILTIN_VEC_VAVGUH,
+  ALTIVEC_BUILTIN_VEC_VAVGUW,
+  ALTIVEC_BUILTIN_VEC_VCFSX,
+  ALTIVEC_BUILTIN_VEC_VCFUX,
+  ALTIVEC_BUILTIN_VEC_VCMPEQFP,
+  ALTIVEC_BUILTIN_VEC_VCMPEQUB,
+  ALTIVEC_BUILTIN_VEC_VCMPEQUH,
+  ALTIVEC_BUILTIN_VEC_VCMPEQUW,
+  ALTIVEC_BUILTIN_VEC_VCMPGTFP,
+  ALTIVEC_BUILTIN_VEC_VCMPGTSB,
+  ALTIVEC_BUILTIN_VEC_VCMPGTSH,
+  ALTIVEC_BUILTIN_VEC_VCMPGTSW,
+  ALTIVEC_BUILTIN_VEC_VCMPGTUB,
+  ALTIVEC_BUILTIN_VEC_VCMPGTUH,
+  ALTIVEC_BUILTIN_VEC_VCMPGTUW,
+  ALTIVEC_BUILTIN_VEC_VMAXFP,
+  ALTIVEC_BUILTIN_VEC_VMAXSB,
+  ALTIVEC_BUILTIN_VEC_VMAXSH,
+  ALTIVEC_BUILTIN_VEC_VMAXSW,
+  ALTIVEC_BUILTIN_VEC_VMAXUB,
+  ALTIVEC_BUILTIN_VEC_VMAXUH,
+  ALTIVEC_BUILTIN_VEC_VMAXUW,
+  ALTIVEC_BUILTIN_VEC_VMINFP,
+  ALTIVEC_BUILTIN_VEC_VMINSB,
+  ALTIVEC_BUILTIN_VEC_VMINSH,
+  ALTIVEC_BUILTIN_VEC_VMINSW,
+  ALTIVEC_BUILTIN_VEC_VMINUB,
+  ALTIVEC_BUILTIN_VEC_VMINUH,
+  ALTIVEC_BUILTIN_VEC_VMINUW,
+  ALTIVEC_BUILTIN_VEC_VMRGHB,
+  ALTIVEC_BUILTIN_VEC_VMRGHH,
+  ALTIVEC_BUILTIN_VEC_VMRGHW,
+  ALTIVEC_BUILTIN_VEC_VMRGLB,
+  ALTIVEC_BUILTIN_VEC_VMRGLH,
+  ALTIVEC_BUILTIN_VEC_VMRGLW,
+  ALTIVEC_BUILTIN_VEC_VMSUMMBM,
+  ALTIVEC_BUILTIN_VEC_VMSUMSHM,
+  ALTIVEC_BUILTIN_VEC_VMSUMSHS,
+  ALTIVEC_BUILTIN_VEC_VMSUMUBM,
+  ALTIVEC_BUILTIN_VEC_VMSUMUHM,
+  ALTIVEC_BUILTIN_VEC_VMSUMUHS,
+  ALTIVEC_BUILTIN_VEC_VMULESB,
+  ALTIVEC_BUILTIN_VEC_VMULESH,
+  ALTIVEC_BUILTIN_VEC_VMULEUB,
+  ALTIVEC_BUILTIN_VEC_VMULEUH,
+  ALTIVEC_BUILTIN_VEC_VMULOSB,
+  ALTIVEC_BUILTIN_VEC_VMULOSH,
+  ALTIVEC_BUILTIN_VEC_VMULOUB,
+  ALTIVEC_BUILTIN_VEC_VMULOUH,
+  ALTIVEC_BUILTIN_VEC_VPKSHSS,
+  ALTIVEC_BUILTIN_VEC_VPKSHUS,
+  ALTIVEC_BUILTIN_VEC_VPKSWSS,
+  ALTIVEC_BUILTIN_VEC_VPKSWUS,
+  ALTIVEC_BUILTIN_VEC_VPKUHUM,
+  ALTIVEC_BUILTIN_VEC_VPKUHUS,
+  ALTIVEC_BUILTIN_VEC_VPKUWUM,
+  ALTIVEC_BUILTIN_VEC_VPKUWUS,
+  ALTIVEC_BUILTIN_VEC_VRLB,
+  ALTIVEC_BUILTIN_VEC_VRLH,
+  ALTIVEC_BUILTIN_VEC_VRLW,
+  ALTIVEC_BUILTIN_VEC_VSLB,
+  ALTIVEC_BUILTIN_VEC_VSLH,
+  ALTIVEC_BUILTIN_VEC_VSLW,
+  ALTIVEC_BUILTIN_VEC_VSPLTB,
+  ALTIVEC_BUILTIN_VEC_VSPLTH,
+  ALTIVEC_BUILTIN_VEC_VSPLTW,
+  ALTIVEC_BUILTIN_VEC_VSRAB,
+  ALTIVEC_BUILTIN_VEC_VSRAH,
+  ALTIVEC_BUILTIN_VEC_VSRAW,
+  ALTIVEC_BUILTIN_VEC_VSRB,
+  ALTIVEC_BUILTIN_VEC_VSRH,
+  ALTIVEC_BUILTIN_VEC_VSRW,
+  ALTIVEC_BUILTIN_VEC_VSUBFP,
+  ALTIVEC_BUILTIN_VEC_VSUBSBS,
+  ALTIVEC_BUILTIN_VEC_VSUBSHS,
+  ALTIVEC_BUILTIN_VEC_VSUBSWS,
+  ALTIVEC_BUILTIN_VEC_VSUBUBM,
+  ALTIVEC_BUILTIN_VEC_VSUBUBS,
+  ALTIVEC_BUILTIN_VEC_VSUBUHM,
+  ALTIVEC_BUILTIN_VEC_VSUBUHS,
+  ALTIVEC_BUILTIN_VEC_VSUBUWM,
+  ALTIVEC_BUILTIN_VEC_VSUBUWS,
+  ALTIVEC_BUILTIN_VEC_VSUM4SBS,
+  ALTIVEC_BUILTIN_VEC_VSUM4SHS,
+  ALTIVEC_BUILTIN_VEC_VSUM4UBS,
+  ALTIVEC_BUILTIN_VEC_VUPKHPX,
+  ALTIVEC_BUILTIN_VEC_VUPKHSB,
+  ALTIVEC_BUILTIN_VEC_VUPKHSH,
+  ALTIVEC_BUILTIN_VEC_VUPKLPX,
+  ALTIVEC_BUILTIN_VEC_VUPKLSB,
+  ALTIVEC_BUILTIN_VEC_VUPKLSH,
+  ALTIVEC_BUILTIN_VEC_XOR,
+  ALTIVEC_BUILTIN_VEC_STEP,
+  ALTIVEC_BUILTIN_OVERLOADED_LAST = ALTIVEC_BUILTIN_VEC_STEP,
+
   /* SPE builtins.  */
-  SPE_BUILTIN_EVADDW,
+  SPE_BUILTIN_EVADDW,
   SPE_BUILTIN_EVAND,
   SPE_BUILTIN_EVANDC,
   SPE_BUILTIN_EVDIVWS,
@@ -3134,5 +2890,84 @@ enum rs6000_builtins
   SPE_BUILTIN_EVMWHGUMIAN,
   SPE_BUILTIN_MTSPEFSCR,
   SPE_BUILTIN_MFSPEFSCR,
-  SPE_BUILTIN_BRINC
+  SPE_BUILTIN_BRINC,
+
+  RS6000_BUILTIN_COUNT
 };
+
+enum rs6000_builtin_type_index
+{
+  RS6000_BTI_NOT_OPAQUE,
+  RS6000_BTI_opaque_V2SI,
+  RS6000_BTI_opaque_V2SF,
+  RS6000_BTI_opaque_p_V2SI,
+  RS6000_BTI_opaque_V4SI,
+  RS6000_BTI_V16QI,
+  RS6000_BTI_V2SI,
+  RS6000_BTI_V2SF,
+  RS6000_BTI_V4HI,
+  RS6000_BTI_V4SI,
+  RS6000_BTI_V4SF,
+  RS6000_BTI_V8HI,
+  RS6000_BTI_unsigned_V16QI,
+  RS6000_BTI_unsigned_V8HI,
+  RS6000_BTI_unsigned_V4SI,
+  RS6000_BTI_bool_char,          /* __bool char */
+  RS6000_BTI_bool_short,         /* __bool short */
+  RS6000_BTI_bool_int,           /* __bool int */
+  RS6000_BTI_pixel,              /* __pixel */
+  RS6000_BTI_bool_V16QI,         /* __vector __bool char */
+  RS6000_BTI_bool_V8HI,          /* __vector __bool short */
+  RS6000_BTI_bool_V4SI,          /* __vector __bool int */
+  RS6000_BTI_pixel_V8HI,         /* __vector __pixel */
+  RS6000_BTI_long,              /* long_integer_type_node */
+  RS6000_BTI_unsigned_long,      /* long_unsigned_type_node */
+  RS6000_BTI_INTQI,             /* intQI_type_node */
+  RS6000_BTI_UINTQI,            /* unsigned_intQI_type_node */
+  RS6000_BTI_INTHI,             /* intHI_type_node */
+  RS6000_BTI_UINTHI,            /* unsigned_intHI_type_node */
+  RS6000_BTI_INTSI,             /* intSI_type_node */
+  RS6000_BTI_UINTSI,            /* unsigned_intSI_type_node */
+  RS6000_BTI_float,             /* float_type_node */
+  RS6000_BTI_void,              /* void_type_node */
+  RS6000_BTI_MAX
+};
+
+
+#define opaque_V2SI_type_node         (rs6000_builtin_types[RS6000_BTI_opaque_V2SI])
+#define opaque_V2SF_type_node         (rs6000_builtin_types[RS6000_BTI_opaque_V2SF])
+#define opaque_p_V2SI_type_node       (rs6000_builtin_types[RS6000_BTI_opaque_p_V2SI])
+#define opaque_V4SI_type_node         (rs6000_builtin_types[RS6000_BTI_opaque_V4SI])
+#define V16QI_type_node               (rs6000_builtin_types[RS6000_BTI_V16QI])
+#define V2SI_type_node                (rs6000_builtin_types[RS6000_BTI_V2SI])
+#define V2SF_type_node                (rs6000_builtin_types[RS6000_BTI_V2SF])
+#define V4HI_type_node                (rs6000_builtin_types[RS6000_BTI_V4HI])
+#define V4SI_type_node                (rs6000_builtin_types[RS6000_BTI_V4SI])
+#define V4SF_type_node                (rs6000_builtin_types[RS6000_BTI_V4SF])
+#define V8HI_type_node                (rs6000_builtin_types[RS6000_BTI_V8HI])
+#define unsigned_V16QI_type_node      (rs6000_builtin_types[RS6000_BTI_unsigned_V16QI])
+#define unsigned_V8HI_type_node       (rs6000_builtin_types[RS6000_BTI_unsigned_V8HI])
+#define unsigned_V4SI_type_node       (rs6000_builtin_types[RS6000_BTI_unsigned_V4SI])
+#define bool_char_type_node           (rs6000_builtin_types[RS6000_BTI_bool_char])
+#define bool_short_type_node          (rs6000_builtin_types[RS6000_BTI_bool_short])
+#define bool_int_type_node            (rs6000_builtin_types[RS6000_BTI_bool_int])
+#define pixel_type_node               (rs6000_builtin_types[RS6000_BTI_pixel])
+#define bool_V16QI_type_node         (rs6000_builtin_types[RS6000_BTI_bool_V16QI])
+#define bool_V8HI_type_node          (rs6000_builtin_types[RS6000_BTI_bool_V8HI])
+#define bool_V4SI_type_node          (rs6000_builtin_types[RS6000_BTI_bool_V4SI])
+#define pixel_V8HI_type_node         (rs6000_builtin_types[RS6000_BTI_pixel_V8HI])
+
+#define long_integer_type_internal_node  (rs6000_builtin_types[RS6000_BTI_long])
+#define long_unsigned_type_internal_node (rs6000_builtin_types[RS6000_BTI_unsigned_long])
+#define intQI_type_internal_node        (rs6000_builtin_types[RS6000_BTI_INTQI])
+#define uintQI_type_internal_node       (rs6000_builtin_types[RS6000_BTI_UINTQI])
+#define intHI_type_internal_node        (rs6000_builtin_types[RS6000_BTI_INTHI])
+#define uintHI_type_internal_node       (rs6000_builtin_types[RS6000_BTI_UINTHI])
+#define intSI_type_internal_node        (rs6000_builtin_types[RS6000_BTI_INTSI])
+#define uintSI_type_internal_node       (rs6000_builtin_types[RS6000_BTI_UINTSI])
+#define float_type_internal_node        (rs6000_builtin_types[RS6000_BTI_float])
+#define void_type_internal_node                 (rs6000_builtin_types[RS6000_BTI_void])
+
+extern GTY(()) tree rs6000_builtin_types[RS6000_BTI_MAX];
+extern GTY(()) tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
+