OSDN Git Service

* config/rs6000/rs6000.h (REG_ALLOC_ORDER): Add vrsave.
[pf3gnuchains/gcc-fork.git] / gcc / config / rs6000 / rs6000.h
index db11084..a149cf2 100644 (file)
@@ -1,5 +1,6 @@
 /* Definitions of target machine for GNU compiler, for IBM RS/6000.
-   Copyright (C) 1992, 93-8, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+   2000, 2001 Free Software Foundation, Inc.
    Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
 
 This file is part of GNU CC.
@@ -21,13 +22,24 @@ Boston, MA 02111-1307, USA.  */
 
 
 /* Note that some other tm.h files include this one and then override
-   many of the definitions that relate to assembler syntax.  */
+   many of the definitions.  */
 
+/* Definitions for the object file format.  These are set at
+   compile-time.  */
 
-/* Names to predefine in the preprocessor for this target machine.  */
+#define OBJECT_XCOFF 1
+#define OBJECT_ELF 2
+#define OBJECT_PEF 3
+#define OBJECT_MACHO 4
 
-#define CPP_PREDEFINES "-D_IBMR2 -D_POWER -D_AIX -D_AIX32 -D_LONG_LONG \
--Asystem(unix) -Asystem(aix) -Acpu(rs6000) -Amachine(rs6000)"
+#define TARGET_ELF (TARGET_OBJECT_FORMAT == OBJECT_ELF)
+#define TARGET_XCOFF (TARGET_OBJECT_FORMAT == OBJECT_XCOFF)
+#define TARGET_MACOS (TARGET_OBJECT_FORMAT == OBJECT_PEF)
+#define TARGET_MACHO (TARGET_OBJECT_FORMAT == OBJECT_MACHO)
+
+#ifndef TARGET_AIX
+#define TARGET_AIX 0
+#endif
 
 /* Print subsidiary information on the compiler version in use.  */
 #define TARGET_VERSION ;
@@ -37,21 +49,6 @@ Boston, MA 02111-1307, USA.  */
 #define TARGET_CPU_DEFAULT ((char *)0)
 #endif
 
-/* Tell the assembler to assume that all undefined names are external.
-
-   Don't do this until the fixed IBM assembler is more generally available.
-   When this becomes permanently defined, the ASM_OUTPUT_EXTERNAL,
-   ASM_OUTPUT_EXTERNAL_LIBCALL, and RS6000_OUTPUT_BASENAME macros will no
-   longer be needed.  Also, the extern declaration of mcount in ASM_FILE_START
-   will no longer be needed.  */
-
-/* #define ASM_SPEC "-u %(asm_cpu)" */
-
-/* Define appropriate architecture macros for preprocessor depending on
-   target switches.  */
-
-#define CPP_SPEC "%{posix: -D_POSIX_SOURCE} %(cpp_cpu)"
-
 /* Common CPP definitions used by CPP_SPEC among the various targets
    for handling -mcpu=xxx switches.  */
 #define CPP_CPU_SPEC \
@@ -86,27 +83,8 @@ Boston, MA 02111-1307, USA.  */
 %{mcpu=801: -D_ARCH_PPC} \
 %{mcpu=821: -D_ARCH_PPC} \
 %{mcpu=823: -D_ARCH_PPC} \
-%{mcpu=860: -D_ARCH_PPC}"
-
-#ifndef CPP_DEFAULT_SPEC
-#define CPP_DEFAULT_SPEC "-D_ARCH_PWR"
-#endif
-
-#ifndef CPP_SYSV_SPEC
-#define CPP_SYSV_SPEC ""
-#endif
-
-#ifndef CPP_ENDIAN_SPEC
-#define CPP_ENDIAN_SPEC ""
-#endif
-
-#ifndef CPP_ENDIAN_DEFAULT_SPEC
-#define CPP_ENDIAN_DEFAULT_SPEC ""
-#endif
-
-#ifndef CPP_SYSV_DEFAULT_SPEC
-#define CPP_SYSV_DEFAULT_SPEC ""
-#endif
+%{mcpu=860: -D_ARCH_PPC} \
+%{maltivec: -D__ALTIVEC__}"
 
 /* Common ASM definitions used by ASM_SPEC among the various targets
    for handling -mcpu=xxx switches.  */
@@ -144,9 +122,9 @@ Boston, MA 02111-1307, USA.  */
 %{mcpu=823: -mppc} \
 %{mcpu=860: -mppc}"
 
-#ifndef ASM_DEFAULT_SPEC
+#define CPP_DEFAULT_SPEC ""
+
 #define ASM_DEFAULT_SPEC ""
-#endif
 
 /* This macro defines names of additional specifications to put in the specs
    that can be used in various specifications like CC1_SPEC.  Its definition
@@ -158,65 +136,15 @@ Boston, MA 02111-1307, USA.  */
 
    Do not define this macro if it does not need to do anything.  */
 
-#ifndef SUBTARGET_EXTRA_SPECS
 #define SUBTARGET_EXTRA_SPECS
-#endif
 
 #define EXTRA_SPECS                                                    \
   { "cpp_cpu",                 CPP_CPU_SPEC },                         \
   { "cpp_default",             CPP_DEFAULT_SPEC },                     \
-  { "cpp_sysv",                        CPP_SYSV_SPEC },                        \
-  { "cpp_sysv_default",                CPP_SYSV_DEFAULT_SPEC },                \
-  { "cpp_endian_default",      CPP_ENDIAN_DEFAULT_SPEC },              \
-  { "cpp_endian",              CPP_ENDIAN_SPEC },                      \
   { "asm_cpu",                 ASM_CPU_SPEC },                         \
   { "asm_default",             ASM_DEFAULT_SPEC },                     \
-  { "link_syscalls",           LINK_SYSCALLS_SPEC },                   \
-  { "link_libg",               LINK_LIBG_SPEC },                       \
   SUBTARGET_EXTRA_SPECS
 
-/* Default location of syscalls.exp under AIX */
-#ifndef CROSS_COMPILE
-#define LINK_SYSCALLS_SPEC "-bI:/lib/syscalls.exp"
-#else
-#define LINK_SYSCALLS_SPEC ""
-#endif
-
-/* Default location of libg.exp under AIX */
-#ifndef CROSS_COMPILE
-#define LINK_LIBG_SPEC "-bexport:/usr/lib/libg.exp"
-#else
-#define LINK_LIBG_SPEC ""
-#endif
-
-/* Define the options for the binder: Start text at 512, align all segments
-   to 512 bytes, and warn if there is text relocation.
-
-   The -bhalt:4 option supposedly changes the level at which ld will abort,
-   but it also suppresses warnings about multiply defined symbols and is
-   used by the AIX cc command.  So we use it here.
-
-   -bnodelcsect undoes a poor choice of default relating to multiply-defined
-   csects.  See AIX documentation for more information about this.
-
-   -bM:SRE tells the linker that the output file is Shared REusable.  Note
-   that to actually build a shared library you will also need to specify an
-   export list with the -Wl,-bE option.  */
-
-#define LINK_SPEC "-T512 -H512 %{!r:-btextro} -bhalt:4 -bnodelcsect\
-   %{static:-bnso %(link_syscalls) } \
-   %{!shared:%{g*: %(link_libg) }} %{shared:-bM:SRE}"
-
-/* Profiled library versions are used by linking with special directories.  */
-#define LIB_SPEC "%{pg:-L/lib/profiled -L/usr/lib/profiled}\
-   %{p:-L/lib/profiled -L/usr/lib/profiled} %{!shared:%{g*:-lg}} -lc"
-
-/* gcc must do the search itself to find libgcc.a, not use -l.  */
-#define LIBGCC_SPEC "libgcc.a%s"
-
-/* Don't turn -B into -L if the argument specifies a relative file name.  */
-#define RELATIVE_PREFIX_NOT_LINKDIR
-
 /* Architecture type.  */
 
 extern int target_flags;
@@ -279,12 +207,20 @@ extern int target_flags;
 /* Disable fused multiply/add operations */
 #define MASK_NO_FUSED_MADD     0x00020000
 
+/* Nonzero if we need to schedule the prolog and epilog.  */
+#define MASK_SCHED_PROLOG      0x00040000
+
+/* Use AltiVec instructions.  */
+#define MASK_ALTIVEC           0x00080000
+
+/* Enhance the current ABI with AltiVec extensions.  */
+#define MASK_ALTIVEC_ABI       0x00100000
+
 #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_POWERPC64       (target_flags & MASK_POWERPC64)
 #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)
@@ -297,46 +233,27 @@ extern int target_flags;
 #define TARGET_STRING_SET      (target_flags & MASK_STRING_SET)
 #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_ALTIVEC_ABI     (target_flags & MASK_ALTIVEC_ABI)
 
 #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)
 
-/* Pseudo target to indicate whether the object format is ELF
-   (to get around not having conditional compilation in the md file)  */
-#ifndef        TARGET_ELF
-#define        TARGET_ELF              0
-#endif
-
-/* If this isn't V.4, don't support -mno-toc.  */
-#ifndef TARGET_NO_TOC
-#define TARGET_NO_TOC          0
-#define        TARGET_TOC              1
-#endif
-
-/* Pseudo target to say whether this is Windows NT */
-#ifndef        TARGET_WINDOWS_NT
-#define        TARGET_WINDOWS_NT 0
-#endif
-
-/* Pseudo target to say whether this is MAC */
-#ifndef        TARGET_MACOS
-#define        TARGET_MACOS 0
-#endif
-
-/* Pseudo target to say whether this is AIX */
-#ifndef TARGET_AIX
-#if (TARGET_ELF || TARGET_WINDOWS_NT || TARGET_MACOS)
-#define TARGET_AIX 0
+#ifdef IN_LIBGCC2
+/* For libgcc2 we make sure this is a compile time constant */
+#ifdef __64BIT__
+#define TARGET_POWERPC64       1
 #else
-#define TARGET_AIX 1
+#define TARGET_POWERPC64       0
 #endif
+#else
+#define TARGET_POWERPC64       (target_flags & MASK_POWERPC64)
 #endif
 
-#ifndef TARGET_XL_CALL
 #define TARGET_XL_CALL 0
-#endif
 
 /* Run-time compilation parameters selecting different hardware subsets.
 
@@ -346,55 +263,100 @@ extern int target_flags;
    where VALUE is the bits to set or minus the bits to clear.
    An empty string NAME is used to identify the default VALUE.  */
 
-/* This is meant to be redefined in the host dependent files */
-#ifndef SUBTARGET_SWITCHES
-#define SUBTARGET_SWITCHES
-#endif
-
 #define TARGET_SWITCHES                                                        \
