OSDN Git Service

Add sibcall handling for rs6000 target.
[pf3gnuchains/gcc-fork.git] / gcc / config / rs6000 / rs6000.h
index 2fa90b4..42aa929 100644 (file)
@@ -1,6 +1,6 @@
 /* Definitions of target machine for GNU compiler, for IBM RS/6000.
    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001 Free Software Foundation, Inc.
+   2000, 2001, 2002 Free Software Foundation, Inc.
    Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
 
 This file is part of GNU CC.
@@ -46,46 +46,6 @@ Boston, MA 02111-1307, USA.  */
 #define TARGET_CPU_DEFAULT ((char *)0)
 #endif
 
-/* Common CPP definitions used by CPP_SPEC among the various targets
-   for handling -mcpu=xxx switches.  */
-#define CPP_CPU_SPEC \
-"%{!mcpu*: \
-  %{mpower: %{!mpower2: -D_ARCH_PWR}} \
-  %{mpower2: -D_ARCH_PWR2} \
-  %{mpowerpc*: -D_ARCH_PPC} \
-  %{mno-power: %{!mpowerpc*: -D_ARCH_COM}} \
-  %{!mno-power: %{!mpower2: %(cpp_default)}}} \
-%{mcpu=common: -D_ARCH_COM} \
-%{mcpu=power: -D_ARCH_PWR} \
-%{mcpu=power2: -D_ARCH_PWR2} \
-%{mcpu=powerpc: -D_ARCH_PPC} \
-%{mcpu=rios: -D_ARCH_PWR} \
-%{mcpu=rios1: -D_ARCH_PWR} \
-%{mcpu=rios2: -D_ARCH_PWR2} \
-%{mcpu=rsc: -D_ARCH_PWR} \
-%{mcpu=rsc1: -D_ARCH_PWR} \
-%{mcpu=401: -D_ARCH_PPC} \
-%{mcpu=403: -D_ARCH_PPC} \
-%{mcpu=405: -D_ARCH_PPC} \
-%{mcpu=505: -D_ARCH_PPC} \
-%{mcpu=601: -D_ARCH_PPC -D_ARCH_PWR} \
-%{mcpu=602: -D_ARCH_PPC} \
-%{mcpu=603: -D_ARCH_PPC} \
-%{mcpu=603e: -D_ARCH_PPC} \
-%{mcpu=ec603e: -D_ARCH_PPC} \
-%{mcpu=604: -D_ARCH_PPC} \
-%{mcpu=604e: -D_ARCH_PPC} \
-%{mcpu=620: -D_ARCH_PPC} \
-%{mcpu=740: -D_ARCH_PPC} \
-%{mcpu=7400: -D_ARCH_PPC} \
-%{mcpu=7450: -D_ARCH_PPC} \
-%{mcpu=750: -D_ARCH_PPC} \
-%{mcpu=801: -D_ARCH_PPC} \
-%{mcpu=821: -D_ARCH_PPC} \
-%{mcpu=823: -D_ARCH_PPC} \
-%{mcpu=860: -D_ARCH_PPC} \
-%{maltivec: -D__ALTIVEC__}"
-
 /* Common ASM definitions used by ASM_SPEC among the various targets
    for handling -mcpu=xxx switches.  */
 #define ASM_CPU_SPEC \
@@ -98,6 +58,8 @@ Boston, MA 02111-1307, USA.  */
 %{mcpu=common: -mcom} \
 %{mcpu=power: -mpwr} \
 %{mcpu=power2: -mpwrx} \
+%{mcpu=power3: -m604} \
+%{mcpu=power4: -mpower4} \
 %{mcpu=powerpc: -mppc} \
 %{mcpu=rios: -mpwr} \
 %{mcpu=rios1: -mpwr} \
@@ -105,8 +67,8 @@ Boston, MA 02111-1307, USA.  */
 %{mcpu=rsc: -mpwr} \
 %{mcpu=rsc1: -mpwr} \
 %{mcpu=401: -mppc} \
-%{mcpu=403: -mppc} \
-%{mcpu=405: -mppc} \
+%{mcpu=403: -m403} \
+%{mcpu=405: -m405} \
 %{mcpu=505: -mppc} \
 %{mcpu=601: -m601} \
 %{mcpu=602: -mppc} \
@@ -116,6 +78,7 @@ Boston, MA 02111-1307, USA.  */
 %{mcpu=604: -mppc} \
 %{mcpu=604e: -mppc} \
 %{mcpu=620: -mppc} \
+%{mcpu=630: -m604} \
 %{mcpu=740: -mppc} \
 %{mcpu=7400: -mppc} \
 %{mcpu=7450: -mppc} \
@@ -124,6 +87,7 @@ Boston, MA 02111-1307, USA.  */
 %{mcpu=821: -mppc} \
 %{mcpu=823: -mppc} \
 %{mcpu=860: -mppc} \
+%{mcpu=8540: -me500} \
 %{maltivec: -maltivec}"
 
 #define CPP_DEFAULT_SPEC ""
@@ -143,7 +107,6 @@ Boston, MA 02111-1307, USA.  */
 #define SUBTARGET_EXTRA_SPECS
 
 #define EXTRA_SPECS                                                    \
-  { "cpp_cpu",                 CPP_CPU_SPEC },                         \
   { "cpp_default",             CPP_DEFAULT_SPEC },                     \
   { "asm_cpu",                 ASM_CPU_SPEC },                         \
   { "asm_default",             ASM_DEFAULT_SPEC },                     \
@@ -191,7 +154,7 @@ extern int target_flags;
    function, and one less allocable register.  */
 #define MASK_MINIMAL_TOC       0x00000200
 
-/* Nonzero for the 64bit model: ints, longs, and pointers are 64 bits.  */
+/* Nonzero for the 64bit model: longs and pointers are 64 bits.  */
 #define MASK_64BIT             0x00000400
 
 /* Disable use of FPRs.  */
@@ -395,7 +358,9 @@ enum processor_type
    PROCESSOR_PPC630,
    PROCESSOR_PPC750,
    PROCESSOR_PPC7400,
-   PROCESSOR_PPC7450
+   PROCESSOR_PPC7450,
+   PROCESSOR_PPC8540,
+   PROCESSOR_POWER4
 };
 
 extern enum processor_type rs6000_cpu;
@@ -417,23 +382,6 @@ extern enum processor_type rs6000_cpu;
    and the old mnemonics are dialect zero.  */
 #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