- {{"power",            MASK_POWER  | MASK_MULTIPLE | MASK_STRING},     \
+ {{"power",            MASK_POWER  | MASK_MULTIPLE | MASK_STRING,      \
+                       N_("Use POWER instruction set")},               \
   {"power2",           (MASK_POWER | MASK_MULTIPLE | MASK_STRING       \
-                        | MASK_POWER2)},                               \
-  {"no-power2",                - MASK_POWER2},                                 \
+                        | 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)},                             \
-  {"powerpc",          MASK_POWERPC},                                  \
+                          | 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)},        \
-  {"powerpc-gpopt",    MASK_POWERPC | MASK_PPC_GPOPT},                 \
-  {"no-powerpc-gpopt", - MASK_PPC_GPOPT},                              \
-  {"powerpc-gfxopt",   MASK_POWERPC | MASK_PPC_GFXOPT},                \
-  {"no-powerpc-gfxopt",        - MASK_PPC_GFXOPT},                             \
-  {"powerpc64",                MASK_POWERPC64},                                \
-  {"no-powerpc64",     - MASK_POWERPC64},                              \
-  {"new-mnemonics",    MASK_NEW_MNEMONICS},                            \
-  {"old-mnemonics",    -MASK_NEW_MNEMONICS},                           \
+                          | 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_("Don't 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_("Don't use PowerPC Graphics group optional instructions")},\
+  {"powerpc64",                MASK_POWERPC64,                                 \
+                       N_("Use PowerPC-64 instruction set")},          \
+  {"no-powerpc64",     - MASK_POWERPC64,                               \
+                       N_("Don't use PowerPC-64 instruction set")},    \
+  {"altivec",          MASK_ALTIVEC,                                   \
+                       N_("Use AltiVec instructions.")},               \
+  {"no-altivec",       - MASK_ALTIVEC,                                 \
+                       N_("Don't 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)},                        \
-  {"fp-in-toc",                - MASK_NO_FP_IN_TOC},                           \
-  {"no-fp-in-toc",     MASK_NO_FP_IN_TOC},                             \
-  {"sum-in-toc",       - MASK_NO_SUM_IN_TOC},                          \
-  {"no-sum-in-toc",    MASK_NO_SUM_IN_TOC},                            \
-  {"minimal-toc",      MASK_MINIMAL_TOC},                              \
-  {"minimal-toc",      - (MASK_NO_FP_IN_TOC | MASK_NO_SUM_IN_TOC)},    \
-  {"no-minimal-toc",   - MASK_MINIMAL_TOC},                            \
-  {"hard-float",       - MASK_SOFT_FLOAT},                             \
-  {"soft-float",       MASK_SOFT_FLOAT},                               \
-  {"multiple",         MASK_MULTIPLE | MASK_MULTIPLE_SET},             \
-  {"no-multiple",      - MASK_MULTIPLE},                               \
-  {"no-multiple",      MASK_MULTIPLE_SET},                             \
-  {"string",           MASK_STRING | MASK_STRING_SET},                 \
-  {"no-string",                - MASK_STRING},                                 \
-  {"no-string",                MASK_STRING_SET},                               \
-  {"update",           - MASK_NO_UPDATE},                              \
-  {"no-update",                MASK_NO_UPDATE},                                \
-  {"fused-madd",       - MASK_NO_FUSED_MADD},                          \
-  {"no-fused-madd",    MASK_NO_FUSED_MADD},                            \
+                          | 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_("Don't 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_("Don't 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 fp")},                         \
+  {"soft-float",       MASK_SOFT_FLOAT,                                \
+                       N_("Do not use hardware fp")},                  \
+  {"multiple",         MASK_MULTIPLE | MASK_MULTIPLE_SET,              \
+                       N_("Generate load/store multiple instructions")},       \
+  {"no-multiple",      - MASK_MULTIPLE,                                \
+                       N_("Do not generate load/store multiple instructions")},\
+  {"no-multiple",      MASK_MULTIPLE_SET,                              \
+                       ""},                                            \
+  {"string",           MASK_STRING | MASK_STRING_SET,                  \
+                       N_("Generate string instructions for block moves")},\
+  {"no-string",                - MASK_STRING,                                  \
+                       N_("Do not generate string instructions for block moves")},\
+  {"no-string",                MASK_STRING_SET,                                \
+                       ""},                                            \
+  {"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_("Don't generate fused multiply/add instructions")},\
+  {"sched-prolog",      MASK_SCHED_PROLOG,                              \
+                       ""},                                            \
+  {"no-sched-prolog",   -MASK_SCHED_PROLOG,                             \
+                       N_("Don't schedule the start and end of the procedure")},\
+  {"sched-epilog",      MASK_SCHED_PROLOG,                              \
+                       ""},                                            \
+  {"no-sched-epilog",   -MASK_SCHED_PROLOG,                             \
+                       ""},                                            \
   SUBTARGET_SWITCHES                                                   \
-  {"",                 TARGET_DEFAULT}}
+  {"",                 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
  {
@@ -409,7 +371,9 @@ enum processor_type
    PROCESSOR_PPC604e,
    PROCESSOR_PPC620,
    PROCESSOR_PPC630,
-   PROCESSOR_PPC750
+   PROCESSOR_PPC750,
+   PROCESSOR_PPC7400,
+   PROCESSOR_PPC7450
 };
 
 extern enum processor_type rs6000_cpu;
@@ -429,7 +393,7 @@ extern enum processor_type rs6000_cpu;
 
 /* Specify the dialect of assembler to use.  New mnemonics is dialect one
    and the old mnemonics are dialect zero.  */
-#define ASSEMBLER_DIALECT TARGET_NEW_MNEMONICS ? 1 : 0
+#define ASSEMBLER_DIALECT (TARGET_NEW_MNEMONICS ? 1 : 0)
 
 /* This macro is similar to `TARGET_SWITCHES' but defines names of
    command options that have values.  Its definition is an
@@ -449,17 +413,17 @@ extern enum processor_type rs6000_cpu;
        #define TARGET_OPTIONS { { "short-data-", &m88k_short_data } }  */
 
 /* This is meant to be overridden in target specific files.  */
-#ifndef SUBTARGET_OPTIONS
 #define        SUBTARGET_OPTIONS
-#endif
 
-#define TARGET_OPTIONS                         \
-{                                              \
-   {"cpu=",  &rs6000_select[1].string},                \
-   {"tune=", &rs6000_select[2].string},                \
-   {"debug-", &rs6000_debug_name},             \
-   {"debug=", &rs6000_debug_name},             \
-   SUBTARGET_OPTIONS                           \
+#define TARGET_OPTIONS                                                 \
+{                                                                      \
+   {"cpu=",  &rs6000_select[1].string,                                 \
+    N_("Use features of and schedule code for given CPU") },           \
+   {"tune=", &rs6000_select[2].string,                                 \
+    N_("Schedule code for given CPU") },                               \
+   {"debug=", &rs6000_debug_name, N_("Enable debug output") },         \
+   {"abi=", &rs6000_abi_string, N_("Specify ABI to use") },            \
+   SUBTARGET_OPTIONS                                                   \
 }
 
 /* rs6000_select[0] is reserved for the default cpu defined via --with-cpu */
@@ -474,7 +438,8 @@ struct rs6000_cpu_select
 extern struct rs6000_cpu_select rs6000_select[];
 
 /* Debug support */
-extern const char *rs6000_debug_name;          /* Name for -mdebug-xxxx option */
+extern const char *rs6000_debug_name;  /* Name for -mdebug-xxxx option */
+extern const char *rs6000_abi_string;  /* for -mabi={sysv,darwin,solaris,eabi,aix,altivec} */
 extern int rs6000_debug_stack;         /* debug stack applications */
 extern int rs6000_debug_arg;           /* debug argument handling */
 
@@ -497,7 +462,6 @@ extern int rs6000_debug_arg;                /* debug argument handling */
 /* Define this to change the optimizations performed by default.  */
 #define OPTIMIZATION_OPTIONS(LEVEL,SIZE) optimization_options(LEVEL,SIZE)
 
-
 /* Show we can debug even without a frame pointer.  */
 #define CAN_DEBUG_WITHOUT_FP
 \f
@@ -556,10 +520,14 @@ extern int rs6000_debug_arg;              /* debug argument handling */
 #define UNITS_PER_WORD (! TARGET_POWERPC64 ? 4 : 8)
 #define MIN_UNITS_PER_WORD 4
 #define UNITS_PER_FP_WORD 8
+#define UNITS_PER_ALTIVEC_WORD 16
 
 /* Type used for ptrdiff_t, as a string used in a declaration.  */
 #define PTRDIFF_TYPE "int"
 
+/* Type used for size_t, as a string used in a declaration.  */
+#define SIZE_TYPE "long unsigned int"
+
 /* Type used for wchar_t, as a string used in a declaration.  */
 #define WCHAR_TYPE "short unsigned int"
 
@@ -617,20 +585,23 @@ extern int rs6000_debug_arg;              /* debug argument handling */
 #define PARM_BOUNDARY (TARGET_32BIT ? 32 : 64)
 
 /* Boundary (in *bits*) on which stack pointer should be aligned.  */
-#define STACK_BOUNDARY (TARGET_32BIT ? 64 : 128)
+#define STACK_BOUNDARY ((TARGET_32BIT && !TARGET_ALTIVEC_ABI) ? 64 : 128)
 
 /* Allocation boundary (in *bits*) for the code of a function.  */
 #define FUNCTION_BOUNDARY 32
 
 /* No data type wants to be aligned rounder than this.  */
-#define BIGGEST_ALIGNMENT 64
+#define BIGGEST_ALIGNMENT 128
 
-/* AIX word-aligns FP doubles but doubleword-aligns 64-bit ints.  */
-#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
-  (TYPE_MODE (TREE_CODE (TREE_TYPE (FIELD)) == ARRAY_TYPE \
-             ? get_inner_array_type (FIELD) \
-             : TREE_TYPE (FIELD)) == DFmode \
-   ? MIN ((COMPUTED), 32) : (COMPUTED))
+/* A C expression to compute the alignment for a variables in the
+   local store.  TYPE is the data type, and ALIGN is the alignment
+   that the object would ordinarily have.  */
+#define LOCAL_ALIGNMENT(TYPE, ALIGN)                           \
+       ((TARGET_ALTIVEC                                        \
+         && TREE_CODE (TYPE)) == VECTOR_TYPE ? 128 : ALIGN)
+
+/* Handle #pragma pack.  */
+#define HANDLE_PRAGMA_PACK 1
 
 /* Alignment of field after `int : 0' in a structure.  */
 #define EMPTY_FIELD_BOUNDARY 32
@@ -641,31 +612,30 @@ extern int rs6000_debug_arg;              /* debug argument handling */
 /* A bitfield declared as `int' forces `int' alignment for the struct.  */
 #define PCC_BITFIELD_TYPE_MATTERS 1
 
-/* AIX increases natural record alignment to doubleword if the first
-   field is an FP double while the FP fields remain word aligned.  */
-#define ROUND_TYPE_ALIGN(STRUCT, COMPUTED, SPECIFIED)  \
-  ((TREE_CODE (STRUCT) == RECORD_TYPE                  \
-    || TREE_CODE (STRUCT) == UNION_TYPE                        \
-    || TREE_CODE (STRUCT) == QUAL_UNION_TYPE)          \
-   && TYPE_FIELDS (STRUCT) != 0                                \
-   && DECL_MODE (TYPE_FIELDS (STRUCT)) == DFmode       \
-   ? MAX (MAX ((COMPUTED), (SPECIFIED)), BIGGEST_ALIGNMENT) \
-   : MAX ((COMPUTED), (SPECIFIED)))
-
 /* Make strings word-aligned so strcpy from constants will be faster.  */
 #define CONSTANT_ALIGNMENT(EXP, ALIGN)  \
   (TREE_CODE (EXP) == STRING_CST       \
    && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
 
-/* Make arrays of chars word-aligned for the same reasons.  */
+/* Make arrays of chars word-aligned for the same reasons.
+   Align vectors to 128 bits.  */
 #define DATA_ALIGNMENT(TYPE, ALIGN)            \
-  (TREE_CODE (TYPE) == ARRAY_TYPE              \
+  (TREE_CODE (TYPE) == VECTOR_TYPE ? 128       \
+   : TREE_CODE (TYPE) == ARRAY_TYPE            \
    && TYPE_MODE (TREE_TYPE (TYPE)) == QImode   \
    && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
 
 /* Non-zero if move instructions will actually fail to work
    when given unaligned data.  */
 #define STRICT_ALIGNMENT 0
+
+/* Define this macro to be the value 1 if unaligned accesses have a cost
+   many times greater than aligned accesses, for example if they are
+   emulated in a trap handler.  */
+#define SLOW_UNALIGNED_ACCESS(MODE, ALIGN)                     \
+   ((STRICT_ALIGNMENT                                          \
+     || (((MODE) == SFmode || (MODE) == DFmode || (MODE) == DImode) \
+         && (ALIGN) < 32)) ? 1 : 0)
 \f
 /* Standard register usage.  */
 
@@ -689,27 +659,35 @@ extern int rs6000_debug_arg;              /* debug argument handling */
    a register, in order to work around problems in allocating stack storage
    in inline functions.  */
 
-#define FIRST_PSEUDO_REGISTER 77
+#define FIRST_PSEUDO_REGISTER 110
+
+/* This must not decrease, for backwards compatibility.  If
+   FIRST_PSEUDO_REGISTER increases, this should as well.  */
+/* fixme: this needs to be defined to "TARGET_ALTIVEC_ABI ? 110 : 77"
+   and then fix usages of DWARF_FRAME_REGISTERS to work.  */
+#define DWARF_FRAME_REGISTERS 77
 
 /* 1 for registers that have pervasive standard uses
    and are not available for the register allocator.
 
-   On RS/6000, r1 is used for the stack and r2 is used as the TOC pointer.
+   On RS/6000, r1 is used for the stack.  On Darwin, r2 is available
+   as a local register; for all other OS's r2 is the TOC pointer.
 
    cr5 is not supposed to be used.
 
    On System V implementations, r13 is fixed and not available for use.  */
 
-#ifndef FIXED_R13
-#define FIXED_R13 0
-#endif
-
 #define FIXED_REGISTERS  \
-  {0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, FIXED_R13, 0, 0, \
+  {0, 1, FIXED_R2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, FIXED_R13, 0, 0, \
+   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+   0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1,         \
+   /* AltiVec registers.  */                      \
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
-   0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1}
+   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+   0                                              \
+}
 
 /* 1 for registers not available across function calls.
    These must include the FIXED_REGISTERS and also any
@@ -723,7 +701,25 @@ extern int rs6000_debug_arg;               /* debug argument handling */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, \
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
-   1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1}
+   1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1,         \
+   /* AltiVec registers.  */                      \
+   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
+#define CR0_REGNO    68
+#define CR1_REGNO    69
+#define CR2_REGNO    70
+#define CR3_REGNO    71
+#define CR4_REGNO    72
+#define MAX_CR_REGNO 75
+#define XER_REGNO    76
+#define FIRST_ALTIVEC_REGNO    77
+#define LAST_ALTIVEC_REGNO     108
+#define VRSAVE_REGNO           109
 
 /* List the order in which to allocate registers.  Each register must be
    listed once, even those in FIXED_REGISTERS.
@@ -746,7 +742,16 @@ extern int rs6000_debug_arg;               /* debug argument handling */
        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, fpmem (fixed)  */
+        cr5, r1, r2, ap, xer, vrsave (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)
+*/
+                                               
 
 #define REG_ALLOC_ORDER                                        \
   {32,                                                         \
@@ -761,7 +766,15 @@ extern int rs6000_debug_arg;               /* debug argument handling */
    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, 2, 67, 76}
+   73, 1, 2, 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                                             \
+}
 
 /* True if register is floating-point.  */
 #define FP_REGNO_P(N) ((N) >= 32 && (N) <= 63)
@@ -769,18 +782,17 @@ extern int rs6000_debug_arg;              /* debug argument handling */
 /* True if register is a condition register.  */
 #define CR_REGNO_P(N) ((N) >= 68 && (N) <= 75)
 
-/* True if register is condition register 0.  */
-#define CR0_REGNO_P(N) ((N) == 68)
-
 /* True if register is a condition register, but not cr0.  */
 #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) == 67)
+#define INT_REGNO_P(N) ((N) <= 31 || (N) == ARG_POINTER_REGNUM)
 
-/* True if register is the temporary memory location used for int/float
-   conversion.  */
-#define FPMEM_REGNO_P(N) ((N) == FPMEM_REGNUM)
+/* True if register is the XER register.  */
+#define XER_REGNO_P(N) ((N) == XER_REGNO)
+
+/* True if register is an AltiVec register.  */
+#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.
@@ -791,10 +803,25 @@ extern int rs6000_debug_arg;              /* debug argument handling */
    PowerPC64 GPRs and FPRs point register holds 64 bits worth.  */
 
 #define HARD_REGNO_NREGS(REGNO, MODE)                                  \
-  (FP_REGNO_P (REGNO) || FPMEM_REGNO_P (REGNO)                         \
+  (FP_REGNO_P (REGNO)                                                  \
    ? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_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))
 
+#define ALTIVEC_VECTOR_MODE(MODE)      \
+       ((MODE) == V16QImode            \
+        || (MODE) == V8HImode          \
+        || (MODE) == V4SFmode          \
+        || (MODE) == V4SImode)
+
+/* 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_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 the float
    registers only can hold floating modes and DImode, and CR register only
@@ -806,8 +833,9 @@ extern int rs6000_debug_arg;                /* debug argument handling */
    (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)              \
    : CR_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_CC             \
-   : FPMEM_REGNO_P (REGNO) ? ((MODE) == DImode || (MODE) == DFmode)    \
+   : XER_REGNO_P (REGNO) ? (MODE) == PSImode                           \
    : ! INT_REGNO_P (REGNO) ? (GET_MODE_CLASS (MODE) == MODE_INT                \
                              && GET_MODE_SIZE (MODE) <= UNITS_PER_WORD) \
    : 1)
@@ -825,6 +853,10 @@ extern int rs6000_debug_arg;               /* debug argument handling */
    ? GET_MODE_CLASS (MODE2) == MODE_CC         \
    : GET_MODE_CLASS (MODE2) == MODE_CC         \
    ? GET_MODE_CLASS (MODE1) == MODE_CC         \
+   : ALTIVEC_VECTOR_MODE (MODE1)               \
+   ? ALTIVEC_VECTOR_MODE (MODE2)               \
+   : ALTIVEC_VECTOR_MODE (MODE2)               \
+   ? ALTIVEC_VECTOR_MODE (MODE1)               \
    : 1)
 
 /* A C expression returning the cost of moving data from a register of class
@@ -833,10 +865,12 @@ extern int rs6000_debug_arg;              /* debug argument handling */
    On the RS/6000, copying between floating-point and fixed-point
    registers is expensive.  */
 
-#define REGISTER_MOVE_COST(CLASS1, CLASS2)                     \
-  ((CLASS1) == FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 2                \
+#define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2)               \
+   ((CLASS1) == FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 2       \
    : (CLASS1) == FLOAT_REGS && (CLASS2) != FLOAT_REGS ? 10     \
    : (CLASS1) != FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 10     \
+   : (CLASS1) == ALTIVEC_REGS && (CLASS2) != ALTIVEC_REGS ? 20 \
+   : (CLASS1) != ALTIVEC_REGS && (CLASS2) == ALTIVEC_REGS ? 20 \
    : (((CLASS1) == SPECIAL_REGS || (CLASS1) == MQ_REGS         \
        || (CLASS1) == LINK_REGS || (CLASS1) == CTR_REGS                \
        || (CLASS1) == LINK_OR_CTR_REGS)                                \
@@ -850,8 +884,8 @@ extern int rs6000_debug_arg;                /* debug argument handling */
 
    On the RS/6000, bump this up a bit.  */
 
-#define MEMORY_MOVE_COST(MODE,CLASS,IN)        \
-  ((GET_MODE_CLASS (MODE) == MODE_FLOAT        \
+#define MEMORY_MOVE_COST(MODE, CLASS, IN)      \
+  ((GET_MODE_CLASS (MODE) == MODE_FLOAT                \
     && (rs6000_cpu == PROCESSOR_RIOS1 || rs6000_cpu == PROCESSOR_PPC601) \
     ? 3 : 2) \
    + 4)
@@ -864,24 +898,6 @@ extern int rs6000_debug_arg;               /* debug argument handling */
 
 #define BRANCH_COST 3
 
-/* A C statement (sans semicolon) to update the integer variable COST
-   based on the relationship between INSN that is dependent on
-   DEP_INSN through the dependence LINK.  The default is to make no
-   adjustment to COST.  On the RS/6000, ignore the cost of anti- and
-   output-dependencies.  In fact, output dependencies on the CR do have
-   a cost, but it is probably not worthwhile to track it.  */
-
-#define ADJUST_COST(INSN,LINK,DEP_INSN,COST)                           \
-  (COST) = rs6000_adjust_cost (INSN,LINK,DEP_INSN,COST)
-
-/* A C statement (sans semicolon) to update the integer scheduling priority
-   INSN_PRIORITY (INSN).  Reduce the priority to execute the INSN earlier,
-   increase the priority to execute INSN later.  Do not define this macro if
-   you do not need to adjust the scheduling priorities of insns.  */
-
-#define ADJUST_PRIORITY(INSN)                                          \
-  INSN_PRIORITY (INSN) = rs6000_adjust_priority (INSN, INSN_PRIORITY (INSN))
-
 /* 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.
@@ -890,6 +906,7 @@ extern int rs6000_debug_arg;                /* debug argument handling */
 
 #define CONDITIONAL_REGISTER_USAGE                                     \
 {                                                                      \
+  int i;                                                               \
   if (! TARGET_POWER)                                                  \
     fixed_regs[64] = 1;                                                        \
   if (TARGET_64BIT)                                                    \
@@ -901,6 +918,16 @@ extern int rs6000_debug_arg;               /* debug argument handling */
       && flag_pic == 1)                                                        \
     fixed_regs[PIC_OFFSET_TABLE_REGNUM]                                        \
       = call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;                   \
+  if (DEFAULT_ABI == ABI_DARWIN && flag_pic)                           \
+    global_regs[PIC_OFFSET_TABLE_REGNUM]                               \
+      = fixed_regs[PIC_OFFSET_TABLE_REGNUM]                            \
+        = call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;                 \
+  if (TARGET_ALTIVEC_ABI)                                              \
+    {                                                                  \
+      fixed_regs[VRSAVE_REGNO] = call_used_regs[VRSAVE_REGNO] = 1;     \
+      for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i) \
+        call_used_regs[i] = 1;                                         \
+    }                                                                  \
 }
 
 /* Specify the registers used for certain standard purposes.
@@ -927,11 +954,11 @@ extern int rs6000_debug_arg;              /* debug argument handling */
 /* Place to put static chain when calling a function that requires it.  */
 #define STATIC_CHAIN_REGNUM 11
 
-/* count register number for special purposes */
-#define COUNT_REGISTER_REGNUM 66
+/* Link register number. */
+#define LINK_REGISTER_REGNUM 65
 
-/* Special register that represents memory, used for float/int conversions.  */
-#define FPMEM_REGNUM 76
+/* Count register number. */
+#define COUNT_REGISTER_REGNUM 66
 
 /* Place that structure value return address is placed.
 
@@ -966,14 +993,7 @@ extern int rs6000_debug_arg;               /* debug argument handling */
    So make a class for registers valid as base registers.
 
    Also, cr0 is the only condition code register that can be used in
-   arithmetic insns, so make a separate class for it.
-
-   There is a special 'register' (76), which is not a register, but a
-   placeholder for memory allocated to convert between floating point and
-   integral types.  This works around a problem where if we allocate memory
-   with allocate_stack_{local,temp} and the function is an inline function, the
-   memory allocated will clobber memory in the caller.  So we use a special
-   register, and if that is used, we allocate stack space for it.  */
+   arithmetic insns, so make a separate class for it.  */
 
 enum reg_class
 {
@@ -981,6 +1001,8 @@ enum reg_class
   BASE_REGS,
   GENERAL_REGS,
   FLOAT_REGS,
+  ALTIVEC_REGS,
+  VRSAVE_REGS,
   NON_SPECIAL_REGS,
   MQ_REGS,
   LINK_REGS,
@@ -991,8 +1013,7 @@ enum reg_class
   CR0_REGS,
   CR_REGS,
   NON_FLOAT_REGS,
-  FPMEM_REGS,
-  FLOAT_OR_FPMEM_REGS,
+  XER_REGS,
   ALL_REGS,
   LIM_REG_CLASSES
 };
@@ -1007,6 +1028,8 @@ enum reg_class
   "BASE_REGS",                                                         \
   "GENERAL_REGS",                                                      \
   "FLOAT_REGS",                                                                \
+  "ALTIVEC_REGS",                                                      \
+  "VRSAVE_REGS",                                                       \
   "NON_SPECIAL_REGS",                                                  \
   "MQ_REGS",                                                           \
   "LINK_REGS",                                                         \
@@ -1017,8 +1040,7 @@ enum reg_class
   "CR0_REGS",                                                          \
   "CR_REGS",                                                           \
   "NON_FLOAT_REGS",                                                    \
-  "FPMEM_REGS",                                                                \
-  "FLOAT_OR_FPMEM_REGS",                                               \
+  "XER_REGS",                                                          \
   "ALL_REGS"                                                           \
 }
 
@@ -1026,25 +1048,26 @@ enum reg_class
    This is an initializer for a vector of HARD_REG_SET
    of length N_REG_CLASSES.  */
 
-#define REG_CLASS_CONTENTS                                             \
-{                                                                      \
-  { 0x00000000, 0x00000000, 0x00000000 },      /* NO_REGS */           \
-  { 0xfffffffe, 0x00000000, 0x00000008 },      /* BASE_REGS */         \
-  { 0xffffffff, 0x00000000, 0x00000008 },      /* GENERAL_REGS */      \
-  { 0x00000000, 0xffffffff, 0x00000000 },      /* FLOAT_REGS */        \
-  { 0xffffffff, 0xffffffff, 0x00000008 },      /* NON_SPECIAL_REGS */  \
-  { 0x00000000, 0x00000000, 0x00000001 },      /* MQ_REGS */           \
-  { 0x00000000, 0x00000000, 0x00000002 },      /* LINK_REGS */         \
-  { 0x00000000, 0x00000000, 0x00000004 },      /* CTR_REGS */          \
-  { 0x00000000, 0x00000000, 0x00000006 },      /* LINK_OR_CTR_REGS */  \
-  { 0x00000000, 0x00000000, 0x00000007 },      /* SPECIAL_REGS */      \
-  { 0xffffffff, 0x00000000, 0x0000000f },      /* SPEC_OR_GEN_REGS */  \
-  { 0x00000000, 0x00000000, 0x00000010 },      /* CR0_REGS */          \
-  { 0x00000000, 0x00000000, 0x00000ff0 },      /* CR_REGS */           \
-  { 0xffffffff, 0x00000000, 0x0000ffff },      /* NON_FLOAT_REGS */    \
-  { 0x00000000, 0x00000000, 0x00010000 },      /* FPMEM_REGS */        \
-  { 0x00000000, 0xffffffff, 0x00010000 },      /* FLOAT_OR_FPMEM_REGS */ \
-  { 0xffffffff, 0xffffffff, 0x0001ffff }       /* ALL_REGS */          \
+#define REG_CLASS_CONTENTS                                                  \
+{                                                                           \
+  { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* NO_REGS */         \
+  { 0xfffffffe, 0x00000000, 0x00000008, 0x00000000 }, /* BASE_REGS */       \
+  { 0xffffffff, 0x00000000, 0x00000008, 0x00000000 }, /* GENERAL_REGS */     \
+  { 0x00000000, 0xffffffff, 0x00000000, 0x00000000 }, /* FLOAT_REGS */       \
+  { 0x00000000, 0x00000000, 0xffffe000, 0x0001ffff }, /* ALTIVEC_REGS */     \
+  { 0x00000000, 0x00000000, 0x00000000, 0x00020000 }, /* VRSAVE_REGS */             \
+  { 0xffffffff, 0xffffffff, 0x00000008, 0x00000000 }, /* 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, 0x00000000 }, /* SPECIAL_REGS */     \
+  { 0xffffffff, 0x00000000, 0x0000000f, 0x00000000 }, /* SPEC_OR_GEN_REGS */ \
+  { 0x00000000, 0x00000000, 0x00000010, 0x00000000 }, /* CR0_REGS */        \
+  { 0x00000000, 0x00000000, 0x00000ff0, 0x00000000 }, /* CR_REGS */         \
+  { 0xffffffff, 0x00000000, 0x0000ffff, 0x00000000 }, /* NON_FLOAT_REGS */   \
+  { 0x00000000, 0x00000000, 0x00010000, 0x00000000 }, /* XER_REGS */        \
+  { 0xffffffff, 0xffffffff, 0xffffffff, 0x0001ffff }  /* ALL_REGS */        \
 }
 
 /* The same information, inverted:
@@ -1052,17 +1075,19 @@ enum reg_class
    reg number REGNO.  This could be a conditional expression
    or could index an array.  */
 
-#define REGNO_REG_CLASS(REGNO)         \
- ((REGNO) == 0 ? GENERAL_REGS          \
-  : (REGNO) < 32 ? BASE_REGS           \
-  : FP_REGNO_P (REGNO) ? FLOAT_REGS    \
-  : (REGNO) == 68 ? CR0_REGS           \
-  : CR_REGNO_P (REGNO) ? CR_REGS       \
-  : (REGNO) == 64 ? MQ_REGS            \
-  : (REGNO) == 65 ? LINK_REGS          \
-  : (REGNO) == 66 ? CTR_REGS           \
-  : (REGNO) == 67 ? BASE_REGS          \
-  : (REGNO) == 76 ? FPMEM_REGS         \
+#define REGNO_REG_CLASS(REGNO)                 \
+ ((REGNO) == 0 ? GENERAL_REGS                  \
+  : (REGNO) < 32 ? BASE_REGS                   \
+  : FP_REGNO_P (REGNO) ? FLOAT_REGS            \
+  : ALTIVEC_REGNO_P (REGNO) ? ALTIVEC_REGS     \
+  : (REGNO) == CR0_REGNO ? CR0_REGS            \
+  : CR_REGNO_P (REGNO) ? CR_REGS               \
+  : (REGNO) == MQ_REGNO ? MQ_REGS              \
+  : (REGNO) == LINK_REGISTER_REGNUM ? LINK_REGS        \
+  : (REGNO) == COUNT_REGISTER_REGNUM ? CTR_REGS        \
+  : (REGNO) == ARG_POINTER_REGNUM ? BASE_REGS  \
+  : (REGNO) == XER_REGNO ? XER_REGS            \
+  : (REGNO) == VRSAVE_REGNO ? VRSAVE_REGS      \
   : NO_REGS)
 
 /* The class value for index registers, and the one for base regs.  */
@@ -1078,9 +1103,10 @@ enum reg_class
    : (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' ? FPMEM_REGS   \
+   : (C) == 'z' ? XER_REGS     \
    : NO_REGS)
 
 /* The letters I, J, K, L, M, N, and P in a register constraint string
@@ -1094,18 +1120,18 @@ enum reg_class
    `K' is a constant with only the low-order 16 bits non-zero
    `L' is a signed 16-bit constant shifted left 16 bits
    `M' is a constant that is greater than 31
-   `N' is a constant that is an exact power of two
+   `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) & (~ (HOST_WIDE_INT) 0xffff0000)) == 0      \
+   : (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' ? exact_log2 (VALUE) >= 0                              \
+   : (C) == 'N' ? (VALUE) > 0 && exact_log2 (VALUE) >= 0               \
    : (C) == 'O' ? (VALUE) == 0                                         \
    : (C) == 'P' ? (unsigned HOST_WIDE_INT) ((- (VALUE)) + 0x8000) < 0x10000 \
    : 0)
@@ -1147,12 +1173,26 @@ enum reg_class
    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
+   into a FP register and discovers it doesn't have the memory location
+   required.
+
+   ??? Would it be a good idea to have reload do the converse, that is
+   try to reload floating modes into FP registers if possible?
+ */
 
 #define PREFERRED_RELOAD_CLASS(X,CLASS)                        \
-  ((GET_CODE (X) == CONST_DOUBLE                       \
-    && GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT)    \
-   ? NO_REGS : (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)))
 
 /* 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,
@@ -1161,11 +1201,14 @@ enum reg_class
 #define SECONDARY_RELOAD_CLASS(CLASS,MODE,IN) \
   secondary_reload_class (CLASS, MODE, IN)
 
-/* If we are copying between FP registers and anything else, we need a memory
-   location.  */
+/* If we are copying between FP or AltiVec registers and anything
+   else, we need a memory location.  */
 
-#define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) \
- ((CLASS1) != (CLASS2) && ((CLASS1) == FLOAT_REGS || (CLASS2) == FLOAT_REGS))
+#define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE)            \
+ ((CLASS1) != (CLASS2) && ((CLASS1) == FLOAT_REGS              \
+                          || (CLASS2) == FLOAT_REGS            \
+                          || (CLASS1) == ALTIVEC_REGS          \
+                          || (CLASS2) == ALTIVEC_REGS))
 
 /* Return the maximum number of consecutive registers
    needed to represent mode MODE in a register of class CLASS.
@@ -1173,15 +1216,19 @@ enum reg_class
    On RS/6000, this is the size of MODE in words,
    except in the FP regs, where a single reg is enough for two words.  */
 #define CLASS_MAX_NREGS(CLASS, MODE)                                   \
- (((CLASS) == FLOAT_REGS || (CLASS) == FPMEM_REGS                      \
-   || (CLASS) == FLOAT_OR_FPMEM_REGS)                                  \
+ (((CLASS) == FLOAT_REGS)                                              \
   ? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \
   : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
 
 /* If defined, gives a class of registers that cannot be used as the
-   operand of a SUBREG that changes the size of the object.  */
+   operand of a SUBREG that changes the mode of the object illegally.  */
+
+#define CLASS_CANNOT_CHANGE_MODE        FLOAT_REGS
+
+/* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE.  */
 
-#define CLASS_CANNOT_CHANGE_SIZE       FLOAT_OR_FPMEM_REGS
+#define CLASS_CANNOT_CHANGE_MODE_P(FROM,TO) \
+  (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO))
 \f
 /* Stack layout; function entry, exit and calling.  */
 
@@ -1191,19 +1238,12 @@ enum rs6000_abi {
   ABI_AIX,                     /* IBM's AIX */
   ABI_AIX_NODESC,              /* AIX calling sequence minus function descriptors */
   ABI_V4,                      /* System V.4/eabi */
-  ABI_NT,                      /* Windows/NT */
-  ABI_SOLARIS                  /* Solaris */
+  ABI_SOLARIS,                 /* Solaris */
+  ABI_DARWIN                   /* Apple's Darwin (OS X kernel) */
 };
 
 extern enum rs6000_abi rs6000_current_abi;     /* available for use by subtarget */
 
-/* Default ABI to compile code for */
-#ifndef DEFAULT_ABI
-#define DEFAULT_ABI ABI_AIX
-/* The prefix to add to user-visible assembler symbols. */
-#define USER_LABEL_PREFIX "."
-#endif
-
 /* Structure used to define the rs6000 stack */
 typedef struct rs6000_stack {
   int first_gp_reg_save;       /* first callee saved GP register used */
@@ -1213,9 +1253,6 @@ typedef struct rs6000_stack {
   int toc_save_p;              /* true if the TOC needs to be saved */
   int push_p;                  /* true if we need to allocate stack space */
   int calls_p;                 /* true if the function makes any calls */
-  int main_p;                  /* true if this is main */
-  int main_save_p;             /* true if this is main and we need to save args */
-  int fpmem_p;                 /* true if float/int conversion temp needed */
   enum rs6000_abi abi;         /* which ABI to use */
   int gp_save_offset;          /* offset to save GP regs from initial SP */
   int fp_save_offset;          /* offset to save FP regs from initial SP */
@@ -1223,20 +1260,17 @@ typedef struct rs6000_stack {
   int cr_save_offset;          /* offset to save CR from initial SP */
   int toc_save_offset;         /* offset to save the TOC pointer */
   int varargs_save_offset;     /* offset to save the varargs registers */
-  int main_save_offset;                /* offset to save main's args */
-  int fpmem_offset;            /* offset for float/int conversion temp */
+  int ehrd_offset;             /* offset to EH return data */
   int reg_size;                        /* register size (4 or 8) */
   int varargs_size;            /* size to hold V.4 args passed in regs */
   int vars_size;               /* variable save area size */
   int parm_size;               /* outgoing parameter size */
-  int main_size;               /* size to hold saving main's args */
   int save_size;               /* save area size */
   int fixed_size;              /* fixed size of stack frame */
   int gp_size;                 /* size of saved GP registers */
   int fp_size;                 /* size of saved FP registers */
   int cr_size;                 /* size to hold CR if not in save_size */
   int lr_size;                 /* size to hold LR if not in save_size */
-  int fpmem_size;              /* size to hold float/int conversion */
   int toc_size;                        /* size to hold TOC if not in save_size */
   int total_size;              /* total bytes allocated for stack */
 } rs6000_stack_t;
@@ -1255,34 +1289,28 @@ typedef struct rs6000_stack {
 /* #define FRAME_GROWS_DOWNWARD */
 
 /* Size of the outgoing register save area */
-#define RS6000_REG_SAVE (TARGET_32BIT ? 32 : 64)
+#define RS6000_REG_SAVE ((DEFAULT_ABI == ABI_AIX                       \
+                         || DEFAULT_ABI == ABI_AIX_NODESC              \
+                         || DEFAULT_ABI == ABI_DARWIN)                 \
+                        ? (TARGET_64BIT ? 64 : 32)                     \
+                        : 0)
 
 /* Size of the fixed area on the stack */
-#define RS6000_SAVE_AREA (TARGET_32BIT ? 24 : 48)
+#define RS6000_SAVE_AREA \
+  (((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_DARWIN) ? 24 : 8)   \
+   << (TARGET_64BIT ? 1 : 0))
 
 /* MEM representing address to save the TOC register */
 #define RS6000_SAVE_TOC gen_rtx_MEM (Pmode, \
                                     plus_constant (stack_pointer_rtx, \
                                                    (TARGET_32BIT ? 20 : 40)))
 
-/* Offset & size for fpmem stack locations used for converting between
-   float and integral types.  */
-extern int rs6000_fpmem_offset;
-extern int rs6000_fpmem_size;
-
 /* Size of the V.4 varargs area if needed */
 #define RS6000_VARARGS_AREA 0
 
-/* Whether a V.4 varargs area is needed */
-extern int rs6000_sysv_varargs_p;
-
 /* Align an address */
 #define RS6000_ALIGN(n,a) (((n) + (a) - 1) & ~((a) - 1))
 
-/* Initialize data used by insn expanders.  This is called from
-   init_emit, once for each function, before code is generated. */
-#define INIT_EXPANDERS rs6000_init_expanders ()
-
 /* 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)
@@ -1321,6 +1349,11 @@ extern int rs6000_sysv_varargs_p;
    area.  */
 #define FIRST_PARM_OFFSET(FNDECL) RS6000_SAVE_AREA
 
+/* Offset from the argument pointer register value to the top of
+   stack.  This is different from FIRST_PARM_OFFSET because of the
+   register save area.  */
+#define ARG_POINTER_CFA_OFFSET(FNDECL) 0
+
 /* Define this if stack space is still allocated for a parameter passed
    in a register.  The value is the number of bytes allocated to this
    area.  */
@@ -1338,7 +1371,7 @@ extern int rs6000_sysv_varargs_p;
 /* Define this if the maximum size of all the outgoing args is to be
    accumulated and pushed during the prologue.  The amount can be
    found in the variable current_function_outgoing_args_size.  */
-#define ACCUMULATE_OUTGOING_ARGS
+#define ACCUMULATE_OUTGOING_ARGS 1
 
 /* Value is the number of bytes of arguments automatically
    popped when returning from a subroutine call.
@@ -1362,14 +1395,18 @@ extern int rs6000_sysv_varargs_p;
                && TYPE_PRECISION (VALTYPE) < BITS_PER_WORD)    \
               || POINTER_TYPE_P (VALTYPE)                      \
               ? word_mode : TYPE_MODE (VALTYPE),               \
-              TREE_CODE (VALTYPE) == REAL_TYPE && TARGET_HARD_FLOAT ? 33 : 3)
+              TREE_CODE (VALTYPE) == VECTOR_TYPE ? ALTIVEC_ARG_RETURN \
+              : TREE_CODE (VALTYPE) == REAL_TYPE && TARGET_HARD_FLOAT \
+               ? FP_ARG_RETURN : GP_ARG_RETURN)
 
 /* Define how to find the value returned by a library function
    assuming the value has mode MODE.  */
 
-#define LIBCALL_VALUE(MODE)            \
-  gen_rtx_REG (MODE, (GET_MODE_CLASS (MODE) == MODE_FLOAT       \
-                     && TARGET_HARD_FLOAT ? 33 : 3))
+#define LIBCALL_VALUE(MODE)                                            \
+  gen_rtx_REG (MODE, ALTIVEC_VECTOR_MODE (MODE) ? ALTIVEC_ARG_RETURN   \
+                    : GET_MODE_CLASS (MODE) == MODE_FLOAT              \
+                    && TARGET_HARD_FLOAT                               \
+                    ? FP_ARG_RETURN : GP_ARG_RETURN)
 
 /* The definition of this macro implies that there are cases where
    a scalar value cannot be returned in registers.
@@ -1398,36 +1435,58 @@ extern int rs6000_sysv_varargs_p;
 #define FP_ARG_MIN_REG 33
 #define        FP_ARG_AIX_MAX_REG 45
 #define        FP_ARG_V4_MAX_REG  40
-#define FP_ARG_MAX_REG FP_ARG_AIX_MAX_REG
+#define        FP_ARG_MAX_REG ((DEFAULT_ABI == ABI_AIX                         \
+                        || DEFAULT_ABI == ABI_AIX_NODESC               \
+                        || DEFAULT_ABI == ABI_DARWIN)                  \
+                       ? FP_ARG_AIX_MAX_REG : FP_ARG_V4_MAX_REG)
 #define FP_ARG_NUM_REG (FP_ARG_MAX_REG - FP_ARG_MIN_REG + 1)
 
+/* Minimum and maximum AltiVec registers used to hold arguments.  */
+#define ALTIVEC_ARG_MIN_REG (FIRST_ALTIVEC_REGNO + 2)
+#define ALTIVEC_ARG_MAX_REG (ALTIVEC_ARG_MIN_REG + 11)
+#define ALTIVEC_ARG_NUM_REG (ALTIVEC_ARG_MAX_REG - ALTIVEC_ARG_MIN_REG + 1)
+
 /* Return registers */
 #define GP_ARG_RETURN GP_ARG_MIN_REG
 #define FP_ARG_RETURN FP_ARG_MIN_REG
+#define ALTIVEC_ARG_RETURN (FIRST_ALTIVEC_REGNO + 2)
 
 /* Flags for the call/call_value rtl operations set up by function_arg */
 #define CALL_NORMAL            0x00000000      /* no special processing */
-#define CALL_NT_DLLIMPORT      0x00000001      /* NT, this is a DLL import call */
+/* Bits in 0x00000001 are unused.  */
 #define CALL_V4_CLEAR_FP_ARGS  0x00000002      /* V.4, no FP args passed */
 #define CALL_V4_SET_FP_ARGS    0x00000004      /* V.4, FP args were passed */
 #define CALL_LONG              0x00000008      /* always call indirect */
 
-/* Define cutoff for using external functions to save floating point */
-#define FP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) == 62 || (FIRST_REG) == 63)
-
 /* 1 if N is a possible register number for a function value
    as seen by the caller.
 
-   On RS/6000, this is r3 and fp1.  */
-#define FUNCTION_VALUE_REGNO_P(N)  ((N) == GP_ARG_RETURN || ((N) == FP_ARG_RETURN))
+   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_ALTIVEC &&       \
+                                       (N) == ALTIVEC_ARG_RETURN))
 
 /* 1 if N is a possible register number for function argument passing.
-   On RS/6000, these are r3-r10 and fp1-fp13.  */
+   On RS/6000, these are r3-r10 and fp1-fp13.
+   On AltiVec, v2 - v13 are used for passing vectors.  */
 #define FUNCTION_ARG_REGNO_P(N)                                                \
-  (((unsigned)((N) - GP_ARG_MIN_REG) < (unsigned)(GP_ARG_NUM_REG))     \
+  ((unsigned)(((N) - GP_ARG_MIN_REG) < (unsigned)(GP_ARG_NUM_REG))     \
+   || (TARGET_ALTIVEC &&                                               \
+       (unsigned)((N) - ALTIVEC_ARG_MIN_REG) < (unsigned)(ALTIVEC_ARG_MAX_REG)) \
    || ((unsigned)((N) - FP_ARG_MIN_REG) < (unsigned)(FP_ARG_NUM_REG)))
 
 \f
+/* A C structure for machine-specific, per-function data.
+   This is added to the cfun structure.  */
+typedef struct machine_function
+{
+  /* 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;
+} 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
@@ -1450,6 +1509,7 @@ typedef struct rs6000_args
 {
   int words;                   /* # words used for passing GP registers */
   int fregno;                  /* next available FP register */
+  int vregno;                  /* next available AltiVec register */
   int nargs_prototype;         /* # args left in the current prototype */
   int orig_nargs;              /* Original value of nargs_prototype */
   int prototype;               /* Whether a prototype was defined */
@@ -1460,11 +1520,11 @@ typedef struct rs6000_args
 /* Define intermediate macro to compute the size (in registers) of an argument
    for the RS/6000.  */
 
-#define RS6000_ARG_SIZE(MODE, TYPE, NAMED)                             \
-(! (NAMED) ? 0                                                         \
: (MODE) != BLKmode                                                   \
? (GET_MODE_SIZE (MODE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD      \
: (int_size_in_bytes (TYPE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
+#define RS6000_ARG_SIZE(MODE, TYPE)                                    \
+((MODE) != BLKmode                                                     \
? (GET_MODE_SIZE (MODE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD      \
: ((unsigned HOST_WIDE_INT) int_size_in_bytes (TYPE)                  \
   + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
 
 /* Initialize a variable CUM of type CUMULATIVE_ARGS
    for a call to a function whose data type is FNTYPE.
@@ -1492,6 +1552,12 @@ typedef struct rs6000_args
    && (CUM).fregno <= FP_ARG_MAX_REG    \
    && TARGET_HARD_FLOAT)
 
+/* Non-zero if we can use an AltiVec register to pass this arg.  */
+#define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE)   \
+  (ALTIVEC_VECTOR_MODE (MODE)                  \
+   && (CUM).vregno <= ALTIVEC_ARG_MAX_REG      \
+   && TARGET_ALTIVEC_ABI)
+
 /* Determine where to put an argument to a function.
    Value is zero to push the argument on the stack,
    or a hard register in which to store the argument.
@@ -1539,8 +1605,7 @@ typedef struct rs6000_args
    the argument, `downward' to pad below, or `none' to inhibit
    padding.  */
 
-#define FUNCTION_ARG_PADDING(MODE, TYPE) \
-  (enum direction) function_arg_padding (MODE, TYPE)
+#define FUNCTION_ARG_PADDING(MODE, TYPE) function_arg_padding (MODE, TYPE)
 
 /* If defined, a C expression that gives the alignment boundary, in bits,
    of an argument with the specified mode and type.  If it is not defined,
@@ -1578,15 +1643,9 @@ typedef struct rs6000_args
 #define EXPAND_BUILTIN_VA_ARG(valist, type) \
   rs6000_va_arg (valist, type)
 
-/* This macro generates the assembly code for function entry.
-   FILE is a stdio stream to output the code to.
-   SIZE is an int: how many units of temporary storage to allocate.
-   Refer to the array `regs_ever_live' to determine which registers
-   to save; `regs_ever_live[I]' is nonzero if register number I
-   is ever used in the function.  This macro is responsible for
-   knowing which registers should not be saved even if used.  */
-
-#define FUNCTION_PROLOGUE(FILE, SIZE) output_prolog (FILE, SIZE)
+/* 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.  */
@@ -1602,51 +1661,17 @@ typedef struct rs6000_args
    its backpointer, which we maintain.  */
 #define EXIT_IGNORE_STACK      1
 
-/* This macro generates the assembly code for function exit,
-   on machines that need it.  If FUNCTION_EPILOGUE is not defined
-   then individual return instructions are generated for each
-   return statement.  Args are same as for FUNCTION_PROLOGUE.
-
-   The function epilogue should not depend on the current stack pointer!
-   It should use the frame pointer only.  This is mandatory because
-   of alloca; we also take advantage of it to omit stack adjustments
-   before returning.  */
-
-#define FUNCTION_EPILOGUE(FILE, SIZE) output_epilog (FILE, SIZE)
-
-/* A C compound statement that outputs the assembler code for a thunk function,
-   used to implement C++ virtual function calls with multiple inheritance.  The
-   thunk acts as a wrapper around a virtual function, adjusting the implicit
-   object parameter before handing control off to the real function.
-
-   First, emit code to add the integer DELTA to the location that contains the
-   incoming first argument.  Assume that this argument contains a pointer, and
-   is the one used to pass the `this' pointer in C++.  This is the incoming
-   argument *before* the function prologue, e.g. `%o0' on a sparc.  The
-   addition must preserve the values of all other incoming arguments.
-
-   After the addition, emit code to jump to FUNCTION, which is a
-   `FUNCTION_DECL'.  This is a direct pure jump, not a call, and does not touch
-   the return address.  Hence returning from FUNCTION will return to whoever
-   called the current `thunk'.
-
-   The effect must be as if FUNCTION had been called directly with the adjusted
-   first argument.  This macro is responsible for emitting all of the code for
-   a thunk function; `FUNCTION_PROLOGUE' and `FUNCTION_EPILOGUE' are not
-   invoked.
-
-   The THUNK_FNDECL is redundant.  (DELTA and FUNCTION have already been
-   extracted from it.)  It might possibly be useful on some targets, but
-   probably not.
-
-   If you do not define this macro, the target-independent code in the C++
-   frontend will generate a less efficient heavyweight thunk that calls
-   FUNCTION instead of jumping to it.  The generic approach does not support
-   varargs.  */
-#if TARGET_ELF
-#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \
-  output_mi_thunk (FILE, THUNK_FNDECL, DELTA, FUNCTION)
-#endif
+/* Define this macro as a C expression that is nonzero for registers
+   that are used by the epilogue or the return' pattern.  The stack
+   and frame pointer registers are already be assumed to be used as
+   needed.  */
+
+#define        EPILOGUE_USES(REGNO)                                    \
+  ((reload_completed && (REGNO) == LINK_REGISTER_REGNUM)       \
+   || (current_function_calls_eh_return                                \
+       && TARGET_AIX                                           \
+       && (REGNO) == TOC_REGISTER))
+
 \f
 /* TRAMPOLINE_TEMPLATE deleted */
 
@@ -1661,35 +1686,6 @@ typedef struct rs6000_args
 #define INITIALIZE_TRAMPOLINE(ADDR, FNADDR, CXT)               \
   rs6000_initialize_trampoline (ADDR, FNADDR, CXT)
 \f
-/* If defined, a C expression whose value is nonzero if IDENTIFIER
-   with arguments ARGS is a valid machine specific attribute for DECL.
-   The attributes in ATTRIBUTES have previously been assigned to DECL.  */
-
-#define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, NAME, ARGS) \
-  (rs6000_valid_decl_attribute_p (DECL, ATTRIBUTES, NAME, ARGS))
-
-/* If defined, a C expression whose value is nonzero if IDENTIFIER
-   with arguments ARGS is a valid machine specific attribute for TYPE.
-   The attributes in ATTRIBUTES have previously been assigned to TYPE.  */
-
-#define VALID_MACHINE_TYPE_ATTRIBUTE(TYPE, ATTRIBUTES, NAME, ARGS) \
-  (rs6000_valid_type_attribute_p (TYPE, ATTRIBUTES, NAME, ARGS))
-
-/* If defined, a C expression whose value is zero if the attributes on
-   TYPE1 and TYPE2 are incompatible, one if they are compatible, and
-   two if they are nearly compatible (which causes a warning to be
-   generated).  */
-
-#define COMP_TYPE_ATTRIBUTES(TYPE1, TYPE2) \
-  (rs6000_comp_type_attributes (TYPE1, TYPE2))
-
-/* If defined, a C statement that assigns default attributes to newly
-   defined TYPE.  */
-
-#define SET_DEFAULT_TYPE_ATTRIBUTES(TYPE) \
-  (rs6000_set_default_type_attributes (TYPE))
-
-\f
 /* Definitions for __builtin_return_address and __builtin_frame_address.
    __builtin_return_address (0) should give link register (65), enable
    this. */
@@ -1705,26 +1701,18 @@ typedef struct rs6000_args
    abi's store the return address.  */
 #define RETURN_ADDRESS_OFFSET                                          \
  ((DEFAULT_ABI == ABI_AIX                                              \
-   || DEFAULT_ABI == ABI_AIX_NODESC)   ? 8 :                           \
+   || DEFAULT_ABI == ABI_DARWIN                                                \
+   || DEFAULT_ABI == ABI_AIX_NODESC)   ? (TARGET_32BIT ? 8 : 16) :     \
   (DEFAULT_ABI == ABI_V4                                               \
    || DEFAULT_ABI == ABI_SOLARIS)      ? (TARGET_32BIT ? 4 : 8) :      \
-  (DEFAULT_ABI == ABI_NT)              ? -4 :                          \
-  (fatal ("RETURN_ADDRESS_OFFSET not supported"), 0))
+  (internal_error ("RETURN_ADDRESS_OFFSET not supported"), 0))
 
 /* The current return address is in link register (65).  The return address
    of anything farther back is accessed normally at an offset of 8 from the
    frame pointer.  */
-#define RETURN_ADDR_RTX(count, frame)                  \
-  ((count == -1)                                       \
-   ? gen_rtx_REG (Pmode, 65)                           \
-   : gen_rtx_MEM (Pmode,                               \
-                 memory_address                        \
-                 (Pmode,                               \
-                  plus_constant (copy_to_reg           \
-                                 (gen_rtx_MEM (Pmode,  \
-                                               memory_address (Pmode, \
-                                                               frame))), \
-                                 RETURN_ADDRESS_OFFSET))))
+#define RETURN_ADDR_RTX(COUNT, FRAME)                 \
+  (rs6000_return_addr (COUNT, FRAME))
+
 \f
 /* Definitions for register eliminations.
 
@@ -1845,26 +1833,28 @@ typedef struct rs6000_args
    After reload, it makes no difference, since pseudo regs have
    been eliminated by then.  */
 
-#ifndef REG_OK_STRICT
+#ifdef REG_OK_STRICT
+# define REG_OK_STRICT_FLAG 1
+#else
+# define REG_OK_STRICT_FLAG 0
+#endif
 
 /* Nonzero if X is a hard reg that can be used as an index
-   or if it is a pseudo reg.  */
-#define REG_OK_FOR_INDEX_P(X)                  \
-  (REGNO (X) <= 31 || REGNO (X) == 67 || REGNO (X) >= FIRST_PSEUDO_REGISTER)
+   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))))
 
 /* Nonzero if X is a hard reg that can be used as a base reg
-   or if it is a pseudo reg.  */
-#define REG_OK_FOR_BASE_P(X)                                    \
-  (REGNO (X) > 0 && REG_OK_FOR_INDEX_P (X))
-
-#else
-
-/* Nonzero if X is a hard reg that can be used as an index.  */
-#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
-/* Nonzero if X is a hard reg that can be used as a base reg.  */
-#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
+   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)))
 
-#endif
+#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)
 \f
 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
    that is a valid memory address for an instruction.
@@ -1884,18 +1874,16 @@ typedef struct rs6000_args
    adjacent memory cells are accessed by adding word-sized offsets
    during assembly output.  */
 
-#define LEGITIMATE_CONSTANT_POOL_BASE_P(X)                             \
-  (TARGET_TOC && GET_CODE (X) == SYMBOL_REF                            \
-   && CONSTANT_POOL_ADDRESS_P (X)                                      \
-   && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (X)))
+#define CONSTANT_POOL_EXPR_P(X) (constant_pool_expr_p (X))
+
+#define TOC_RELATIVE_EXPR_P(X) (toc_relative_expr_p (X))
 
-/* AIX64 guaranteed to have 64 bit TOC alignment.  */
 #define LEGITIMATE_CONSTANT_POOL_ADDRESS_P(X)                          \
-  (LEGITIMATE_CONSTANT_POOL_BASE_P (X)                                 \
-   || (TARGET_TOC                                                      \
-       && GET_CODE (X) == CONST && GET_CODE (XEXP (X, 0)) == PLUS      \
-       && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT                        \
-       && LEGITIMATE_CONSTANT_POOL_BASE_P (XEXP (XEXP (X, 0), 0))))
+  (TARGET_TOC                                                          \
+  && GET_CODE (X) == PLUS                                              \
+  && GET_CODE (XEXP (X, 0)) == REG                                     \
+  && (TARGET_MINIMAL_TOC || REGNO (XEXP (X, 0)) == TOC_REGISTER)       \
+  && CONSTANT_POOL_EXPR_P (XEXP (X, 1)))
 
 #define LEGITIMATE_SMALL_DATA_P(MODE, X)                               \
   ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)               \
@@ -1903,68 +1891,53 @@ typedef struct rs6000_args
    && (GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == CONST)            \
    && small_data_operand (X, MODE))
 
-#define LEGITIMATE_ADDRESS_INTEGER_P(X,OFFSET)                         \
+#define LEGITIMATE_ADDRESS_INTEGER_P(X, OFFSET)                                \
  (GET_CODE (X) == CONST_INT                                            \
   && (unsigned HOST_WIDE_INT) (INTVAL (X) + (OFFSET) + 0x8000) < 0x10000)
 
-#define LEGITIMATE_OFFSET_ADDRESS_P(MODE,X)            \
- (GET_CODE (X) == PLUS                                 \
-  && GET_CODE (XEXP (X, 0)) == REG                     \
-  && REG_OK_FOR_BASE_P (XEXP (X, 0))                   \
-  && LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 0)     \
-  && (((MODE) != DFmode && (MODE) != DImode)           \
-      || (TARGET_32BIT                                 \
-         ? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 4) \
-         : ! (INTVAL (XEXP (X, 1)) & 3)))              \
-  && ((MODE) != TImode                                 \
-      || (TARGET_32BIT                                 \
-         ? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 12) \
-         : (LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 8) \
+#define LEGITIMATE_OFFSET_ADDRESS_P(MODE, X, STRICT)           \
+ (GET_CODE (X) == PLUS                                         \
+  && GET_CODE (XEXP (X, 0)) == REG                             \
+  && INT_REG_OK_FOR_BASE_P (XEXP (X, 0), (STRICT))             \
+  && LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 0)             \
+  && (! ALTIVEC_VECTOR_MODE (MODE) || INTVAL (X) == 0)         \
+  && (((MODE) != DFmode && (MODE) != DImode)                   \
+      || (TARGET_32BIT                                         \
+         ? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 4)       \
+         : ! (INTVAL (XEXP (X, 1)) & 3)))                      \
+  && ((MODE) != TImode                                         \
+      || (TARGET_32BIT                                         \
+         ? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 12)      \
+         : (LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 8)      \
             && ! (INTVAL (XEXP (X, 1)) & 3)))))
 
-#define LEGITIMATE_INDEXED_ADDRESS_P(X)                \
- (GET_CODE (X) == PLUS                         \
-  && GET_CODE (XEXP (X, 0)) == REG             \
-  && GET_CODE (XEXP (X, 1)) == REG             \
-  && ((REG_OK_FOR_BASE_P (XEXP (X, 0))         \
-       && REG_OK_FOR_INDEX_P (XEXP (X, 1)))    \
-      || (REG_OK_FOR_BASE_P (XEXP (X, 1))      \
-         && REG_OK_FOR_INDEX_P (XEXP (X, 0)))))
-
-#define LEGITIMATE_INDIRECT_ADDRESS_P(X)       \
-  (GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X))
-
-#define LEGITIMATE_LO_SUM_ADDRESS_P(MODE, X)           \
-  (TARGET_ELF                                          \
-   && ! flag_pic && ! TARGET_TOC                       \
-   && (MODE) != DImode                                 \
-   && (MODE) != TImode                                 \
-   && (TARGET_HARD_FLOAT || (MODE) != DFmode)          \
-   && GET_CODE (X) == LO_SUM                           \
-   && GET_CODE (XEXP (X, 0)) == REG                    \
-   && REG_OK_FOR_BASE_P (XEXP (X, 0))                  \
+#define LEGITIMATE_INDEXED_ADDRESS_P(X, STRICT)                        \
+ (GET_CODE (X) == PLUS                                         \
+  && GET_CODE (XEXP (X, 0)) == REG                             \
+  && GET_CODE (XEXP (X, 1)) == REG                             \
+  && ((INT_REG_OK_FOR_BASE_P (XEXP (X, 0), (STRICT))           \
+       && INT_REG_OK_FOR_INDEX_P (XEXP (X, 1), (STRICT)))      \
+      || (INT_REG_OK_FOR_BASE_P (XEXP (X, 1), (STRICT))                \
+         && INT_REG_OK_FOR_INDEX_P (XEXP (X, 0), (STRICT)))))
+
+#define LEGITIMATE_INDIRECT_ADDRESS_P(X, STRICT)               \
+  (GET_CODE (X) == REG && INT_REG_OK_FOR_BASE_P (X, (STRICT)))
+
+#define LEGITIMATE_LO_SUM_ADDRESS_P(MODE, X, STRICT)           \
+  (TARGET_ELF                                                  \
+   && ! flag_pic && ! TARGET_TOC                               \
+   && (MODE) != DImode                                         \
+   && (MODE) != TImode                                         \
+   && ! ALTIVEC_VECTOR_MODE (MODE)                             \
+   && (TARGET_HARD_FLOAT || (MODE) != DFmode)                  \
+   && GET_CODE (X) == LO_SUM                                   \
+   && GET_CODE (XEXP (X, 0)) == REG                            \
+   && INT_REG_OK_FOR_BASE_P (XEXP (X, 0), (STRICT))            \
    && CONSTANT_P (XEXP (X, 1)))
 
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)                \
-{ if (LEGITIMATE_INDIRECT_ADDRESS_P (X))               \
-    goto ADDR;                                         \
-  if ((GET_CODE (X) == PRE_INC || GET_CODE (X) == PRE_DEC) \
-      && TARGET_UPDATE                                 \
-      && LEGITIMATE_INDIRECT_ADDRESS_P (XEXP (X, 0)))  \
-    goto ADDR;                                         \
-  if (LEGITIMATE_SMALL_DATA_P (MODE, X))               \
-    goto ADDR;                                         \
-  if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (X))          \
-    goto ADDR;                                         \
-  if (LEGITIMATE_OFFSET_ADDRESS_P (MODE, X))           \
-    goto ADDR;                                         \
-  if ((MODE) != TImode                                 \
-      && (TARGET_HARD_FLOAT || TARGET_POWERPC64 || (MODE) != DFmode) \
-      && (TARGET_POWERPC64 || (MODE) != DImode)                \
-      && LEGITIMATE_INDEXED_ADDRESS_P (X))             \
-    goto ADDR;                                         \
-  if (LEGITIMATE_LO_SUM_ADDRESS_P (MODE, X))           \
-    goto ADDR;                                         \
+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)                        \
+{ if (rs6000_legitimate_address (MODE, X, REG_OK_STRICT_FLAG)) \
+    goto ADDR;                                                 \
 }
 \f
 /* Try machine-dependent ways of modifying an illegitimate address
@@ -1990,43 +1963,13 @@ typedef struct rs6000_args
    Then check for the sum of a register and something not constant, try to
    load the other things into a register and return the sum.  */
 
-#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN)                            \
-{ if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == REG            \
-    && GET_CODE (XEXP (X, 1)) == CONST_INT                             \
-    && (unsigned HOST_WIDE_INT) (INTVAL (XEXP (X, 1)) + 0x8000) >= 0x10000) \
-    { HOST_WIDE_INT high_int, low_int;                                 \
-      rtx sum;                                                         \
-      high_int = INTVAL (XEXP (X, 1)) & (~ (HOST_WIDE_INT) 0xffff);    \
-      low_int = INTVAL (XEXP (X, 1)) & 0xffff;                         \
-      if (low_int & 0x8000)                                            \
-       high_int += 0x10000, low_int |= ((HOST_WIDE_INT) -1) << 16;     \
-      sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (X, 0),           \
-                                        GEN_INT (high_int)), 0);       \
-      (X) = gen_rtx_PLUS (Pmode, sum, GEN_INT (low_int));              \
-      goto WIN;                                                                \
-    }                                                                  \
-  else if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == REG       \
-          && GET_CODE (XEXP (X, 1)) != CONST_INT                       \
-          && (TARGET_HARD_FLOAT || TARGET_POWERPC64 || (MODE) != DFmode) \
-          && (TARGET_POWERPC64 || (MODE) != DImode)                    \
-          && (MODE) != TImode)                                         \
-    {                                                                  \
-      (X) = gen_rtx_PLUS (Pmode, XEXP (X, 0),                          \
-                         force_reg (Pmode, force_operand (XEXP (X, 1), 0))); \
-      goto WIN;                                                                \
-    }                                                                  \
-  else if (TARGET_ELF && TARGET_32BIT && TARGET_NO_TOC                 \
-          && !flag_pic                                                 \
-          && GET_CODE (X) != CONST_INT                                 \
-          && GET_CODE (X) != CONST_DOUBLE && CONSTANT_P (X)            \
-          && (TARGET_HARD_FLOAT || (MODE) != DFmode)                   \
-          && (MODE) != DImode && (MODE) != TImode)                     \
-    {                                                                  \
-      rtx reg = gen_reg_rtx (Pmode);                                   \
-      emit_insn (gen_elf_high (reg, (X)));                             \
-      (X) = gen_rtx_LO_SUM (Pmode, reg, (X));                          \
-      goto WIN;                                                                \
-    }                                                                  \
+#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN)                    \
+{  rtx result = rs6000_legitimize_address (X, OLDX, MODE);     \
+   if (result != NULL_RTX)                                     \
+     {                                                         \
+       (X) = result;                                           \
+       goto WIN;                                               \
+     }                                                         \
 }
 
 /* Try a machine-dependent way of reloading an illegitimate address
@@ -2037,48 +1980,55 @@ typedef struct rs6000_args
    register by splitting the addend across an addiu/addis and the mem insn.
    This cuts number of extra insns needed from 3 to 1.  */
    