-   initializer with a subgrouping for each command option.
-
-   Each subgrouping contains a string constant, that defines the
-   fixed part of the option name, and the address of a variable.
-   The variable, type `char *', is set to the variable part of the
-   given option if the fixed part matches.  The actual option name
-   is made by appending `-m' to the specified name.
-
-   Here is an example which defines `-mshort-data-NUMBER'.  If the
-   given option is `-mshort-data-512', the variable `m88k_short_data'
-   will be set to the string `"512"'.
-
-       extern char *m88k_short_data;
-       #define TARGET_OPTIONS { { "short-data-", &m88k_short_data } }  */
-
 /* This is meant to be overridden in target specific files.  */
 #define        SUBTARGET_OPTIONS
 
@@ -444,9 +392,18 @@ extern enum processor_type rs6000_cpu;
    {"tune=", &rs6000_select[2].string,                                 \
     N_("Schedule code for given CPU") },                               \
    {"debug=", &rs6000_debug_name, N_("Enable debug output") },         \
+   {"traceback=", &rs6000_traceback_name,                              \
+    N_("Select full, part, or no traceback table") },                  \
    {"abi=", &rs6000_abi_string, N_("Specify ABI to use") },            \
    {"long-double-", &rs6000_long_double_size_string,                   \
     N_("Specify size of long double (64 or 128 bits)") },              \
+   {"isel=", &rs6000_isel_string,                                       \
+    N_("Specify yes/no if isel instructions should be generated") },    \
+   {"vrsave=", &rs6000_altivec_vrsave_string,                         \
+    N_("Specify yes/no if VRSAVE instructions should be generated for AltiVec") }, \
+   {"longcall", &rs6000_longcall_switch,                               \
+    N_("Avoid all range limits on call instructions") },               \
+   {"no-longcall", &rs6000_longcall_switch, "" },                      \
    SUBTARGET_OPTIONS                                                   \
 }
 
@@ -470,14 +427,30 @@ extern int rs6000_debug_arg;              /* debug argument handling */
 #define        TARGET_DEBUG_STACK      rs6000_debug_stack
 #define        TARGET_DEBUG_ARG        rs6000_debug_arg
 
+extern const char *rs6000_traceback_name; /* Type of traceback table.  */
+
 /* These are separate from target_flags because we've run out of bits
    there.  */
 extern const char *rs6000_long_double_size_string;
 extern int rs6000_long_double_type_size;
 extern int rs6000_altivec_abi;
+extern int rs6000_spe_abi;
+extern int rs6000_isel;
+extern int rs6000_fprs;
+extern const char *rs6000_isel_string;
+extern const char *rs6000_altivec_vrsave_string;
+extern int rs6000_altivec_vrsave;
+extern const char *rs6000_longcall_switch;
+extern int rs6000_default_long_calls;
 
 #define TARGET_LONG_DOUBLE_128 (rs6000_long_double_type_size == 128)
 #define TARGET_ALTIVEC_ABI rs6000_altivec_abi
+#define TARGET_ALTIVEC_VRSAVE rs6000_altivec_vrsave
+
+#define TARGET_SPE_ABI 0
+#define TARGET_SPE 0
+#define TARGET_ISEL 0
+#define TARGET_FPRS 1
 
 /* Sometimes certain combinations of command options do not make sense
    on a particular target machine.  You can define a macro
@@ -497,11 +470,17 @@ extern int rs6000_altivec_abi;
 
 /* Show we can debug even without a frame pointer.  */
 #define CAN_DEBUG_WITHOUT_FP
-\f
-/* target machine storage layout */
 
-/* Define to support cross compilation to an RS6000 target.  */
-#define REAL_ARITHMETIC
+/* Target pragma.  */
+#define REGISTER_TARGET_PRAGMAS(PFILE) do { \
+  cpp_register_pragma (PFILE, 0, "longcall", rs6000_pragma_longcall); \
+} while (0)
+
+/* Target #defines.  */
+#define TARGET_CPU_CPP_BUILTINS() \
+  rs6000_cpu_cpp_builtins (pfile)
+\f
+/* Target machine storage layout.  */
 
 /* Define this macro if it is advisable to hold scalars in registers
    in a wider mode than that declared by the program.  In such cases,
@@ -539,14 +518,6 @@ extern int rs6000_altivec_abi;
    instructions for them.  Might as well be consistent with bits and bytes.  */
 #define WORDS_BIG_ENDIAN 1
 
-/* number of bits in an addressable storage unit */
-#define BITS_PER_UNIT 8
-
-/* Width in bits of a "word", which is the contents of a machine register.
-   Note that this is not necessarily the width of data type `int';
-   if using 16-bit ints on a 68000, this would still be 32.
-   But on a machine with 16-bit registers, this would be 16.  */
-#define BITS_PER_WORD (! TARGET_POWERPC64 ? 32 : 64)
 #define MAX_BITS_PER_WORD 64
 
 /* Width of a word, in units (bytes).  */
@@ -554,6 +525,7 @@ extern int rs6000_altivec_abi;
 #define MIN_UNITS_PER_WORD 4
 #define UNITS_PER_FP_WORD 8
 #define UNITS_PER_ALTIVEC_WORD 16
+#define UNITS_PER_SPE_WORD 8
 
 /* Type used for ptrdiff_t, as a string used in a declaration.  */
 #define PTRDIFF_TYPE "int"
@@ -589,12 +561,6 @@ extern int rs6000_altivec_abi;
    words.  */
 #define LONG_LONG_TYPE_SIZE 64
 
-/* A C expression for the size in bits of the type `char' on the
-   target machine.  If you don't define this, the default is one
-   quarter of a word.  (If this would be less than one storage unit,
-   it is rounded up to one unit.)  */
-#define CHAR_TYPE_SIZE BITS_PER_UNIT
-
 /* A C expression for the size in bits of the type `float' on the
    target machine.  If you don't define this, the default is one
    word.  */
@@ -641,10 +607,8 @@ extern int rs6000_altivec_abi;
    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
+  ((TARGET_ALTIVEC && TREE_CODE (TYPE) == VECTOR_TYPE) ? 128 : \
+    (TARGET_SPE && TREE_CODE (TYPE) == VECTOR_TYPE) ? 64 : ALIGN)
 
 /* Alignment of field after `int : 0' in a structure.  */
 #define EMPTY_FIELD_BOUNDARY 32
@@ -652,18 +616,33 @@ extern int rs6000_altivec_abi;
 /* Every structure's size must be a multiple of this.  */
 #define STRUCTURE_SIZE_BOUNDARY 8
 
+/* Return 1 if a structure or array containing FIELD should be
+   accessed using `BLKMODE'.
+
+   For the SPE, simd types are V2SI, and gcc can be tempted to put the
+   entire thing in a DI and use subregs to access the internals.
+   store_bit_field() will force (subreg:DI (reg:V2SI x))'s to the
+   back-end.  Because a single GPR can hold a V2SI, but not a DI, the
+   best thing to do is set structs to BLKmode and avoid Severe Tire
+   Damage.  */
+#define MEMBER_TYPE_FORCES_BLK(FIELD, MODE) \
+  (TARGET_SPE && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE)
+
 /* A bitfield declared as `int' forces `int' alignment for the struct.  */
 #define PCC_BITFIELD_TYPE_MATTERS 1
 
-/* 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 strings word-aligned so strcpy from constants will be faster.
+   Make vector constants quadword aligned.  */
+#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.
    Align vectors to 128 bits.  */
 #define DATA_ALIGNMENT(TYPE, ALIGN)            \