-#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN)     \
-do {                                                                    \
-  /* We must recognize output that we have already generated ourselves.  */ \
-  if (GET_CODE (X) == PLUS                                             \
-      && GET_CODE (XEXP (X, 0)) == PLUS                                        \
-      && GET_CODE (XEXP (XEXP (X, 0), 0)) == REG                       \
-      && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT                 \
-      && GET_CODE (XEXP (X, 1)) == CONST_INT)                          \
-    {                                                                  \
-      push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL_PTR,       \
-                   BASE_REG_CLASS, GET_MODE (X), VOIDmode, 0, 0,        \
-                   OPNUM, TYPE);                                        \
-      goto WIN;                                                         \
-    }                                                                  \
-  if (GET_CODE (X) == PLUS                                              \
-      && GET_CODE (XEXP (X, 0)) == REG                                  \
-      && REGNO (XEXP (X, 0)) < FIRST_PSEUDO_REGISTER                    \
-      && REG_MODE_OK_FOR_BASE_P (XEXP (X, 0), MODE)                     \
-      && GET_CODE (XEXP (X, 1)) == CONST_INT)                           \
-    {                                                                   \
-      HOST_WIDE_INT val = INTVAL (XEXP (X, 1));                         \
-      HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;           \
-      HOST_WIDE_INT high                                                \
-        = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;       \
-                                                                        \
-      /* Check for 32-bit overflow.  */                                 \
-      if (high + low != val)                                            \
-        break;                                                          \
-                                                                        \
-      /* Reload the high part into a base reg; leave the low part       \
-         in the mem directly.  */                                       \
-                                                                        \
-      X = gen_rtx_PLUS (GET_MODE (X),                                   \
-                        gen_rtx_PLUS (GET_MODE (X), XEXP (X, 0),        \
-                                      GEN_INT (high)),                  \
-                        GEN_INT (low));                                 \
-                                                                        \
-      push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL_PTR,       \
-                   BASE_REG_CLASS, GET_MODE (X), VOIDmode, 0, 0,        \
-                   OPNUM, TYPE);                                        \
-      goto WIN;                                                         \
-    }                                                                   \
+#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN)         \
+do {                                                                        \
+  /* We must recognize output that we have already generated ourselves.  */  \
+  if (GET_CODE (X) == PLUS                                                  \
+      && GET_CODE (XEXP (X, 0)) == PLUS                                             \
+      && GET_CODE (XEXP (XEXP (X, 0), 0)) == REG                            \
+      && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT                      \
+      && GET_CODE (XEXP (X, 1)) == CONST_INT)                               \
+    {                                                                       \
+      push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL,               \
+                   BASE_REG_CLASS, GET_MODE (X), VOIDmode, 0, 0,            \
+                   OPNUM, TYPE);                                            \
+      goto WIN;                                                                     \
+    }                                                                       \
+  if (GET_CODE (X) == PLUS                                                  \
+      && GET_CODE (XEXP (X, 0)) == REG                                      \
+      && REGNO (XEXP (X, 0)) < FIRST_PSEUDO_REGISTER                        \
+      && REG_MODE_OK_FOR_BASE_P (XEXP (X, 0), MODE)                         \
+      && GET_CODE (XEXP (X, 1)) == CONST_INT)                               \
+    {                                                                       \
+      HOST_WIDE_INT val = INTVAL (XEXP (X, 1));                                     \
+      HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;               \
+      HOST_WIDE_INT high                                                    \
+        = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;           \
+                                                                            \
+      /* Check for 32-bit overflow.  */                                             \
+      if (high + low != val)                                                \
+        break;                                                              \
+                                                                            \
+      /* Reload the high part into a base reg; leave the low part           \
+         in the mem directly.  */                                           \
+                                                                            \
+      X = gen_rtx_PLUS (GET_MODE (X),                                       \
+                        gen_rtx_PLUS (GET_MODE (X), XEXP (X, 0),            \
+                                      GEN_INT (high)),                      \
+                        GEN_INT (low));                                             \
+                                                                            \
+      push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL,               \
+                   BASE_REG_CLASS, GET_MODE (X), VOIDmode, 0, 0,            \
+                   OPNUM, TYPE);                                            \
+      goto WIN;                                                                     \
+    }                                                                       \
+  else if (TARGET_TOC                                                       \
+          && CONSTANT_POOL_EXPR_P (X)                                       \
+          && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (X), MODE)) \
+    {                                                                       \
+      (X) = create_TOC_reference (X);                                       \
+      goto WIN;                                                                     \
+    }                                                                       \
 } while (0)
 
 /* Go to LABEL if ADDR (a legitimate address expression)
@@ -2114,6 +2064,8 @@ do {                                                                    \
 
 #define PIC_OFFSET_TABLE_REGNUM 30
 
+#define TOC_REGISTER (TARGET_MINIMAL_TOC ? 30 : 2)
+
 /* Define this macro if the register defined by
    `PIC_OFFSET_TABLE_REGNUM' is clobbered by calls.  Do not define
    this macro if `PPIC_OFFSET_TABLE_REGNUM' is not defined. */
@@ -2150,12 +2102,9 @@ do {                                                                    \
 /* In rare cases, correct code generation requires extra machine
    dependent processing between the second jump optimization pass and
    delayed branch scheduling.  On those machines, define this macro
-   as a C statement to act on the code starting at INSN.
+   as a C statement to act on the code starting at INSN.  */
 
-   On the RS/6000, we use it to make sure the GOT_TOC register marker
-   that FINALIZE_PIC is supposed to remove actually got removed.  */
-
-#define MACHINE_DEPENDENT_REORG(INSN) rs6000_reorg (INSN)
+/* #define MACHINE_DEPENDENT_REORG(INSN) */
 
 \f
 /* Define this if some processing needs to be done immediately before
@@ -2165,7 +2114,7 @@ do {                                                                    \
 
 /* Specify the machine mode that this machine uses
    for the index in the tablejump instruction.  */
-#define CASE_VECTOR_MODE (TARGET_32BIT ? SImode : DImode)
+#define CASE_VECTOR_MODE SImode
 
 /* Define as C expression which evaluates to nonzero if the tablejump
    instruction expects the table to contain offsets from the address of the
@@ -2210,38 +2159,6 @@ do {                                                                    \
 /* Define if loading short immediate values into registers sign extends.  */
 #define SHORT_IMMEDIATES_SIGN_EXTEND
 \f
-/* The RS/6000 uses the XCOFF format.  */
-
-#define XCOFF_DEBUGGING_INFO
-
-/* Define if the object format being used is COFF or a superset.  */
-#define OBJECT_FORMAT_COFF
-
-/* Define the magic numbers that we recognize as COFF.
-
-   AIX 4.3 adds U803XTOCMAGIC (0757) for 64-bit objects, but collect2.c
-   does not include files in the correct order to conditionally define
-   the symbolic name in this macro. 
-
-   The AIX linker accepts import/export files as object files,
-   so accept "#!" (0x2321) magic number.  */
-#define MY_ISCOFF(magic) \
-  ((magic) == U802WRMAGIC || (magic) == U802ROMAGIC \
-   || (magic) == U802TOCMAGIC || (magic) == 0757 || (magic) == 0x2321)
-
-/* This is the only version of nm that collect2 can work with.  */
-#define REAL_NM_FILE_NAME "/usr/ucb/nm"
-
-/* We don't have GAS for the RS/6000 yet, so don't write out special
-   .stabs in cc1plus.  */
-
-#define FASCIST_ASSEMBLER
-
-/* AIX does not have any init/fini or ctor/dtor sections, so create
-   static constructors and destructors as normal functions.  */
-/* #define ASM_OUTPUT_CONSTRUCTOR(file, name) */
-/* #define ASM_OUTPUT_DESTRUCTOR(file, name) */
-
 /* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
    is done just by pretending it is already truncated.  */
 #define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
@@ -2269,10 +2186,6 @@ do {                                                                    \
 
 #define SHIFT_COUNT_TRUNCATED (TARGET_POWER ? 1 : 0)
 
-/* Use atexit for static constructors/destructors, instead of defining
-   our own exit function.  */
-#define HAVE_ATEXIT
-
 /* Compute the cost of computing a constant rtl expression RTX
    whose rtx-code is CODE.  The body of this macro is a portion
    of a switch statement.  If the code is computed here,
@@ -2329,6 +2242,8 @@ do {                                                                    \
         return COSTS_N_INSNS (2);                                      \
       case PROCESSOR_PPC601:                                           \
         return COSTS_N_INSNS (5);                                      \
+      case PROCESSOR_PPC7400:                                         \
+      case PROCESSOR_PPC7450:                                         \
       case PROCESSOR_PPC603:                                           \
       case PROCESSOR_PPC750:                                           \
         return (GET_CODE (XEXP (X, 1)) != CONST_INT                    \
@@ -2381,7 +2296,10 @@ do {                                                                    \
                ? COSTS_N_INSNS (21)                                    \
                : COSTS_N_INSNS (37));                                  \
       case PROCESSOR_PPC750:                                           \
+      case PROCESSOR_PPC7400:                                          \
         return COSTS_N_INSNS (19);                                     \
+      case PROCESSOR_PPC7450:                                          \
+        return COSTS_N_INSNS (23);                                     \
       }                                                                        \
   case FFS:                                                            \
     return COSTS_N_INSNS (4);                                          \
@@ -2413,18 +2331,19 @@ do {                                                                    \
    For the RS/6000, we need separate modes when unsigned (logical) comparisons
    are being done and we need a separate mode for floating-point.  We also
    use a mode for the case when we are comparing the results of two
-   comparisons.  */
+   comparisons, as then only the EQ bit is valid in the register.  */
 
 #define EXTRA_CC_MODES         \
     CC(CCUNSmode,  "CCUNS")    \
     CC(CCFPmode,   "CCFP")     \
     CC(CCEQmode,   "CCEQ")
 
-/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
-   return the mode to be used for the comparison.  For floating-point, CCFPmode
-   should be used.  CCUNSmode should be used for unsigned comparisons.
-   CCEQmode should be used when we are doing an inequality comparison on
-   the result of a comparison. CCmode should be used in all other cases.  */
+/* Given a comparison code (EQ, NE, etc.) and the first operand of a
+   COMPARE, return the mode to be used for the comparison.  For
+   floating-point, CCFPmode should be used.  CCUNSmode should be used
+   for unsigned comparisons.  CCEQmode should be used when we are
+   doing an inequality comparison on the result of a
+   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      \
@@ -2438,32 +2357,6 @@ do {                                                                    \
 
 extern struct rtx_def *rs6000_compare_op0, *rs6000_compare_op1;
 extern int rs6000_compare_fp_p;
-
-/* Set to non-zero by "fix" operation to indicate that itrunc and
-   uitrunc must be defined.  */
-
-extern int rs6000_trunc_used;
-
-/* Function names to call to do floating point truncation.  */
-
-#define RS6000_ITRUNC "__itrunc"
-#define RS6000_UITRUNC "__uitrunc"
-
-/* Prefix and suffix to use to saving floating point */
-#ifndef SAVE_FP_PREFIX
-#define        SAVE_FP_PREFIX "._savef"
-#define SAVE_FP_SUFFIX ""
-#endif
-
-/* Prefix and suffix to use to restoring floating point */
-#ifndef RESTORE_FP_PREFIX
-#define        RESTORE_FP_PREFIX "._restf"
-#define RESTORE_FP_SUFFIX ""
-#endif
-
-/* Function name to call to do profiling.  */
-#define RS6000_MCOUNT ".__mcount"
-
 \f
 /* Control the assembler format that we output.  */
 
@@ -2472,356 +2365,55 @@ extern int rs6000_trunc_used;
    the end of the line.  */
 #define ASM_COMMENT_START " #"
 
-/* Output at beginning of assembler file.
-
-   Initialize the section names for the RS/6000 at this point.
-
-   Specify filename, including full path, to assembler.
-
-   We want to go into the TOC section so at least one .toc will be emitted.
-   Also, in order to output proper .bs/.es pairs, we need at least one static
-   [RW] section emitted.
-
-   We then switch back to text to force the gcc2_compiled. label and the space
-   allocated after it (when profiling) into the text section.
-
-   Finally, declare mcount when profiling to make the assembler happy.  */
-
-#define ASM_FILE_START(FILE)                                   \
-{                                                              \
-  rs6000_gen_section_name (&xcoff_bss_section_name,            \
-                          main_input_filename, ".bss_");       \
-  rs6000_gen_section_name (&xcoff_private_data_section_name,   \
-                          main_input_filename, ".rw_");        \
-  rs6000_gen_section_name (&xcoff_read_only_section_name,      \
-                          main_input_filename, ".ro_");        \
-                                                               \
-  fprintf (FILE, "\t.file\t\"%s\"\n", main_input_filename);    \
-  if (TARGET_64BIT)                                            \
-    fputs ("\t.machine\t\"ppc64\"\n", FILE);                   \
-  toc_section ();                                              \
-  if (write_symbols != NO_DEBUG)                               \
-    private_data_section ();                                   \
-  text_section ();                                             \
-  if (profile_flag)                                            \
-    fprintf (FILE, "\t.extern %s\n", RS6000_MCOUNT);           \
-  rs6000_file_start (FILE, TARGET_CPU_DEFAULT);                        \
-}
-
-/* Output at end of assembler file.
-
-   On the RS/6000, referencing data should automatically pull in text.  */
-
-#define ASM_FILE_END(FILE)                                     \
-{                                                              \
-  text_section ();                                             \
-  fputs ("_section_.text:\n", FILE);                           \
-  data_section ();                                             \
-  fputs ("\t.long _section_.text\n", FILE);                    \
-}
-
-/* We define this to prevent the name mangler from putting dollar signs into
-   function names.  */
-
-#define NO_DOLLAR_IN_LABEL
-
-/* We define this to 0 so that gcc will never accept a dollar sign in a
-   variable name.  This is needed because the AIX assembler will not accept
-   dollar signs.  */
-
-#define DOLLARS_IN_IDENTIFIERS 0
-
 /* Implicit library calls should use memcpy, not bcopy, etc.  */
 
 #define TARGET_MEM_FUNCTIONS
 
-/* Define the extra sections we need.  We define three: one is the read-only
-   data section which is used for constants.  This is a csect whose name is
-   derived from the name of the input file.  The second is for initialized
-   global variables.  This is a csect whose name is that of the variable.
-   The third is the TOC.  */
-
-#define EXTRA_SECTIONS \
-   read_only_data, private_data, read_only_private_data, toc, bss
-
-/* Define the name of our readonly data section.  */
-
-#define READONLY_DATA_SECTION read_only_data_section
-
-
-/* Define the name of the section to use for the exception tables.
-   TODO: test and see if we can use read_only_data_section, if so,
-   remove this.  */
-
-#define EXCEPTION_SECTION data_section
-
-/* If we are referencing a function that is static or is known to be
-   in this file, make the SYMBOL_REF special.  We can use this to indicate
-   that we can branch to this function without emitting a no-op after the
-   call.  Do not set this flag if the function is weakly defined. */
-
-#define ENCODE_SECTION_INFO(DECL)  \
-  if (TREE_CODE (DECL) == FUNCTION_DECL                        \
-      && (TREE_ASM_WRITTEN (DECL) || ! TREE_PUBLIC (DECL)) \
-      && !DECL_WEAK (DECL)) \
-    SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1;
-
-/* Indicate that jump tables go in the text section.  */
-
-#define JUMP_TABLES_IN_TEXT_SECTION 1
-
-/* Define the routines to implement these extra sections.
-   BIGGEST_ALIGNMENT is 64, so align the sections that much.  */
-
-#define EXTRA_SECTION_FUNCTIONS                                \
-                                                       \
-void                                                   \
-read_only_data_section ()                              \
-{                                                      \
-  if (in_section != read_only_data)                    \
-    {                                                  \
-      fprintf (asm_out_file, ".csect %s[RO],3\n",      \
-              xcoff_read_only_section_name);           \
-      in_section = read_only_data;                     \
-    }                                                  \
-}                                                      \
-                                                       \
-void                                                   \
-private_data_section ()                                        \
-{                                                      \
-  if (in_section != private_data)                      \
-    {                                                  \
-      fprintf (asm_out_file, ".csect %s[RW],3\n",      \
-              xcoff_private_data_section_name);        \
-      in_section = private_data;                       \
-    }                                                  \
-}                                                      \
-                                                       \
-void                                                   \
-read_only_private_data_section ()                      \
-{                                                      \
-  if (in_section != read_only_private_data)            \
-    {                                                  \
-      fprintf (asm_out_file, ".csect %s[RO],3\n",      \
-              xcoff_private_data_section_name);        \
-      in_section = read_only_private_data;             \
-    }                                                  \
-}                                                      \
-                                                       \
-void                                                   \
-toc_section ()                                         \
-{                                                      \
-  if (TARGET_MINIMAL_TOC)                              \
-    {                                                  \
-      /* toc_section is always called at least once from ASM_FILE_START, \
-        so this is guaranteed to always be defined once and only once   \
-        in each file.  */                                               \
-      if (! toc_initialized)                           \
-       {                                               \
-         fputs (".toc\nLCTOC..0:\n", asm_out_file);    \
-         fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file); \
-         toc_initialized = 1;                          \
-       }                                               \
-                                                       \
-      if (in_section != toc)                           \
-       fprintf (asm_out_file, ".csect toc_table[RW]%s\n",      \
-                (TARGET_32BIT ? "" : ",3"));           \
-    }                                                  \
-  else                                                 \
-    {                                                  \
-      if (in_section != toc)                           \
-        fputs (".toc\n", asm_out_file);                        \
-    }                                                  \
-  in_section = toc;                                    \
-}
-
 /* Flag to say the TOC is initialized */
 extern int toc_initialized;
 
-/* This macro produces the initial definition of a function name.
-   On the RS/6000, we need to place an extra '.' in the function name and
-   output the function descriptor.
-
-   The csect for the function will have already been created by the
-   `text_section' call previously done.  We do have to go back to that
-   csect, however.  */
-
-/* ??? What do the 16 and 044 in the .function line really mean?  */
-
-#define ASM_DECLARE_FUNCTION_NAME(FILE,NAME,DECL)              \
-{ if (TREE_PUBLIC (DECL))                                      \
-    {                                                          \
-      fputs ("\t.globl .", FILE);                              \
-      RS6000_OUTPUT_BASENAME (FILE, NAME);                     \
-      putc ('\n', FILE);                                       \
-    }                                                          \
-  else                                                         \
-    {                                                          \
-      fputs ("\t.lglobl .", FILE);                             \
-      RS6000_OUTPUT_BASENAME (FILE, NAME);                     \
-      putc ('\n', FILE);                                       \
-    }                                                          \
-  fputs (".csect ", FILE);                                     \
-  RS6000_OUTPUT_BASENAME (FILE, NAME);                         \
-  fputs (TARGET_32BIT ? "[DS]\n" : "[DS],3\n", FILE);          \
-  RS6000_OUTPUT_BASENAME (FILE, NAME);                         \
-  fputs (":\n", FILE);                                         \
-  fputs (TARGET_32BIT ? "\t.long ." : "\t.llong .", FILE);     \
-  RS6000_OUTPUT_BASENAME (FILE, NAME);                         \
-  fputs (", TOC[tc0], 0\n", FILE);                             \
-  fputs (".csect .text[PR]\n.", FILE);                         \
-  RS6000_OUTPUT_BASENAME (FILE, NAME);                         \
-  fputs (":\n", FILE);                                         \
-  if (write_symbols == XCOFF_DEBUG)                            \
-    xcoffout_declare_function (FILE, DECL, NAME);              \
-}
-
-/* Return non-zero if this entry is to be written into the constant pool
-   in a special way.  We do so if this is a SYMBOL_REF, LABEL_REF or a CONST
-   containing one of them.  If -mfp-in-toc (the default), we also do
-   this for floating-point constants.  We actually can only do this
-   if the FP formats of the target and host machines are the same, but
-   we can't check that since not every file that uses
-   GO_IF_LEGITIMATE_ADDRESS_P includes real.h.  */
-
-#define ASM_OUTPUT_SPECIAL_POOL_ENTRY_P(X)                             \
-  (TARGET_TOC                                                          \
-   && (GET_CODE (X) == SYMBOL_REF                                      \
-       || (GET_CODE (X) == CONST && GET_CODE (XEXP (X, 0)) == PLUS     \
-          && GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF)           \
-       || GET_CODE (X) == LABEL_REF                                    \
-       || (! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)             \
-          && GET_CODE (X) == CONST_DOUBLE                              \
-          && (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT              \
-              || (TARGET_POWERPC64 && GET_MODE (X) == DImode)))))
-#if 0
-          && BITS_PER_WORD == HOST_BITS_PER_INT)))
-#endif
-
-/* Select section for constant in constant pool.
-
-   On RS/6000, all constants are in the private read-only data area.
-   However, if this is being placed in the TOC it must be output as a
-   toc entry.  */
-
-#define SELECT_RTX_SECTION(MODE, X)            \
-{ if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (X))     \
-    toc_section ();                            \
-  else                                         \
-    read_only_private_data_section ();         \
-}
-
 /* Macro to output a special constant pool entry.  Go to WIN if we output
    it.  Otherwise, it is written the usual way.
 
    On the RS/6000, toc entries are handled this way.  */
 