-  (TREE_CODE (TYPE) == VECTOR_TYPE ? 128       \
+  (TREE_CODE (TYPE) == VECTOR_TYPE ? (TARGET_SPE_ABI ? 64 : 128)       \
    : TREE_CODE (TYPE) == ARRAY_TYPE            \
    && TYPE_MODE (TREE_TYPE (TYPE)) == QImode   \
    && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
@@ -702,7 +681,7 @@ extern int rs6000_altivec_abi;
    a register, in order to work around problems in allocating stack storage
    in inline functions.  */
 
-#define FIRST_PSEUDO_REGISTER 110
+#define FIRST_PSEUDO_REGISTER 113
 
 /* This must be included for pre gcc 3.0 glibc compatibility.  */
 #define PRE_GCC3_DWARF_FRAME_REGISTERS 77
@@ -726,7 +705,8 @@ extern int rs6000_altivec_abi;
    /* 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, \
-   1                                              \
+   1, 1                                                   \
+   , 1, 1                                          \
 }
 
 /* 1 for registers not available across function calls.
@@ -745,7 +725,8 @@ extern int rs6000_altivec_abi;
    /* 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, \
-   1                                              \
+   1, 1                                                   \
+   , 1, 1                                          \
 }
 
 /* Like `CALL_USED_REGISTERS' except this macro doesn't require that
@@ -763,7 +744,8 @@ extern int rs6000_altivec_abi;
    /* 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                                              \
+   0, 0                                                   \
+   , 0, 0                                          \
 }
 
 #define MQ_REGNO     64
@@ -776,8 +758,11 @@ extern int rs6000_altivec_abi;
 #define XER_REGNO    76
 #define FIRST_ALTIVEC_REGNO    77
 #define LAST_ALTIVEC_REGNO     108
-#define TOTAL_ALTIVEC_REGS     (LAST_ALTIVEC_REGNO - FIRST_ALTIVEC_REGNO)
+#define TOTAL_ALTIVEC_REGS     (LAST_ALTIVEC_REGNO - FIRST_ALTIVEC_REGNO + 1)
 #define VRSAVE_REGNO           109
+#define VSCR_REGNO             110
+#define SPE_ACC_REGNO          111
+#define SPEFSCR_REGNO          112
 
 /* List the order in which to allocate registers.  Each register must be
    listed once, even those in FIXED_REGISTERS.
@@ -800,7 +785,8 @@ extern int rs6000_altivec_abi;
        mq              (not saved; best to use it if we can)
        ctr             (not saved; when we have the choice ctr is better)
        lr              (saved)
-        cr5, r1, r2, ap, xer, vrsave (fixed)
+        cr5, r1, r2, ap, xer, vrsave, vscr (fixed)
+       spe_acc, spefscr (fixed)
 
        AltiVec registers:
        v0 - v1         (not saved or used for anything)
@@ -831,7 +817,8 @@ extern int rs6000_altivec_abi;
    79,                                                 \
    96, 95, 94, 93, 92, 91,                             \
    108, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98,        \
-   97, 109                                             \
+   97, 109, 110                                                \
+   , 111, 112                                              \
 }
 
 /* True if register is floating-point.  */
@@ -846,6 +833,9 @@ extern int rs6000_altivec_abi;
 /* True if register is an integer register.  */
 #define INT_REGNO_P(N) ((N) <= 31 || (N) == ARG_POINTER_REGNUM)
 
+/* SPE SIMD registers are just the GPRs.  */
+#define SPE_SIMD_REGNO_P(N) ((N) <= 31)
+
 /* True if register is the XER register.  */
 #define XER_REGNO_P(N) ((N) == XER_REGNO)
 
@@ -857,28 +847,40 @@ extern int rs6000_altivec_abi;
    This is ordinarily the length in words of a value of mode MODE
    but can be less for certain modes in special long registers.
 
+   For the SPE, GPRs are 64 bits but only 32 bits are visible in
+   scalar instructions.  The upper 32 bits are only available to the
+   SIMD instructions.
+
    POWER and PowerPC GPRs hold 32 bits worth;
    PowerPC64 GPRs and FPRs point register holds 64 bits worth.  */
 
 #define HARD_REGNO_NREGS(REGNO, MODE)                                  \
   (FP_REGNO_P (REGNO)                                                  \
    ? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \
+   : (SPE_SIMD_REGNO_P (REGNO) && TARGET_SPE && SPE_VECTOR_MODE (MODE))   \
+   ? ((GET_MODE_SIZE (MODE) + UNITS_PER_SPE_WORD - 1) / UNITS_PER_SPE_WORD) \
    : ALTIVEC_REGNO_P (REGNO)                                           \
    ? ((GET_MODE_SIZE (MODE) + UNITS_PER_ALTIVEC_WORD - 1) / UNITS_PER_ALTIVEC_WORD) \
    : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
 
 #define ALTIVEC_VECTOR_MODE(MODE)      \
-       ((MODE) == V16QImode            \
-        || (MODE) == V8HImode          \
-        || (MODE) == V4SFmode          \
-        || (MODE) == V4SImode)
+        ((MODE) == V16QImode           \
+         || (MODE) == V8HImode         \
+         || (MODE) == V4SFmode         \
+         || (MODE) == V4SImode)
+
+#define SPE_VECTOR_MODE(MODE)          \
+       ((MODE) == V4HImode             \
+         || (MODE) == V2SFmode          \
+         || (MODE) == V2SImode)
 
 /* Define this macro to be nonzero if the port is prepared to handle
    insns involving vector mode MODE.  At the very least, it must have
    move patterns for this mode.  */
 
-#define VECTOR_MODE_SUPPORTED_P(MODE)  \
-       (TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (MODE))
+#define VECTOR_MODE_SUPPORTED_P(MODE)                  \
+        ((TARGET_SPE && SPE_VECTOR_MODE (MODE))                \
+        || (TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (MODE)))
 
 /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
    For POWER and PowerPC, the GPRs can hold any mode, but the float
@@ -892,6 +894,7 @@ extern int rs6000_altivec_abi;
     || (GET_MODE_CLASS (MODE) == MODE_INT                              \
        && GET_MODE_SIZE (MODE) == UNITS_PER_FP_WORD))                  \
    : ALTIVEC_REGNO_P (REGNO) ? ALTIVEC_VECTOR_MODE (MODE)              \
+   : SPE_SIMD_REGNO_P (REGNO) && TARGET_SPE && SPE_VECTOR_MODE (MODE) ? 1 \
    : CR_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_CC             \
    : XER_REGNO_P (REGNO) ? (MODE) == PSImode                           \
    : ! INT_REGNO_P (REGNO) ? (GET_MODE_CLASS (MODE) == MODE_INT                \
@@ -956,6 +959,20 @@ extern int rs6000_altivec_abi;
 
 #define BRANCH_COST 3
 
+
+/* A fixed register used at prologue and epilogue generation to fix
+   addressing modes.  The SPE needs heavy addressing fixes at the last
+   minute, and it's best to save a register for it.
+
+   AltiVec also needs fixes, but we've gotten around using r11, which
+   is actually wrong because when use_backchain_to_restore_sp is true,
+   we end up clobbering r11.
+
+   The AltiVec case needs to be fixed.  Dunno if we should break ABI
+   compatability and reserve a register for it as well..  */
+
+#define FIXED_SCRATCH (TARGET_SPE ? 14 : 11)
+
 /* Define this macro to change register usage conditional on target flags.
    Set MQ register fixed (already call_used) if not POWER architecture
    (RIOS1, RIOS2, RSC, and PPC601) so that it will not be allocated.
@@ -970,22 +987,37 @@ extern int rs6000_altivec_abi;
   if (TARGET_64BIT)                                                    \
     fixed_regs[13] = call_used_regs[13]                                        \
       = call_really_used_regs[13] = 1;                                         \
-  if (TARGET_SOFT_FLOAT)                                               \
+  if (TARGET_SOFT_FLOAT || !TARGET_FPRS)                               \
     for (i = 32; i < 64; i++)                                          \
       fixed_regs[i] = call_used_regs[i]                                        \
         = call_really_used_regs[i] = 1;                                        \
-  if (DEFAULT_ABI == ABI_V4 && flag_pic == 1)                          \
-    fixed_regs[PIC_OFFSET_TABLE_REGNUM]                                        \
-      = call_used_regs[PIC_OFFSET_TABLE_REGNUM]                                \
-      = call_really_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]                                \
-      = call_really_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;            \
+  if (DEFAULT_ABI == ABI_V4                                            \
+      && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM                     \
+      && flag_pic == 1)                                                        \
+    fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]                         \
+      = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]                 \
+      = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;     \
+  if (DEFAULT_ABI == ABI_DARWIN                                                \
+      && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)                    \
+    global_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]                                \
+      = fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]                     \
+      = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]                 \
+      = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;     \
+  if (TARGET_ALTIVEC)                                                   \
+    global_regs[VSCR_REGNO] = 1;                                        \
+  if (TARGET_SPE)                                                      \
+    {                                                                   \
+      global_regs[SPEFSCR_REGNO] = 1;                                  \
+      fixed_regs[FIXED_SCRATCH]                                                \
+        = call_used_regs[FIXED_SCRATCH]                                        \
+       = call_really_used_regs[FIXED_SCRATCH] = 1;                     \
+    }                                                                   \
   if (! TARGET_ALTIVEC)                                                        \
-    for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)                \
-      fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;        \
+    {                                                                  \
+      for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)      \
+       fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1; \
+      call_really_used_regs[VRSAVE_REGNO] = 1;                         \
+    }                                                                  \
   if (TARGET_ALTIVEC_ABI)                                              \
     for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)   \
       call_used_regs[i] = call_really_used_regs[i] = 1;                        \
@@ -1064,6 +1096,9 @@ enum reg_class
   FLOAT_REGS,
   ALTIVEC_REGS,
   VRSAVE_REGS,
+  VSCR_REGS,
+  SPE_ACC_REGS,
+  SPEFSCR_REGS,
   NON_SPECIAL_REGS,
   MQ_REGS,
   LINK_REGS,
@@ -1091,6 +1126,9 @@ enum reg_class
   "FLOAT_REGS",                                                                \
   "ALTIVEC_REGS",                                                      \
   "VRSAVE_REGS",                                                       \
+  "VSCR_REGS",                                                         \
+  "SPE_ACC_REGS",                                                       \
+  "SPEFSCR_REGS",                                                       \
   "NON_SPECIAL_REGS",                                                  \
   "MQ_REGS",                                                           \
   "LINK_REGS",                                                         \
@@ -1117,6 +1155,9 @@ enum reg_class
   { 0x00000000, 0xffffffff, 0x00000000, 0x00000000 }, /* FLOAT_REGS */       \
   { 0x00000000, 0x00000000, 0xffffe000, 0x00001fff }, /* ALTIVEC_REGS */     \
   { 0x00000000, 0x00000000, 0x00000000, 0x00002000 }, /* VRSAVE_REGS */             \
+  { 0x00000000, 0x00000000, 0x00000000, 0x00004000 }, /* VSCR_REGS */       \
+  { 0x00000000, 0x00000000, 0x00000000, 0x00008000 }, /* SPE_ACC_REGS */     \
+  { 0x00000000, 0x00000000, 0x00000000, 0x00010000 }, /* SPEFSCR_REGS */     \
   { 0xffffffff, 0xffffffff, 0x00000008, 0x00000000 }, /* NON_SPECIAL_REGS */ \
   { 0x00000000, 0x00000000, 0x00000001, 0x00000000 }, /* MQ_REGS */         \
   { 0x00000000, 0x00000000, 0x00000002, 0x00000000 }, /* LINK_REGS */       \
@@ -1149,6 +1190,9 @@ enum reg_class
   : (REGNO) == ARG_POINTER_REGNUM ? BASE_REGS  \
   : (REGNO) == XER_REGNO ? XER_REGS            \
   : (REGNO) == VRSAVE_REGNO ? VRSAVE_REGS      \
+  : (REGNO) == VSCR_REGNO ? VRSAVE_REGS        \
+  : (REGNO) == SPE_ACC_REGNO ? SPE_ACC_REGS    \
+  : (REGNO) == SPEFSCR_REGNO ? SPEFSCR_REGS    \
   : NO_REGS)
 
 /* The class value for index registers, and the one for base regs.  */
@@ -1216,16 +1260,21 @@ enum reg_class
    'Q' means that is a memory operand that is just an offset from a reg.
    'R' is for AIX TOC entries.
    'S' is a constant that can be placed into a 64-bit mask operand
-   'T' is a consatnt that can be placed into a 32-bit mask operand
-   'U' is for V.4 small data references.  */
+   'T' is a constant that can be placed into a 32-bit mask operand
+   'U' is for V.4 small data references.
+   't' is for AND masks that can be performed by two rldic{l,r} insns.  */
 
 #define EXTRA_CONSTRAINT(OP, C)                                                \
   ((C) == 'Q' ? GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == REG \
    : (C) == 'R' ? LEGITIMATE_CONSTANT_POOL_ADDRESS_P (OP)              \
-   : (C) == 'S' ? mask64_operand (OP, VOIDmode)                                \
-   : (C) == 'T' ? mask_operand (OP, VOIDmode)                          \
+   : (C) == 'S' ? mask64_operand (OP, DImode)                          \
+   : (C) == 'T' ? mask_operand (OP, SImode)                            \
    : (C) == 'U' ? (DEFAULT_ABI == ABI_V4                               \
                   && small_data_operand (OP, GET_MODE (OP)))           \
+   : (C) == 't' ? (mask64_2_operand (OP, DImode)                       \
+                  && (fixed_regs[CR0_REGNO]                            \
+                      || !logical_operand (OP, DImode))                \
+                  && !mask64_operand (OP, DImode))                     \
    : 0)
 
 /* Given an rtx X being reloaded into a reg required to be
@@ -1323,6 +1372,7 @@ typedef struct rs6000_stack {
   int lr_save_offset;          /* offset to save LR from initial SP */
   int cr_save_offset;          /* offset to save CR from initial SP */
   int vrsave_save_offset;      /* offset to save VRSAVE from initial SP */
+  int spe_gp_save_offset;      /* offset to save spe 64-bit gprs  */
   int toc_save_offset;         /* offset to save the TOC pointer */
   int varargs_save_offset;     /* offset to save the varargs registers */
   int ehrd_offset;             /* offset to EH return data */
@@ -1340,6 +1390,8 @@ typedef struct rs6000_stack {
   int vrsave_size;             /* size to hold VRSAVE if not in save_size */
   int altivec_padding_size;    /* size of altivec alignment padding if
                                   not in save_size */
+  int spe_gp_size;             /* size of 64-bit GPR save size for SPE */
+  int spe_padding_size;
   int toc_size;                        /* size to hold TOC if not in save_size */
   int total_size;              /* total bytes allocated for stack */
 } rs6000_stack_t;
@@ -1458,6 +1510,8 @@ typedef struct rs6000_stack {
    If the precise function being called is known, FUNC is its FUNCTION_DECL;
    otherwise, FUNC is 0.
 
+   On the SPE, both FPs and vectors are returned in r3.
+
    On RS/6000 an integer value is in r3 and a floating-point value is in
    fp1, unless -msoft-float.  */
 
@@ -1466,8 +1520,13 @@ typedef struct rs6000_stack {
                && TYPE_PRECISION (VALTYPE) < BITS_PER_WORD)    \
               || POINTER_TYPE_P (VALTYPE)                      \
               ? word_mode : TYPE_MODE (VALTYPE),               \
-              TREE_CODE (VALTYPE) == VECTOR_TYPE ? ALTIVEC_ARG_RETURN \
-              : TREE_CODE (VALTYPE) == REAL_TYPE && TARGET_HARD_FLOAT \
+              TREE_CODE (VALTYPE) == VECTOR_TYPE               \
+              && TARGET_ALTIVEC ? ALTIVEC_ARG_RETURN           \
+              : TREE_CODE (VALTYPE) == REAL_TYPE               \
+                && TARGET_SPE_ABI && !TARGET_FPRS              \
+              ? GP_ARG_RETURN                                  \
+              : TREE_CODE (VALTYPE) == REAL_TYPE               \
+                && TARGET_HARD_FLOAT && TARGET_FPRS            \
                ? FP_ARG_RETURN : GP_ARG_RETURN)
 
 /* Define how to find the value returned by a library function
@@ -1476,7 +1535,7 @@ typedef struct rs6000_stack {
 #define LIBCALL_VALUE(MODE)                                            \
   gen_rtx_REG (MODE, ALTIVEC_VECTOR_MODE (MODE) ? ALTIVEC_ARG_RETURN   \
                     : GET_MODE_CLASS (MODE) == MODE_FLOAT              \
-                    && TARGET_HARD_FLOAT                               \
+                    && TARGET_HARD_FLOAT && TARGET_FPRS                \
                     ? FP_ARG_RETURN : GP_ARG_RETURN)
 
 /* The AIX ABI for the RS/6000 specifies that all structures are
@@ -1495,7 +1554,7 @@ typedef struct rs6000_stack {
 #define RETURN_IN_MEMORY(TYPE) \
   (AGGREGATE_TYPE_P (TYPE) && \
    (TARGET_AIX_STRUCT_RET || \
-    (unsigned HOST_WIDEST_INT) int_size_in_bytes (TYPE) > 8))
+    (unsigned HOST_WIDE_INT) int_size_in_bytes (TYPE) > 8))
 
 /* DRAFT_V4_STRUCT_RET defaults off.  */
 #define DRAFT_V4_STRUCT_RET 0
@@ -1556,7 +1615,7 @@ typedef struct rs6000_stack {
    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_NUM_REG)) \
    || ((unsigned)((N) - FP_ARG_MIN_REG) < (unsigned)(FP_ARG_NUM_REG)))