-#define ASM_OUTPUT_SPECIAL_POOL_ENTRY(FILE, X, MODE, ALIGN, LABELNO, WIN)  \
-{ if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (X))     \
-    {                                          \
-      output_toc (FILE, X, LABELNO);           \
-      goto WIN;                                        \
-    }                                          \
+#define ASM_OUTPUT_SPECIAL_POOL_ENTRY(FILE, X, MODE, ALIGN, LABELNO, WIN) \
+{ if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (X, MODE))                         \
+    {                                                                    \
+      output_toc (FILE, X, LABELNO, MODE);                               \
+      goto WIN;                                                                  \
+    }                                                                    \
 }
 
-/* Select the section for an initialized data object.
-
-   On the RS/6000, we have a special section for all variables except those
-   that are static.  */
-
-#define SELECT_SECTION(EXP,RELOC)                      \
-{                                                      \
-  if ((TREE_CODE (EXP) == STRING_CST                   \
-       && ! flag_writable_strings)                     \
-      || (TREE_CODE_CLASS (TREE_CODE (EXP)) == 'd'     \
-         && TREE_READONLY (EXP) && ! TREE_THIS_VOLATILE (EXP) \
-         && DECL_INITIAL (EXP)                         \
-         && (DECL_INITIAL (EXP) == error_mark_node     \
-             || TREE_CONSTANT (DECL_INITIAL (EXP)))    \
-         && ! (RELOC)))                                \
-    {                                                  \
-      if (TREE_PUBLIC (EXP))                           \
-        read_only_data_section ();                     \
-      else                                             \
-        read_only_private_data_section ();             \
-    }                                                  \
-  else                                                 \
+/* This implementes the `alias' attribute.  */
+
+#define ASM_OUTPUT_DEF_FROM_DECLS(FILE,decl,target)    \
+do {                                                   \
+  const char * alias = XSTR (XEXP (DECL_RTL (decl), 0), 0); \
+  char * name = IDENTIFIER_POINTER (target);           \
+  if (TREE_CODE (decl) == FUNCTION_DECL                        \
+      && DEFAULT_ABI == ABI_AIX)                       \
     {                                                  \
-      if (TREE_PUBLIC (EXP))                           \
-        data_section ();                               \
+      if (TREE_PUBLIC (decl))                          \
+       {                                               \
+         fputs ("\t.globl .", FILE);                   \
+         assemble_name (FILE, alias);                  \
+         putc ('\n', FILE);                            \
+       }                                               \
       else                                             \
-        private_data_section ();                       \
+       {                                               \
+         fputs ("\t.lglobl .", FILE);                  \
+         assemble_name (FILE, alias);                  \
+         putc ('\n', FILE);                            \
+       }                                               \
+      fputs ("\t.set .", FILE);                                \
+      assemble_name (FILE, alias);                     \
+      fputs (",.", FILE);                              \
+      assemble_name (FILE, name);                      \
+      fputc ('\n', FILE);                              \
     }                                                  \
-}
-
-/* This outputs NAME to FILE up to the first null or '['.  */
-
-#define RS6000_OUTPUT_BASENAME(FILE, NAME)     \
-  {                                            \
-    const char *_p;                            \
-                                               \
-    STRIP_NAME_ENCODING (_p, (NAME));          \
-    assemble_name ((FILE), _p);                        \
-  }
-
-/* Remove any trailing [DS] or the like from the symbol name.  */
-
-#define STRIP_NAME_ENCODING(VAR,NAME)                                  \
-  do                                                                   \
-    {                                                                  \
-      const char *_name = (NAME);                                      \
-      int _len;                                                                \
-      if (_name[0] == '*')                                             \
-       _name++;                                                        \
-      _len = strlen (_name);                                           \
-      if (_name[_len - 1] != ']')                                      \
-       (VAR) = _name;                                                  \
-      else                                                             \
-       {                                                               \
-         char *_new_name = (char *) alloca (_len + 1);                 \
-         strcpy (_new_name, _name);                                    \
-         _new_name[_len - 4] = '\0';                                   \
-         (VAR) = _new_name;                                            \
-       }                                                               \
-    }                                                                  \
-  while (0)
-
-/* Output something to declare an external symbol to the assembler.  Most
-   assemblers don't need this.
-
-   If we haven't already, add "[RW]" (or "[DS]" for a function) to the
-   name.  Normally we write this out along with the name.  In the few cases
-   where we can't, it gets stripped off.  */
-
-#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME)  \
-{ rtx _symref = XEXP (DECL_RTL (DECL), 0);     \
-  if ((TREE_CODE (DECL) == VAR_DECL            \
-       || TREE_CODE (DECL) == FUNCTION_DECL)   \
-      && (NAME)[strlen (NAME) - 1] != ']')     \
-    {                                          \
-      char *_name = (char *) permalloc (strlen (XSTR (_symref, 0)) + 5); \
-      strcpy (_name, XSTR (_symref, 0));       \
-      strcat (_name, TREE_CODE (DECL) == FUNCTION_DECL ? "[DS]" : "[RW]"); \
-      XSTR (_symref, 0) = _name;               \
-    }                                          \
-  fputs ("\t.extern ", FILE);                  \
-  assemble_name (FILE, XSTR (_symref, 0));     \
-  if (TREE_CODE (DECL) == FUNCTION_DECL)       \
-    {                                          \
-      fputs ("\n\t.extern .", FILE);           \
-      RS6000_OUTPUT_BASENAME (FILE, XSTR (_symref, 0));        \
-    }                                          \
-  putc ('\n', FILE);                           \
-}
-
-/* Similar, but for libcall.  We only have to worry about the function name,
-   not that of the descriptor. */
-
-#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN) \
-{ fputs ("\t.extern .", FILE);                 \
-  assemble_name (FILE, XSTR (FUN, 0));         \
-  putc ('\n', FILE);                           \
-}
+  ASM_OUTPUT_DEF (FILE, alias, name);                  \
+} while (0)
 
 /* Output to assembler file text saying following lines
    may contain character constants, extra white space, comments, etc.  */
@@ -2833,17 +2425,6 @@ extern int toc_initialized;
 
 #define ASM_APP_OFF ""
 
-/* Output before instructions.
-   Text section for 64-bit target may contain 64-bit address jump table.  */
-
-#define TEXT_SECTION_ASM_OP (TARGET_32BIT \
-                            ? ".csect .text[PR]" : ".csect .text[PR],3")
-
-/* Output before writable data.
-   Align entire section to BIGGEST_ALIGNMENT.  */
-
-#define DATA_SECTION_ASM_OP ".csect .data[RW],3"
-
 /* How to refer to registers in assembler output.
    This sequence is indexed by compiler's hard-register-number (see above).  */
 
@@ -2931,7 +2512,41 @@ extern char rs6000_reg_names[][8];       /* register names (0 vs. %r0). */
   &rs6000_reg_names[74][0],    /* cr6  */                              \
   &rs6000_reg_names[75][0],    /* cr7  */                              \
                                                                        \
-  &rs6000_reg_names[76][0],    /* fpmem */                             \
+  &rs6000_reg_names[76][0],    /* xer  */                              \
+                                                                       \
+  &rs6000_reg_names[77][0],    /* v0  */                               \
+  &rs6000_reg_names[78][0],    /* v1  */                               \
+  &rs6000_reg_names[79][0],    /* v2  */                               \
+  &rs6000_reg_names[80][0],    /* v3  */                               \
+  &rs6000_reg_names[81][0],    /* v4  */                               \
+  &rs6000_reg_names[82][0],    /* v5  */                               \
+  &rs6000_reg_names[83][0],    /* v6  */                               \
+  &rs6000_reg_names[84][0],    /* v7  */                               \
+  &rs6000_reg_names[85][0],    /* v8  */                               \
+  &rs6000_reg_names[86][0],    /* v9  */                               \
+  &rs6000_reg_names[87][0],    /* v10  */                              \
+  &rs6000_reg_names[88][0],    /* v11  */                              \
+  &rs6000_reg_names[89][0],    /* v12  */                              \
+  &rs6000_reg_names[90][0],    /* v13  */                              \
+  &rs6000_reg_names[91][0],    /* v14  */                              \
+  &rs6000_reg_names[92][0],    /* v15  */                              \
+  &rs6000_reg_names[93][0],    /* v16  */                              \
+  &rs6000_reg_names[94][0],    /* v17  */                              \
+  &rs6000_reg_names[95][0],    /* v18  */                              \
+  &rs6000_reg_names[96][0],    /* v19  */                              \
+  &rs6000_reg_names[97][0],    /* v20  */                              \
+  &rs6000_reg_names[98][0],    /* v21  */                              \
+  &rs6000_reg_names[99][0],    /* v22  */                              \
+  &rs6000_reg_names[100][0],   /* v23  */                              \
+  &rs6000_reg_names[101][0],   /* v24  */                              \
+  &rs6000_reg_names[102][0],   /* v25  */                              \
+  &rs6000_reg_names[103][0],   /* v26  */                              \
+  &rs6000_reg_names[104][0],   /* v27  */                              \
+  &rs6000_reg_names[105][0],   /* v28  */                              \
+  &rs6000_reg_names[106][0],   /* v29  */                              \
+  &rs6000_reg_names[107][0],   /* v30  */                              \
+  &rs6000_reg_names[108][0],   /* v31  */                              \
+  &rs6000_reg_names[109][0],   /* vrsave  */                           \
 }
 
 /* print-rtl can't handle the above REGISTER_NAMES, so define the
@@ -2950,7 +2565,12 @@ extern char rs6000_reg_names[][8];       /* register names (0 vs. %r0). */
     "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",            \
      "mq",  "lr", "ctr",  "ap",                                                \
     "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",            \
-  "fpmem"                                                              \
+  "xer",                                                               \
+     "v0",  "v1",  "v2",  "v3",  "v4",  "v5",  "v6",  "v7",             \
+     "v8",  "v9", "v10", "v11", "v12", "v13", "v14", "v15",             \
+    "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",             \
+    "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",             \
+    "vrsave"                                                           \
 }
 
 /* Table of additional register names to use in user input.  */
@@ -2972,6 +2592,15 @@ extern char rs6000_reg_names[][8];       /* register names (0 vs. %r0). */
   {"fr20", 52}, {"fr21", 53}, {"fr22", 54}, {"fr23", 55},      \
   {"fr24", 56}, {"fr25", 57}, {"fr26", 58}, {"fr27", 59},      \
   {"fr28", 60}, {"fr29", 61}, {"fr30", 62}, {"fr31", 63},      \
+  {"v0",   77}, {"v1",   78}, {"v2",   79}, {"v3",   80},       \
+  {"v4",   81}, {"v5",   82}, {"v6",   83}, {"v7",   84},       \
+  {"v8",   85}, {"v9",   86}, {"v10",  87}, {"v11",  88},       \
+  {"v12",  89}, {"v13",  90}, {"v14",  91}, {"v15",  92},       \
+  {"v16",  93}, {"v17",  94}, {"v18",  95}, {"v19",  96},       \
+  {"v20",  97}, {"v21",  98}, {"v22",  99}, {"v23",  100},     \
+  {"v24",  101},{"v25",  102},{"v26",  103},{"v27",  104},      \
+  {"v28",  105},{"v29",  106},{"v30",  107},{"v31",  108},      \
+  {"vrsave", 109},                                             \
   /* no additional names for: mq, lr, ctr, ap */               \
   {"cr0",  68}, {"cr1",  69}, {"cr2",  70}, {"cr3",  71},      \
   {"cr4",  72}, {"cr5",  73}, {"cr6",  74}, {"cr7",  75},      \
@@ -2985,52 +2614,6 @@ extern char rs6000_reg_names[][8];       /* register names (0 vs. %r0). */
    the loader.  This depends on the AIX version.  */
 #define RS6000_CALL_GLUE "cror 31,31,31"
 
-/* This is how to output the definition of a user-level label named NAME,
-   such as the label on a static function or variable NAME.  */
-
-#define ASM_OUTPUT_LABEL(FILE,NAME)    \
-  do { RS6000_OUTPUT_BASENAME (FILE, NAME); fputs (":\n", FILE); } while (0)
-
-/* This is how to output a command to make the user-level label named NAME
-   defined for reference from other files.  */
-
-#define ASM_GLOBALIZE_LABEL(FILE,NAME) \
-  do { fputs ("\t.globl ", FILE);      \
-       RS6000_OUTPUT_BASENAME (FILE, NAME); putc ('\n', FILE);} while (0)
-
-/* This is how to output a reference to a user-level label named NAME.
-   `assemble_name' uses this.  */
-
-#define ASM_OUTPUT_LABELREF(FILE,NAME) \
-  fputs (NAME, FILE)
-
-/* This is how to output an internal numbered label where
-   PREFIX is the class of label and NUM is the number within the class.  */
-
-#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM)     \
-  fprintf (FILE, "%s..%d:\n", PREFIX, NUM)
-
-/* This is how to output an internal label prefix.  rs6000.c uses this
-   when generating traceback tables.  */
-
-#define ASM_OUTPUT_INTERNAL_LABEL_PREFIX(FILE,PREFIX)  \
-  fprintf (FILE, "%s..", PREFIX)
-
-/* This is how to output a label for a jump table.  Arguments are the same as
-   for ASM_OUTPUT_INTERNAL_LABEL, except the insn for the jump table is
-   passed. */
-
-#define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLEINSN)       \
-{ ASM_OUTPUT_ALIGN (FILE, 2); ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM); }
-
-/* This is how to store into the string LABEL
-   the symbol_ref name of an internal numbered label where
-   PREFIX is the class of label and NUM is the number within the class.
-   This is suitable for output with `assemble_name'.  */
-
-#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM)  \
-  sprintf (LABEL, "*%s..%d", PREFIX, NUM)
-
 /* This is how to output an assembler line defining a `double' constant.  */
 
 #define ASM_OUTPUT_DOUBLE(FILE, VALUE)                 \
@@ -3057,13 +2640,13 @@ do {                                                                    \
   if (TARGET_32BIT)                                                    \
     {                                                                  \
       assemble_integer (operand_subword ((VALUE), 0, 0, DImode),       \
-                        UNITS_PER_WORD, 1);                            \
+                        UNITS_PER_WORD, BITS_PER_WORD, 1);             \
       assemble_integer (operand_subword ((VALUE), 1, 0, DImode),       \
-                        UNITS_PER_WORD, 1);                            \
+                        UNITS_PER_WORD, BITS_PER_WORD, 1);             \
     }                                                                  \
   else                                                                 \
     {                                                                  \
-      fputs ("\t.llong ", FILE);                                       \
+      fprintf (FILE, "%s", DOUBLE_INT_ASM_OP);                         \
       output_addr_const (FILE, (VALUE));                               \
       putc ('\n', FILE);                                               \
     }                                                                  \