@@ -1564,7 +1623,7 @@ typedef struct rs6000_stack {
 \f
 /* A C structure for machine-specific, per-function data.
    This is added to the cfun structure.  */
-typedef struct machine_function
+typedef struct machine_function GTY(())
 {
   /* Whether a System V.4 varargs area was created.  */
   int sysv_varargs_p;
@@ -1608,8 +1667,7 @@ typedef struct rs6000_args
 #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)
+ : (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.
@@ -1635,7 +1693,7 @@ typedef struct rs6000_args
 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
   (GET_MODE_CLASS (MODE) == MODE_FLOAT  \
    && (CUM).fregno <= FP_ARG_MAX_REG    \
-   && TARGET_HARD_FLOAT)
+   && TARGET_HARD_FLOAT && TARGET_FPRS)
 
 /* Non-zero if we can use an AltiVec register to pass this arg.  */
 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE)   \
@@ -1721,17 +1779,29 @@ typedef struct rs6000_args
   (VALIST) = rs6000_build_va_list ()
 
 /* Implement `va_start' for varargs and stdarg.  */
-#define EXPAND_BUILTIN_VA_START(stdarg, valist, nextarg) \
-  rs6000_va_start (stdarg, valist, nextarg)
+#define EXPAND_BUILTIN_VA_START(valist, nextarg) \
+  rs6000_va_start (valist, nextarg)
 
 /* Implement `va_arg'.  */
 #define EXPAND_BUILTIN_VA_ARG(valist, type) \
   rs6000_va_arg (valist, type)
 
+/* For AIX, the rule is that structures are passed left-aligned in
+   their stack slot.  However, GCC does not presently do this:
+   structures which are the same size as integer types are passed
+   right-aligned, as if they were in fact integers.  This only
+   matters for structures of size 1 or 2, or 4 when TARGET_64BIT.
+   ABI_V4 does not use std_expand_builtin_va_arg.  */
+#define PAD_VARARGS_DOWN (TYPE_MODE (type) != BLKmode)
+
 /* 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
 
+/* We do not allow indirect calls to be optimized into sibling calls, nor
+   do we allow calls with vector parameters.  */
+#define FUNCTION_OK_FOR_SIBCALL(DECL) function_ok_for_sibcall ((DECL))
+
 /* Output assembler code to FILE to increment profiler label # LABELNO
    for profiling a function entry.  */
 
@@ -1753,7 +1823,7 @@ typedef struct rs6000_args
 
 #define        EPILOGUE_USES(REGNO)                                    \
   ((reload_completed && (REGNO) == LINK_REGISTER_REGNUM)       \
-   || (REGNO) == VRSAVE_REGNO                                  \
+   || (TARGET_ALTIVEC && (REGNO) == VRSAVE_REGNO)              \
    || (current_function_calls_eh_return                                \
        && TARGET_AIX                                           \
        && (REGNO) == TOC_REGISTER))
@@ -1963,6 +2033,9 @@ typedef struct rs6000_args
 
 #define TOC_RELATIVE_EXPR_P(X) (toc_relative_expr_p (X))
 
+/* SPE offset addressing is limited to 5-bits worth of double words.  */
+#define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
+
 #define LEGITIMATE_CONSTANT_POOL_ADDRESS_P(X)                          \
   (TARGET_TOC                                                          \
   && GET_CODE (X) == PLUS                                              \
@@ -1985,7 +2058,11 @@ typedef struct rs6000_args
   && 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)         \
+  && (! ALTIVEC_VECTOR_MODE (MODE)                            \
+      || (GET_CODE (XEXP (X,1)) == CONST_INT && INTVAL (XEXP (X,1)) == 0)) \
+  && (! SPE_VECTOR_MODE (MODE)                                 \
+      || (GET_CODE (XEXP (X, 1)) == CONST_INT                  \
+         && SPE_CONST_OFFSET_OK (INTVAL (XEXP (X, 1)))))       \
   && (((MODE) != DFmode && (MODE) != DImode)                   \
       || (TARGET_32BIT                                         \
          ? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 4)       \
@@ -2013,7 +2090,7 @@ typedef struct rs6000_args
    && ! flag_pic && ! TARGET_TOC                       \
    && GET_MODE_NUNITS (MODE) == 1                      \
    && (GET_MODE_BITSIZE (MODE) <= 32                   \
-       || (TARGET_HARD_FLOAT && (MODE) == DFmode))     \
+       || (TARGET_HARD_FLOAT && TARGET_FPRS && (MODE) == DFmode))      \
    && GET_CODE (X) == LO_SUM                           \
    && GET_CODE (XEXP (X, 0)) == REG                    \
    && INT_REG_OK_FOR_BASE_P (XEXP (X, 0), (STRICT))    \
@@ -2103,7 +2180,8 @@ do {                                                                           \
    this macro is not defined, it is up to the machine-dependent files
    to allocate such a register (if necessary).  */
 
-#define PIC_OFFSET_TABLE_REGNUM 30
+#define RS6000_PIC_OFFSET_TABLE_REGNUM 30
+#define PIC_OFFSET_TABLE_REGNUM (flag_pic ? RS6000_PIC_OFFSET_TABLE_REGNUM : INVALID_REGNUM)
 
 #define TOC_REGISTER (TARGET_MINIMAL_TOC ? 30 : 2)
 
@@ -2163,12 +2241,6 @@ do {                                                                          \
    Do not define this if the table should contain absolute addresses.  */
 #define CASE_VECTOR_PC_RELATIVE 1
 
-/* Specify the tree operation to be used to convert reals to integers.  */
-#define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR
-
-/* This is the kind of divide that is easiest to do in the general case.  */
-#define EASY_DIV_EXPR TRUNC_DIV_EXPR
-
 /* Define this as 1 if `char' should by default be signed; else as 0.  */
 #define DEFAULT_SIGNED_CHAR 0
 
@@ -2264,6 +2336,8 @@ do {                                                                           \
            ? COSTS_N_INSNS (2)                                         \
            : COSTS_N_INSNS (1));                                       \
   case MULT:                                                           \
+    if (optimize_size)                                                 \
+      return COSTS_N_INSNS (2);                                                \
     switch (rs6000_cpu)                                                        \
       {                                                                        \
       case PROCESSOR_RIOS1:                                            \
@@ -2297,9 +2371,11 @@ do {                                                                          \
                : COSTS_N_INSNS (3));                                   \
       case PROCESSOR_PPC403:                                           \
       case PROCESSOR_PPC604:                                           \
+      case PROCESSOR_PPC8540:                                          \
         return COSTS_N_INSNS (4);                                      \
       case PROCESSOR_PPC620:                                           \
       case PROCESSOR_PPC630:                                           \
+      case PROCESSOR_POWER4:                                           \
         return (GET_CODE (XEXP (X, 1)) != CONST_INT                    \
                ? GET_MODE (XEXP (X, 1)) != DImode                      \
                ? COSTS_N_INSNS (5) : COSTS_N_INSNS (7)                 \
@@ -2339,10 +2415,12 @@ do {                                                                         \
        return COSTS_N_INSNS (20);                                      \
       case PROCESSOR_PPC620:                                           \
       case PROCESSOR_PPC630:                                           \
+      case PROCESSOR_POWER4:                                           \
         return (GET_MODE (XEXP (X, 1)) != DImode                       \
                ? COSTS_N_INSNS (21)                                    \
                : COSTS_N_INSNS (37));                                  \
       case PROCESSOR_PPC750:                                           \
+      case PROCESSOR_PPC8540:                                          \
       case PROCESSOR_PPC7400:                                          \
         return COSTS_N_INSNS (19);                                     \
       case PROCESSOR_PPC7450:                                          \
@@ -2373,18 +2451,6 @@ do {                                                                          \
 
 /* #define ADJUST_INSN_LENGTH(X,LENGTH) */
 
-/* Add any extra modes needed to represent the condition code.
-
-   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, 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
@@ -2402,7 +2468,8 @@ do {                                                                           \
    stored from the compare operation.  Note that we can't use "rtx" here
    since it hasn't been defined!  */
 
-extern struct rtx_def *rs6000_compare_op0, *rs6000_compare_op1;
+extern GTY(()) rtx rs6000_compare_op0;
+extern GTY(()) rtx rs6000_compare_op1;
 extern int rs6000_compare_fp_p;
 \f
 /* Control the assembler format that we output.  */
@@ -2438,43 +2505,73 @@ extern int toc_initialized;
 #define RS6000_WEAK 0
 #endif
 
-/* 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 (decl))                          \
-       {                                               \
-         if (RS6000_WEAK && DECL_WEAK (decl))          \
-           {                                           \
-             fputs ("\t.weak .", FILE);                \
-             assemble_name (FILE, alias);              \
-             putc ('\n', FILE);                        \
-           }                                           \
-         else                                          \
-           {                                           \
-             fputs ("\t.globl .", FILE);               \
-             assemble_name (FILE, alias);              \
-             putc ('\n', FILE);                        \
-           }                                           \
-       }                                               \
-      else                                             \
-       {                                               \
-         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);                              \
-    }                                                  \
-  ASM_OUTPUT_DEF (FILE, alias, name);                  \
-} while (0)
+#if RS6000_WEAK
+/* Used in lieu of ASM_WEAKEN_LABEL.  */
+#define        ASM_WEAKEN_DECL(FILE, DECL, NAME, VAL)                          \
+  do                                                                   \
+    {                                                                  \
+      fputs ("\t.weak\t", (FILE));                                     \
+      RS6000_OUTPUT_BASENAME ((FILE), (NAME));                         \
+      if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL                  \
+         && DEFAULT_ABI == ABI_AIX)                                    \
+       {                                                               \
+         if (TARGET_XCOFF)                                             \
+           fputs ("[DS]", (FILE));                                     \
+         fputs ("\n\t.weak\t.", (FILE));                               \
+         RS6000_OUTPUT_BASENAME ((FILE), (NAME));                      \
+       }                                                               \
+      fputc ('\n', (FILE));                                            \
+      if (VAL)                                                         \
+       {                                                               \
+         ASM_OUTPUT_DEF ((FILE), (NAME), (VAL));                       \
+         if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL               \
+             && DEFAULT_ABI == ABI_AIX)                                \
+           {                                                           \
+             fputs ("\t.set\t.", (FILE));                              \
+             RS6000_OUTPUT_BASENAME ((FILE), (NAME));                  \
+             fputs (",.", (FILE));                                     \
+             RS6000_OUTPUT_BASENAME ((FILE), (VAL));                   \
+             fputc ('\n', (FILE));                                     \
+           }                                                           \
+       }                                                               \
+    }                                                                  \
+  while (0)
+#endif
+
+/* This implements the `alias' attribute.  */
+#undef ASM_OUTPUT_DEF_FROM_DECLS
+#define        ASM_OUTPUT_DEF_FROM_DECLS(FILE, DECL, TARGET)                   \
+  do                                                                   \
+    {                                                                  \
+      const char *alias = XSTR (XEXP (DECL_RTL (DECL), 0), 0);         \
+      const char *name = IDENTIFIER_POINTER (TARGET);                  \
+      if (TREE_CODE (DECL) == FUNCTION_DECL                            \
+         && DEFAULT_ABI == ABI_AIX)                                    \
+       {                                                               \
+         if (TREE_PUBLIC (DECL))                                       \
+           {                                                           \
+             if (!RS6000_WEAK || !DECL_WEAK (DECL))                    \
+               {                                                       \
+                 fputs ("\t.globl\t.", FILE);                          \
+                 RS6000_OUTPUT_BASENAME (FILE, alias);                 \
+                 putc ('\n', FILE);                                    \
+               }                                                       \
+           }                                                           \
+         else if (TARGET_XCOFF)                                        \
+           {                                                           \
+             fputs ("\t.lglobl\t.", FILE);                             \
+             RS6000_OUTPUT_BASENAME (FILE, alias);                     \
+             putc ('\n', FILE);                                        \
+           }                                                           \
+         fputs ("\t.set\t.", FILE);                                    \
+         RS6000_OUTPUT_BASENAME (FILE, alias);                         \
+         fputs (",.", FILE);                                           \
+         RS6000_OUTPUT_BASENAME (FILE, name);                          \
+         fputc ('\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.  */
@@ -2608,6 +2705,9 @@ extern char rs6000_reg_names[][8];        /* register names (0 vs. %r0).  */
   &rs6000_reg_names[107][0],   /* v30  */                              \
   &rs6000_reg_names[108][0],   /* v31  */                              \
   &rs6000_reg_names[109][0],   /* vrsave  */                           \
+  &rs6000_reg_names[110][0],   /* vscr  */                             \
+  &rs6000_reg_names[111][0],   /* spe_acc */                           \
+  &rs6000_reg_names[112][0],   /* spefscr */                           \
 }
 
 /* print-rtl can't handle the above REGISTER_NAMES, so define the
@@ -2631,7 +2731,8 @@ extern char rs6000_reg_names[][8];        /* register names (0 vs. %r0).  */
      "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"                                                           \
+    "vrsave", "vscr"                                                   \
+    , "spe_acc", "spefscr"                                              \
 }
 
 /* Table of additional register names to use in user input.  */
@@ -2661,7 +2762,8 @@ extern char rs6000_reg_names[][8];        /* register names (0 vs. %r0).  */
   {"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},                                             \
+  {"vrsave", 109}, {"vscr", 110},                              \
+  {"spe_acc", 111}, {"spefscr", 112},                          \
   /* no additional names for: mq, lr, ctr, ap */               \
   {"cr0",  68}, {"cr1",  69}, {"cr2",  70}, {"cr3",  71},      \
   {"cr4",  72}, {"cr5",  73}, {"cr6",  74}, {"cr7",  75},      \
@@ -2729,6 +2831,10 @@ extern char rs6000_reg_names[][8];       /* register names (0 vs. %r0).  */
 /* Define the codes that are matched by predicates in rs6000.c.  */
 
 #define PREDICATE_CODES                                                           \
+  {"any_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,            \
+                  LABEL_REF, SUBREG, REG, MEM, PARALLEL}},                \
+  {"zero_constant", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,          \
+                   LABEL_REF, SUBREG, REG, MEM}},                         \
   {"short_cint_operand", {CONST_INT}},                                    \
   {"u_short_cint_operand", {CONST_INT}},                                  \
   {"non_short_cint_operand", {CONST_INT}},                                \
@@ -2738,6 +2844,7 @@ extern char rs6000_reg_names[][8];        /* register names (0 vs. %r0).  */
   {"cc_reg_not_cr0_operand", {SUBREG, REG}},                              \
   {"reg_or_short_operand", {SUBREG, REG, CONST_INT}},                     \
   {"reg_or_neg_short_operand", {SUBREG, REG, CONST_INT}},                 \
+  {"reg_or_aligned_short_operand", {SUBREG, REG, CONST_INT}},             \
   {"reg_or_u_short_operand", {SUBREG, REG, CONST_INT}},                           \
   {"reg_or_cint_operand", {SUBREG, REG, CONST_INT}},                      \
   {"reg_or_arith_cint_operand", {SUBREG, REG, CONST_INT}},                \
@@ -2757,12 +2864,16 @@ extern char rs6000_reg_names[][8];      /* register names (0 vs. %r0).  */
   {"non_add_cint_operand", {CONST_INT}},                                  \
   {"and_operand", {SUBREG, REG, CONST_INT}},                              \
   {"and64_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}},              \
+  {"and64_2_operand", {SUBREG, REG, CONST_INT}},                          \
   {"logical_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}},            \
   {"non_logical_cint_operand", {CONST_INT, CONST_DOUBLE}},                \
   {"mask_operand", {CONST_INT}},                                          \
-  {"mask64_operand", {CONST_INT, CONST_DOUBLE}},                          \
+  {"mask_operand_wrap", {CONST_INT}},                                     \
+  {"mask64_operand", {CONST_INT}},                                        \
+  {"mask64_2_operand", {CONST_INT}},                                      \
   {"count_register_operand", {REG}},                                      \
   {"xer_operand", {REG}},                                                 \
+  {"symbol_ref_operand", {SYMBOL_REF}},                                           \
   {"call_operand", {SYMBOL_REF, REG}},                                    \
   {"current_file_function_operand", {SYMBOL_REF}},                        \
   {"input_operand", {SUBREG, MEM, REG, CONST_INT,                         \
@@ -2784,6 +2895,7 @@ extern char rs6000_reg_names[][8];        /* register names (0 vs. %r0).  */
                                GT, LEU, LTU, GEU, GTU}},                  \
   {"boolean_operator", {AND, IOR, XOR}},                                  \
   {"boolean_or_operator", {IOR, XOR}},                                    \
+  {"altivec_register_operand", {REG}},                                    \
   {"min_max_operator", {SMIN, SMAX, UMIN, UMAX}},
 
 /* uncomment for disabling the corresponding default options */
@@ -2961,6 +3073,26 @@ enum rs6000_builtins
   ALTIVEC_BUILTIN_VUPKLSB,
   ALTIVEC_BUILTIN_VUPKLPX,
   ALTIVEC_BUILTIN_VUPKLSH,
+  ALTIVEC_BUILTIN_MTVSCR,
+  ALTIVEC_BUILTIN_MFVSCR,
+  ALTIVEC_BUILTIN_DSSALL,
+  ALTIVEC_BUILTIN_DSS,
+  ALTIVEC_BUILTIN_LVSL,
+  ALTIVEC_BUILTIN_LVSR,
+  ALTIVEC_BUILTIN_DSTT,
+  ALTIVEC_BUILTIN_DSTST,
+  ALTIVEC_BUILTIN_DSTSTT,
+  ALTIVEC_BUILTIN_DST,
+  ALTIVEC_BUILTIN_LVEBX,
+  ALTIVEC_BUILTIN_LVEHX,
+  ALTIVEC_BUILTIN_LVEWX,
+  ALTIVEC_BUILTIN_LVXL,
+  ALTIVEC_BUILTIN_LVX,
+  ALTIVEC_BUILTIN_STVX,
+  ALTIVEC_BUILTIN_STVEBX,
+  ALTIVEC_BUILTIN_STVEHX,
+  ALTIVEC_BUILTIN_STVEWX,
+  ALTIVEC_BUILTIN_STVXL,
   ALTIVEC_BUILTIN_VCMPBFP_P,
   ALTIVEC_BUILTIN_VCMPEQFP_P,
   ALTIVEC_BUILTIN_VCMPEQUB_P,
@@ -2973,5 +3105,254 @@ enum rs6000_builtins
   ALTIVEC_BUILTIN_VCMPGTSW_P,
   ALTIVEC_BUILTIN_VCMPGTUB_P,
   ALTIVEC_BUILTIN_VCMPGTUH_P,
-  ALTIVEC_BUILTIN_VCMPGTUW_P
+  ALTIVEC_BUILTIN_VCMPGTUW_P,
+  ALTIVEC_BUILTIN_ABSS_V4SI,
+  ALTIVEC_BUILTIN_ABSS_V8HI,
+  ALTIVEC_BUILTIN_ABSS_V16QI,
+  ALTIVEC_BUILTIN_ABS_V4SI,
+  ALTIVEC_BUILTIN_ABS_V4SF,
+  ALTIVEC_BUILTIN_ABS_V8HI,
+  ALTIVEC_BUILTIN_ABS_V16QI
+  /* SPE builtins.  */
+  , SPE_BUILTIN_EVADDW,
+  SPE_BUILTIN_EVAND,
+  SPE_BUILTIN_EVANDC,
+  SPE_BUILTIN_EVDIVWS,
+  SPE_BUILTIN_EVDIVWU,
+  SPE_BUILTIN_EVEQV,
+  SPE_BUILTIN_EVFSADD,
+  SPE_BUILTIN_EVFSDIV,
+  SPE_BUILTIN_EVFSMUL,
+  SPE_BUILTIN_EVFSSUB,
+  SPE_BUILTIN_EVLDDX,
+  SPE_BUILTIN_EVLDHX,
+  SPE_BUILTIN_EVLDWX,
+  SPE_BUILTIN_EVLHHESPLATX,
+  SPE_BUILTIN_EVLHHOSSPLATX,
+  SPE_BUILTIN_EVLHHOUSPLATX,
+  SPE_BUILTIN_EVLWHEX,
+  SPE_BUILTIN_EVLWHOSX,
+  SPE_BUILTIN_EVLWHOUX,
+  SPE_BUILTIN_EVLWHSPLATX,
+  SPE_BUILTIN_EVLWWSPLATX,
+  SPE_BUILTIN_EVMERGEHI,
+  SPE_BUILTIN_EVMERGEHILO,
+  SPE_BUILTIN_EVMERGELO,
+  SPE_BUILTIN_EVMERGELOHI,
+  SPE_BUILTIN_EVMHEGSMFAA,
+  SPE_BUILTIN_EVMHEGSMFAN,
+  SPE_BUILTIN_EVMHEGSMIAA,
+  SPE_BUILTIN_EVMHEGSMIAN,
+  SPE_BUILTIN_EVMHEGUMIAA,
+  SPE_BUILTIN_EVMHEGUMIAN,
+  SPE_BUILTIN_EVMHESMF,
+  SPE_BUILTIN_EVMHESMFA,
+  SPE_BUILTIN_EVMHESMFAAW,
+  SPE_BUILTIN_EVMHESMFANW,
+  SPE_BUILTIN_EVMHESMI,
+  SPE_BUILTIN_EVMHESMIA,
+  SPE_BUILTIN_EVMHESMIAAW,
+  SPE_BUILTIN_EVMHESMIANW,
+  SPE_BUILTIN_EVMHESSF,
+  SPE_BUILTIN_EVMHESSFA,
+  SPE_BUILTIN_EVMHESSFAAW,
+  SPE_BUILTIN_EVMHESSFANW,
+  SPE_BUILTIN_EVMHESSIAAW,
+  SPE_BUILTIN_EVMHESSIANW,
+  SPE_BUILTIN_EVMHEUMI,
+  SPE_BUILTIN_EVMHEUMIA,
+  SPE_BUILTIN_EVMHEUMIAAW,
+  SPE_BUILTIN_EVMHEUMIANW,
+  SPE_BUILTIN_EVMHEUSIAAW,
+  SPE_BUILTIN_EVMHEUSIANW,
+  SPE_BUILTIN_EVMHOGSMFAA,
+  SPE_BUILTIN_EVMHOGSMFAN,
+  SPE_BUILTIN_EVMHOGSMIAA,
+  SPE_BUILTIN_EVMHOGSMIAN,
+  SPE_BUILTIN_EVMHOGUMIAA,
+  SPE_BUILTIN_EVMHOGUMIAN,
+  SPE_BUILTIN_EVMHOSMF,
+  SPE_BUILTIN_EVMHOSMFA,
+  SPE_BUILTIN_EVMHOSMFAAW,
+  SPE_BUILTIN_EVMHOSMFANW,
+  SPE_BUILTIN_EVMHOSMI,
+  SPE_BUILTIN_EVMHOSMIA,
+  SPE_BUILTIN_EVMHOSMIAAW,
+  SPE_BUILTIN_EVMHOSMIANW,
+  SPE_BUILTIN_EVMHOSSF,
+  SPE_BUILTIN_EVMHOSSFA,
+  SPE_BUILTIN_EVMHOSSFAAW,
+  SPE_BUILTIN_EVMHOSSFANW,
+  SPE_BUILTIN_EVMHOSSIAAW,
+  SPE_BUILTIN_EVMHOSSIANW,
+  SPE_BUILTIN_EVMHOUMI,
+  SPE_BUILTIN_EVMHOUMIA,
+  SPE_BUILTIN_EVMHOUMIAAW,
+  SPE_BUILTIN_EVMHOUMIANW,
+  SPE_BUILTIN_EVMHOUSIAAW,
+  SPE_BUILTIN_EVMHOUSIANW,
+  SPE_BUILTIN_EVMWHSMF,
+  SPE_BUILTIN_EVMWHSMFA,
+  SPE_BUILTIN_EVMWHSMI,
+  SPE_BUILTIN_EVMWHSMIA,
+  SPE_BUILTIN_EVMWHSSF,
+  SPE_BUILTIN_EVMWHSSFA,
+  SPE_BUILTIN_EVMWHUMI,
+  SPE_BUILTIN_EVMWHUMIA,
+  SPE_BUILTIN_EVMWLSMF,
+  SPE_BUILTIN_EVMWLSMFA,
+  SPE_BUILTIN_EVMWLSMFAAW,
+  SPE_BUILTIN_EVMWLSMFANW,
+  SPE_BUILTIN_EVMWLSMIAAW,
+  SPE_BUILTIN_EVMWLSMIANW,
+  SPE_BUILTIN_EVMWLSSF,
+  SPE_BUILTIN_EVMWLSSFA,
+  SPE_BUILTIN_EVMWLSSFAAW,
+  SPE_BUILTIN_EVMWLSSFANW,
+  SPE_BUILTIN_EVMWLSSIAAW,
+  SPE_BUILTIN_EVMWLSSIANW,
+  SPE_BUILTIN_EVMWLUMI,
+  SPE_BUILTIN_EVMWLUMIA,
+  SPE_BUILTIN_EVMWLUMIAAW,
+  SPE_BUILTIN_EVMWLUMIANW,
+  SPE_BUILTIN_EVMWLUSIAAW,
+  SPE_BUILTIN_EVMWLUSIANW,
+  SPE_BUILTIN_EVMWSMF,
+  SPE_BUILTIN_EVMWSMFA,
+  SPE_BUILTIN_EVMWSMFAA,
+  SPE_BUILTIN_EVMWSMFAN,
+  SPE_BUILTIN_EVMWSMI,
+  SPE_BUILTIN_EVMWSMIA,
+  SPE_BUILTIN_EVMWSMIAA,
+  SPE_BUILTIN_EVMWSMIAN,
+  SPE_BUILTIN_EVMWHSSFAA,
+  SPE_BUILTIN_EVMWSSF,
+  SPE_BUILTIN_EVMWSSFA,
+  SPE_BUILTIN_EVMWSSFAA,
+  SPE_BUILTIN_EVMWSSFAN,
+  SPE_BUILTIN_EVMWUMI,
+  SPE_BUILTIN_EVMWUMIA,
+  SPE_BUILTIN_EVMWUMIAA,
+  SPE_BUILTIN_EVMWUMIAN,
+  SPE_BUILTIN_EVNAND,
+  SPE_BUILTIN_EVNOR,
+  SPE_BUILTIN_EVOR,
+  SPE_BUILTIN_EVORC,
+  SPE_BUILTIN_EVRLW,
+  SPE_BUILTIN_EVSLW,
+  SPE_BUILTIN_EVSRWS,
+  SPE_BUILTIN_EVSRWU,
+  SPE_BUILTIN_EVSTDDX,
+  SPE_BUILTIN_EVSTDHX,
+  SPE_BUILTIN_EVSTDWX,
+  SPE_BUILTIN_EVSTWHEX,
+  SPE_BUILTIN_EVSTWHOX,
+  SPE_BUILTIN_EVSTWWEX,
+  SPE_BUILTIN_EVSTWWOX,
+  SPE_BUILTIN_EVSUBFW,
+  SPE_BUILTIN_EVXOR,
+  SPE_BUILTIN_EVABS,
+  SPE_BUILTIN_EVADDSMIAAW,
+  SPE_BUILTIN_EVADDSSIAAW,
+  SPE_BUILTIN_EVADDUMIAAW,
+  SPE_BUILTIN_EVADDUSIAAW,
+  SPE_BUILTIN_EVCNTLSW,
+  SPE_BUILTIN_EVCNTLZW,
+  SPE_BUILTIN_EVEXTSB,
+  SPE_BUILTIN_EVEXTSH,
+  SPE_BUILTIN_EVFSABS,
+  SPE_BUILTIN_EVFSCFSF,
+  SPE_BUILTIN_EVFSCFSI,
+  SPE_BUILTIN_EVFSCFUF,
+  SPE_BUILTIN_EVFSCFUI,
+  SPE_BUILTIN_EVFSCTSF,
+  SPE_BUILTIN_EVFSCTSI,
+  SPE_BUILTIN_EVFSCTSIZ,
+  SPE_BUILTIN_EVFSCTUF,
+  SPE_BUILTIN_EVFSCTUI,
+  SPE_BUILTIN_EVFSCTUIZ,
+  SPE_BUILTIN_EVFSNABS,
+  SPE_BUILTIN_EVFSNEG,
+  SPE_BUILTIN_EVMRA,
+  SPE_BUILTIN_EVNEG,
+  SPE_BUILTIN_EVRNDW,
+  SPE_BUILTIN_EVSUBFSMIAAW,
+  SPE_BUILTIN_EVSUBFSSIAAW,
+  SPE_BUILTIN_EVSUBFUMIAAW,
+  SPE_BUILTIN_EVSUBFUSIAAW,
+  SPE_BUILTIN_EVADDIW,
+  SPE_BUILTIN_EVLDD,
+  SPE_BUILTIN_EVLDH,
+  SPE_BUILTIN_EVLDW,
+  SPE_BUILTIN_EVLHHESPLAT,
+  SPE_BUILTIN_EVLHHOSSPLAT,
+  SPE_BUILTIN_EVLHHOUSPLAT,
+  SPE_BUILTIN_EVLWHE,
+  SPE_BUILTIN_EVLWHOS,
+  SPE_BUILTIN_EVLWHOU,
+  SPE_BUILTIN_EVLWHSPLAT,
+  SPE_BUILTIN_EVLWWSPLAT,
+  SPE_BUILTIN_EVRLWI,
+  SPE_BUILTIN_EVSLWI,
+  SPE_BUILTIN_EVSRWIS,
+  SPE_BUILTIN_EVSRWIU,
+  SPE_BUILTIN_EVSTDD,
+  SPE_BUILTIN_EVSTDH,
+  SPE_BUILTIN_EVSTDW,
+  SPE_BUILTIN_EVSTWHE,
+  SPE_BUILTIN_EVSTWHO,
+  SPE_BUILTIN_EVSTWWE,
+  SPE_BUILTIN_EVSTWWO,
+  SPE_BUILTIN_EVSUBIFW,
+
+  /* Compares.  */
+  SPE_BUILTIN_EVCMPEQ,
+  SPE_BUILTIN_EVCMPGTS,
+  SPE_BUILTIN_EVCMPGTU,
+  SPE_BUILTIN_EVCMPLTS,
+  SPE_BUILTIN_EVCMPLTU,
+  SPE_BUILTIN_EVFSCMPEQ,
+  SPE_BUILTIN_EVFSCMPGT,
+  SPE_BUILTIN_EVFSCMPLT,
+  SPE_BUILTIN_EVFSTSTEQ,
+  SPE_BUILTIN_EVFSTSTGT,
+  SPE_BUILTIN_EVFSTSTLT,
+
+  /* EVSEL compares.  */
+  SPE_BUILTIN_EVSEL_CMPEQ,
+  SPE_BUILTIN_EVSEL_CMPGTS,
+  SPE_BUILTIN_EVSEL_CMPGTU,
+  SPE_BUILTIN_EVSEL_CMPLTS,
+  SPE_BUILTIN_EVSEL_CMPLTU,
+  SPE_BUILTIN_EVSEL_FSCMPEQ,
+  SPE_BUILTIN_EVSEL_FSCMPGT,
+  SPE_BUILTIN_EVSEL_FSCMPLT,
+  SPE_BUILTIN_EVSEL_FSTSTEQ,
+  SPE_BUILTIN_EVSEL_FSTSTGT,
+  SPE_BUILTIN_EVSEL_FSTSTLT,
+
+  SPE_BUILTIN_EVSPLATFI,
+  SPE_BUILTIN_EVSPLATI,
+  SPE_BUILTIN_EVMWHSSMAA,
+  SPE_BUILTIN_EVMWHSMFAA,
+  SPE_BUILTIN_EVMWHSMIAA,
+  SPE_BUILTIN_EVMWHUSIAA,
+  SPE_BUILTIN_EVMWHUMIAA,
+  SPE_BUILTIN_EVMWHSSFAN,
+  SPE_BUILTIN_EVMWHSSIAN,
+  SPE_BUILTIN_EVMWHSMFAN,
+  SPE_BUILTIN_EVMWHSMIAN,
+  SPE_BUILTIN_EVMWHUSIAN,
+  SPE_BUILTIN_EVMWHUMIAN,
+  SPE_BUILTIN_EVMWHGSSFAA,
+  SPE_BUILTIN_EVMWHGSMFAA,
+  SPE_BUILTIN_EVMWHGSMIAA,
+  SPE_BUILTIN_EVMWHGUMIAA,
+  SPE_BUILTIN_EVMWHGSSFAN,
+  SPE_BUILTIN_EVMWHGSMFAN,
+  SPE_BUILTIN_EVMWHGSMIAN,
+  SPE_BUILTIN_EVMWHGUMIAN,
+  SPE_BUILTIN_MTSPEFSCR,
+  SPE_BUILTIN_MFSPEFSCR,
+  SPE_BUILTIN_BRINC
 };