@@ -3089,30 +2672,16 @@ do {                                                                    \
 /* This is how to output an assembler line for a numeric constant byte.  */
 
 #define ASM_OUTPUT_BYTE(FILE,VALUE)  \
-  fprintf (FILE, "\t.byte 0x%x\n", (VALUE))
-
-/* This is how to output an assembler line to define N characters starting
-   at P to FILE.  */
+  fprintf (FILE, "\t.byte 0x%x\n", (int)(VALUE))
 
-#define ASM_OUTPUT_ASCII(FILE, P, N)  output_ascii ((FILE), (P), (N))
-
-/* This is how to output an element of a case-vector that is absolute.
-   (RS/6000 does not use such vectors, but we must define this macro
-   anyway.)   */
-
-#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)           \
-  do { char buf[100];                                  \
-       fputs (TARGET_32BIT ? "\t.long " : "\t.llong ", FILE);  \
-       ASM_GENERATE_INTERNAL_LABEL (buf, "L", VALUE);  \
-       assemble_name (FILE, buf);                      \
-       putc ('\n', FILE);                              \
-     } while (0)
+/* This is used by the definition of ASM_OUTPUT_ADDR_ELT in defaults.h.  */
+#define ASM_LONG (TARGET_32BIT ? ".long" : DOUBLE_INT_ASM_OP)
 
 /* This is how to output an element of a case-vector that is relative.  */
 
-#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL)       \
+#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
   do { char buf[100];                                  \
-       fputs (TARGET_32BIT ? "\t.long " : "\t.llong ", FILE);  \
+       fputs ("\t.long ", FILE);                       \
        ASM_GENERATE_INTERNAL_LABEL (buf, "L", VALUE);  \
        assemble_name (FILE, buf);                      \
        putc ('-', FILE);                               \
@@ -3129,34 +2698,6 @@ do {                                                                     \
   if ((LOG) != 0)                      \
     fprintf (FILE, "\t.align %d\n", (LOG))
 
-#define ASM_OUTPUT_SKIP(FILE,SIZE)  \
-  fprintf (FILE, "\t.space %d\n", (SIZE))
-
-/* This says how to output an assembler line
-   to define a global common symbol.  */
-
-#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGNMENT) \
-  do { fputs (".comm ", (FILE));                       \
-       RS6000_OUTPUT_BASENAME ((FILE), (NAME));                \
-       if ( (SIZE) > 4)                                        \
-         fprintf ((FILE), ",%d,3\n", (SIZE));          \
-       else                                            \
-        fprintf( (FILE), ",%d\n", (SIZE));             \
-  } while (0)
-
-/* This says how to output an assembler line
-   to define a local common symbol.
-   Alignment cannot be specified, but we can try to maintain
-   alignment after preceding TOC section if it was aligned
-   for 64-bit mode.  */
-
-#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED)    \
-  do { fputs (".lcomm ", (FILE));                      \
-       RS6000_OUTPUT_BASENAME ((FILE), (NAME));                \
-       fprintf ((FILE), ",%d,%s\n", (TARGET_32BIT ? (SIZE) : (ROUNDED)), \
-               xcoff_bss_section_name);                \
-     } while (0)
-
 /* Store in OUTPUT a string (made with alloca) containing
    an assembler-name for a local static variable named NAME.
    LABELNO is an integer which is different for each call.  */
@@ -3165,20 +2706,16 @@ do {                                                                    \
 ( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10),   \
   sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))
 
-/* Define the parentheses used to group arithmetic operations
-   in assembler code.  */
+/* Pick up the return address upon entry to a procedure. Used for
+   dwarf2 unwind information.  This also enables the table driven
+   mechanism.  */
 
-#define ASM_OPEN_PAREN "("
-#define ASM_CLOSE_PAREN ")"
+#define INCOMING_RETURN_ADDR_RTX   gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
+#define DWARF_FRAME_RETURN_COLUMN  DWARF_FRAME_REGNUM (LINK_REGISTER_REGNUM)
 
-/* Define results of standard character escape sequences.  */
-#define TARGET_BELL 007
-#define TARGET_BS 010
-#define TARGET_TAB 011
-#define TARGET_NEWLINE 012
-#define TARGET_VT 013
-#define TARGET_FF 014
-#define TARGET_CR 015
+/* Describe how we implement __builtin_eh_return.  */
+#define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N) + 3 : INVALID_REGNUM)
+#define EH_RETURN_STACKADJ_RTX  gen_rtx_REG (Pmode, 10)
 
 /* Print operand X (an rtx) in assembler syntax to file FILE.
    CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
@@ -3197,165 +2734,183 @@ do {                                                                  \
 
 /* Define the codes that are matched by predicates in rs6000.c.  */
 
-#define PREDICATE_CODES                                                \
-  {"short_cint_operand", {CONST_INT}},                         \
-  {"u_short_cint_operand", {CONST_INT}},                       \
-  {"non_short_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_u_short_operand", {SUBREG, REG, CONST_INT}},        \
-  {"reg_or_cint_operand", {SUBREG, REG, CONST_INT}},           \
-  {"got_operand", {SYMBOL_REF, CONST, LABEL_REF}},             \
-  {"got_no_const_operand", {SYMBOL_REF, LABEL_REF}},           \
-  {"easy_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}},   \
-  {"logical_operand", {SUBREG, REG, CONST_INT}},               \
-  {"non_logical_cint_operand", {CONST_INT}},                   \
-  {"mask_operand", {CONST_INT}},                               \
-  {"mask64_operand", {CONST_INT, CONST_DOUBLE}},               \
-  {"count_register_operand", {REG}},                           \
-  {"fpmem_operand", {REG}},                                    \
-  {"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}},                    \
-  {"branch_comparison_operator", {EQ, NE, LE, LT, GE,          \
-                                 GT, LEU, LTU, GEU, GTU}},     \
-  {"scc_comparison_operator", {EQ, NE, LE, LT, GE,             \
-                              GT, LEU, LTU, GEU, GTU}},        \
-  {"trap_comparison_operator", {EQ, NE, LE, LT, GE,            \
-                               GT, LEU, LTU, GEU, GTU}},
+#define PREDICATE_CODES                                                           \
+  {"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_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}},                      \
+  {"easy_fp_constant", {CONST_DOUBLE}},                                           \
+  {"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}},              \
+  {"logical_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}},            \
+  {"non_logical_cint_operand", {CONST_INT, CONST_DOUBLE}},                \
+  {"mask_operand", {CONST_INT}},                                          \
+  {"mask64_operand", {CONST_INT, CONST_DOUBLE}},                          \
+  {"count_register_operand", {REG}},                                      \
+  {"xer_operand", {REG}},                                                 \
+  {"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}},                               \
+  {"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}},                                    \
+  {"min_max_operator", {SMIN, SMAX, UMIN, UMAX}},
 
 /* uncomment for disabling the corresponding default options */
 /* #define  MACHINE_no_sched_interblock */
 /* #define  MACHINE_no_sched_speculative */
 /* #define  MACHINE_no_sched_speculative_load */
 
-/* indicate that issue rate is defined for this machine
-   (no need to use the default) */
-#define ISSUE_RATE get_issue_rate ()
-
 /* General flags.  */
 extern int flag_pic;
 extern int optimize;
 extern int flag_expensive_optimizations;
 extern int frame_pointer_needed;
 
-/* Declare functions in rs6000.c */
-extern void optimization_options ();
-extern void output_options ();
-extern void rs6000_override_options ();
-extern void rs6000_file_start ();
-extern struct rtx_def *rs6000_float_const ();
-extern struct rtx_def *rs6000_got_register ();
-extern struct rtx_def *find_addr_reg();
-extern int direct_return ();
-extern int get_issue_rate ();
-extern int any_operand ();
-extern int short_cint_operand ();
-extern int u_short_cint_operand ();
-extern int non_short_cint_operand ();
-extern int gpc_reg_operand ();
-extern int cc_reg_operand ();
-extern int cc_reg_not_cr0_operand ();
-extern int reg_or_short_operand ();
-extern int reg_or_neg_short_operand ();
-extern int reg_or_u_short_operand ();
-extern int reg_or_cint_operand ();
-extern int got_operand ();
-extern int got_no_const_operand ();
-extern int num_insns_constant ();
-extern int easy_fp_constant ();
-extern int volatile_mem_operand ();
-extern int offsettable_mem_operand ();
-extern int mem_or_easy_const_operand ();
-extern int add_operand ();
-extern int non_add_cint_operand ();
-extern int non_logical_cint_operand ();
-extern int logical_operand ();
-extern int mask_operand ();
-extern int mask64_operand ();
-extern int and64_operand ();
-extern int and_operand ();
-extern int count_register_operand ();
-extern int fpmem_operand ();
-extern int reg_or_mem_operand ();
-extern int lwa_operand ();
-extern int call_operand ();
-extern int current_file_function_operand ();
-extern int input_operand ();
-extern int small_data_operand ();
-extern void init_cumulative_args ();
-extern void function_arg_advance ();
-extern int function_arg_boundary ();
-extern struct rtx_def *function_arg ();
-extern int function_arg_partial_nregs ();
-extern int function_arg_pass_by_reference ();
-extern void setup_incoming_varargs ();
-extern union tree_node *rs6000_va_list ();
-extern void rs6000_va_start ();
-extern struct rtx_def *rs6000_va_arg ();
-extern struct rtx_def *rs6000_stack_temp ();
-extern int expand_block_move ();
-extern int load_multiple_operation ();
-extern int store_multiple_operation ();
-extern int branch_comparison_operator ();
-extern int scc_comparison_operator ();
-extern int trap_comparison_operator ();
-extern int includes_lshift_p ();
-extern int includes_rshift_p ();
-extern int registers_ok_for_quad_peep ();
-extern int addrs_ok_for_quad_peep ();
-extern enum reg_class secondary_reload_class ();
-extern int ccr_bit ();
-extern void rs6000_finalize_pic ();
-extern void rs6000_reorg ();
-extern void rs6000_save_machine_status ();
-extern void rs6000_restore_machine_status ();
-extern void rs6000_init_expanders ();
-extern void print_operand ();
-extern void print_operand_address ();
-extern int first_reg_to_save ();
-extern int first_fp_reg_to_save ();
-extern int rs6000_makes_calls ();
-extern rs6000_stack_t *rs6000_stack_info ();
-extern void output_prolog ();
-extern void output_epilog ();
-extern void output_mi_thunk ();
-extern void output_toc ();
-extern void output_ascii ();
-extern void rs6000_gen_section_name ();
-extern void output_function_profiler ();
-extern int rs6000_adjust_cost ();
-extern int rs6000_adjust_priority ();
-extern void rs6000_trampoline_template ();
-extern int rs6000_trampoline_size ();
-extern void rs6000_initialize_trampoline ();
-extern void rs6000_output_load_toc_table ();
-extern int rs6000_comp_type_attributes ();
-extern int rs6000_valid_decl_attribute_p ();
-extern int rs6000_valid_type_attribute_p ();
-extern void rs6000_set_default_type_attributes ();
-extern struct rtx_def *rs6000_dll_import_ref ();
-extern struct rtx_def *rs6000_longcall_ref ();
-extern int function_arg_padding ();
-extern void toc_section ();
-extern void private_data_section ();
-extern void rs6000_fatal_bad_address ();
-
-/* See nonlocal_goto_receiver for when this must be set.  */
-
-#define DONT_ACCESS_GBLS_AFTER_EPILOGUE (TARGET_TOC && TARGET_MINIMAL_TOC)
+enum rs6000_builtins
+{
+  /* AltiVec builtins.  */
+  ALTIVEC_BUILTIN_ST_INTERNAL,
+  ALTIVEC_BUILTIN_LD_INTERNAL,
+  ALTIVEC_BUILTIN_VADDUBM,
+  ALTIVEC_BUILTIN_VADDUHM,
+  ALTIVEC_BUILTIN_VADDUWM,
+  ALTIVEC_BUILTIN_VADDFP,
+  ALTIVEC_BUILTIN_VADDCUW,
+  ALTIVEC_BUILTIN_VADDUBS,
+  ALTIVEC_BUILTIN_VADDSBS,
+  ALTIVEC_BUILTIN_VADDUHS,
+  ALTIVEC_BUILTIN_VADDSHS,
+  ALTIVEC_BUILTIN_VADDUWS,
+  ALTIVEC_BUILTIN_VADDSWS,
+  ALTIVEC_BUILTIN_VAND,
+  ALTIVEC_BUILTIN_VANDC,
+  ALTIVEC_BUILTIN_VAVGUB,
+  ALTIVEC_BUILTIN_VAVGSB,
+  ALTIVEC_BUILTIN_VAVGUH,
+  ALTIVEC_BUILTIN_VAVGSH,
+  ALTIVEC_BUILTIN_VAVGUW,
+  ALTIVEC_BUILTIN_VAVGSW,
+  ALTIVEC_BUILTIN_VCMPBFP,
+  ALTIVEC_BUILTIN_VCMPEQUB,
+  ALTIVEC_BUILTIN_VCMPEQUH,
+  ALTIVEC_BUILTIN_VCMPEQUW,
+  ALTIVEC_BUILTIN_VCMPEQFP,
+  ALTIVEC_BUILTIN_VCMPGEFP,
+  ALTIVEC_BUILTIN_VCMPGTUB,
+  ALTIVEC_BUILTIN_VCMPGTSB,
+  ALTIVEC_BUILTIN_VCMPGTUH,
+  ALTIVEC_BUILTIN_VCMPGTSH,
+  ALTIVEC_BUILTIN_VCMPGTUW,
+  ALTIVEC_BUILTIN_VCMPGTSW,
+  ALTIVEC_BUILTIN_VCMPGTFP,
+  ALTIVEC_BUILTIN_VMAXUB,
+  ALTIVEC_BUILTIN_VMAXSB,
+  ALTIVEC_BUILTIN_VMAXUH,
+  ALTIVEC_BUILTIN_VMAXSH,
+  ALTIVEC_BUILTIN_VMAXUW,
+  ALTIVEC_BUILTIN_VMAXSW,
+  ALTIVEC_BUILTIN_VMAXFP,
+  ALTIVEC_BUILTIN_VMRGHB,
+  ALTIVEC_BUILTIN_VMRGHH,
+  ALTIVEC_BUILTIN_VMRGHW,
+  ALTIVEC_BUILTIN_VMRGLB,
+  ALTIVEC_BUILTIN_VMRGLH,
+  ALTIVEC_BUILTIN_VMRGLW,
+  ALTIVEC_BUILTIN_VMINUB,
+  ALTIVEC_BUILTIN_VMINSB,
+  ALTIVEC_BUILTIN_VMINUH,
+  ALTIVEC_BUILTIN_VMINSH,
+  ALTIVEC_BUILTIN_VMINUW,
+  ALTIVEC_BUILTIN_VMINSW,
+  ALTIVEC_BUILTIN_VMINFP,
+  ALTIVEC_BUILTIN_VMULEUB,
+  ALTIVEC_BUILTIN_VMULESB,
+  ALTIVEC_BUILTIN_VMULEUH,
+  ALTIVEC_BUILTIN_VMULESH,
+  ALTIVEC_BUILTIN_VMULOUB,
+  ALTIVEC_BUILTIN_VMULOSB,
+  ALTIVEC_BUILTIN_VMULOUH,
+  ALTIVEC_BUILTIN_VMULOSH,
+  ALTIVEC_BUILTIN_VNOR,
+  ALTIVEC_BUILTIN_VOR,
+  ALTIVEC_BUILTIN_VPKUHUM,
+  ALTIVEC_BUILTIN_VPKUWUM,
+  ALTIVEC_BUILTIN_VPKPX,
+  ALTIVEC_BUILTIN_VPKUHSS,
+  ALTIVEC_BUILTIN_VPKSHSS,
+  ALTIVEC_BUILTIN_VPKUWSS,
+  ALTIVEC_BUILTIN_VPKSWSS,
+  ALTIVEC_BUILTIN_VPKUHUS,
+  ALTIVEC_BUILTIN_VPKSHUS,
+  ALTIVEC_BUILTIN_VPKUWUS,
+  ALTIVEC_BUILTIN_VPKSWUS,
+  ALTIVEC_BUILTIN_VRLB,
+  ALTIVEC_BUILTIN_VRLH,
+  ALTIVEC_BUILTIN_VRLW,
+  ALTIVEC_BUILTIN_VSLB,
+  ALTIVEC_BUILTIN_VSLH,
+  ALTIVEC_BUILTIN_VSLW,
+  ALTIVEC_BUILTIN_VSL,
+  ALTIVEC_BUILTIN_VSLO,
+  ALTIVEC_BUILTIN_VSRB,
+  ALTIVEC_BUILTIN_VRSH,
+  ALTIVEC_BUILTIN_VRSW,
+  ALTIVEC_BUILTIN_VSRAB,
+  ALTIVEC_BUILTIN_VSRAH,
+  ALTIVEC_BUILTIN_VSRAW,
+  ALTIVEC_BUILTIN_VSR,
+  ALTIVEC_BUILTIN_VSRO,
+  ALTIVEC_BUILTIN_VSUBUBM,
+  ALTIVEC_BUILTIN_VSUBUHM,
+  ALTIVEC_BUILTIN_VSUBUWM,
+  ALTIVEC_BUILTIN_VSUBFP,
+  ALTIVEC_BUILTIN_VSUBCUW,
+  ALTIVEC_BUILTIN_VSUBUBS,
+  ALTIVEC_BUILTIN_VSUBSBS,
+  ALTIVEC_BUILTIN_VSUBUHS,
+  ALTIVEC_BUILTIN_VSUBSHS,
+  ALTIVEC_BUILTIN_VSUBUWS,
+  ALTIVEC_BUILTIN_VSUBSWS,
+  ALTIVEC_BUILTIN_VSUM4UBS,
+  ALTIVEC_BUILTIN_VSUM4SBS,
+  ALTIVEC_BUILTIN_VSUM4SHS,
+  ALTIVEC_BUILTIN_VSUM2SWS,
+  ALTIVEC_BUILTIN_VSUMSWS,
+  ALTIVEC_BUILTIN_VXOR
+};