OSDN Git Service

* config.gcc: Don't mention MAX_LONG_TYPE_SIZE.
[pf3gnuchains/gcc-fork.git] / gcc / config / rs6000 / rs6000.h
index fe932a6..cd8d05d 100644 (file)
@@ -1,25 +1,24 @@
 /* Definitions of target machine for GNU compiler, for IBM RS/6000.
    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+   2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
    Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
 
-This file is part of GNU CC.
+   This file is part of GCC.
 
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published
+   by the Free Software Foundation; either version 2, or (at your
+   option) any later version.
 
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING.  If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
 
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING.  If not, write to the
+   Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA.  */
 
 /* Note that some other tm.h files include this one and then override
    many of the definitions.  */
@@ -69,7 +68,9 @@ Boston, MA 02111-1307, USA.  */
 %{mcpu=401: -mppc} \
 %{mcpu=403: -m403} \
 %{mcpu=405: -m405} \
-%{mcpu=405f: -m405} \
+%{mcpu=405fp: -m405} \
+%{mcpu=440: -m440} \
+%{mcpu=440fp: -m440} \
 %{mcpu=505: -mppc} \
 %{mcpu=601: -m601} \
 %{mcpu=602: -mppc} \
@@ -83,11 +84,15 @@ Boston, MA 02111-1307, USA.  */
 %{mcpu=740: -mppc} \
 %{mcpu=7400: -mppc} \
 %{mcpu=7450: -mppc} \
+%{mcpu=G4: -mppc} \
 %{mcpu=750: -mppc} \
+%{mcpu=G3: -mppc} \
 %{mcpu=801: -mppc} \
 %{mcpu=821: -mppc} \
 %{mcpu=823: -mppc} \
 %{mcpu=860: -mppc} \
+%{mcpu=970: -mpower4} \
+%{mcpu=G5: -mpower4} \
 %{mcpu=8540: -me500} \
 %{maltivec: -maltivec}"
 
@@ -100,7 +105,7 @@ Boston, MA 02111-1307, USA.  */
    is an initializer with a subgrouping for each command option.
 
    Each subgrouping contains a string constant, that defines the
-   specification name, and a string constant that used by the GNU CC driver
+   specification name, and a string constant that used by the GCC driver
    program.
 
    Do not define this macro if it does not need to do anything.  */
@@ -155,7 +160,10 @@ extern int target_flags;
    function, and one less allocable register.  */
 #define MASK_MINIMAL_TOC       0x00000200
 
-/* Nonzero for the 64bit model: longs and pointers are 64 bits.  */
+/* Nonzero for the 64 bit ABIs: longs and pointers are 64 bits.  The
+   chip is running in "64-bit mode", in which CR0 is set in dot
+   operations based on all 64 bits of the register, bdnz works on 64-bit
+   ctr, lr is 64 bits, and so on.  Requires MASK_POWERPC64.  */
 #define MASK_64BIT             0x00000400
 
 /* Disable use of FPRs.  */
@@ -182,9 +190,12 @@ extern int target_flags;
 /* Return small structures in memory (as the AIX ABI requires).  */
 #define MASK_AIX_STRUCT_RET    0x00040000
 
-/* The only remaining free bits are 0x00780000. sysv4.h uses
-   0x00800000 -> 0x40000000, and 0x80000000 is not available
-   because target_flags is signed.  */
+/* Use single field mfcr instruction.  */
+#define MASK_MFCRF             0x00080000
+
+/* The only remaining free bits are 0x00600000.  linux64.h uses
+   0x00100000, and sysv4.h uses 0x00800000 -> 0x40000000.
+   0x80000000 is not available because target_flags is signed.  */
 
 #define TARGET_POWER           (target_flags & MASK_POWER)
 #define TARGET_POWER2          (target_flags & MASK_POWER2)
@@ -205,11 +216,26 @@ extern int target_flags;
 #define TARGET_ALTIVEC         (target_flags & MASK_ALTIVEC)
 #define TARGET_AIX_STRUCT_RET  (target_flags & MASK_AIX_STRUCT_RET)
 
+/* Define TARGET_MFCRF if the target assembler supports the optional
+   field operand for mfcr and the target processor supports the
+   instruction.  */
+
+#ifdef HAVE_AS_MFCRF
+#define TARGET_MFCRF           (target_flags & MASK_MFCRF)
+#else
+#define TARGET_MFCRF 0
+#endif
+
+
 #define TARGET_32BIT           (! TARGET_64BIT)
 #define TARGET_HARD_FLOAT      (! TARGET_SOFT_FLOAT)
 #define TARGET_UPDATE          (! TARGET_NO_UPDATE)
 #define TARGET_FUSED_MADD      (! TARGET_NO_FUSED_MADD)
 
+#ifndef HAVE_AS_TLS
+#define HAVE_AS_TLS 0
+#endif
+
 #ifdef IN_LIBGCC2
 /* For libgcc2 we make sure this is a compile time constant */
 #if defined (__64BIT__) || defined (__powerpc64__)
@@ -250,19 +276,19 @@ extern int target_flags;
   {"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")},\
+                       N_("Do not use PowerPC General Purpose group optional instructions")},\
   {"powerpc-gfxopt",   MASK_POWERPC | MASK_PPC_GFXOPT,                 \
                        N_("Use PowerPC Graphics group optional instructions")},\
   {"no-powerpc-gfxopt",        - MASK_PPC_GFXOPT,                              \
-                       N_("Don't use PowerPC Graphics group optional instructions")},\
+                       N_("Do not 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")},    \
+                       N_("Do not use PowerPC-64 instruction set")},   \
   {"altivec",          MASK_ALTIVEC ,                                  \
                        N_("Use AltiVec instructions")},                \
   {"no-altivec",       - MASK_ALTIVEC ,                                        \
-                       N_("Don't use AltiVec instructions")},  \
+                       N_("Do not use AltiVec instructions")}, \
   {"new-mnemonics",    MASK_NEW_MNEMONICS,                             \
                        N_("Use new mnemonics for PowerPC architecture")},\
   {"old-mnemonics",    -MASK_NEW_MNEMONICS,                            \
@@ -273,11 +299,11 @@ extern int target_flags;
   {"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")},\
+                       N_("Do not place floating point constants in TOC")},\
   {"sum-in-toc",       - MASK_NO_SUM_IN_TOC,                           \
                        N_("Place symbol+offset constants in TOC")},    \
   {"no-sum-in-toc",    MASK_NO_SUM_IN_TOC,                             \
-                       N_("Don't place symbol+offset constants in TOC")},\
+                       N_("Do not place symbol+offset constants in TOC")},\
   {"minimal-toc",      MASK_MINIMAL_TOC,                               \
                        "Use only one TOC entry per procedure"},        \
   {"minimal-toc",      - (MASK_NO_FP_IN_TOC | MASK_NO_SUM_IN_TOC),     \
@@ -285,9 +311,9 @@ extern int target_flags;
   {"no-minimal-toc",   - MASK_MINIMAL_TOC,                             \
                        N_("Place variable addresses in the regular TOC")},\
   {"hard-float",       - MASK_SOFT_FLOAT,                              \
-                       N_("Use hardware fp")},                         \
+                       N_("Use hardware floating point")},             \
   {"soft-float",       MASK_SOFT_FLOAT,                                \
-                       N_("Do not use hardware fp")},                  \
+                       N_("Do not use hardware floating point")},      \
   {"multiple",         MASK_MULTIPLE,                                  \
                        N_("Generate load/store multiple instructions")},       \
   {"no-multiple",      - MASK_MULTIPLE,                                \
@@ -303,11 +329,11 @@ extern int target_flags;
   {"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")},\
+                       N_("Do not 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")},\
+                       N_("Do not schedule the start and end of the procedure")},\
   {"sched-epilog",      MASK_SCHED_PROLOG,                              \
                        ""},                                            \
   {"no-sched-epilog",   -MASK_SCHED_PROLOG,                             \
@@ -317,9 +343,13 @@ extern int target_flags;
   {"svr4-struct-return", - MASK_AIX_STRUCT_RET,                                \
                        N_("Return small structures in registers (SVR4 default)")},\
   {"no-aix-struct-return", - MASK_AIX_STRUCT_RET,                      \
-                       ""},\
+                       ""},                                            \
   {"no-svr4-struct-return", MASK_AIX_STRUCT_RET,                       \
-                       ""},\
+                       ""},                                            \
+  {"mfcrf",            MASK_MFCRF,                                     \
+                       N_("Generate single field mfcr instruction")},  \
+  {"no-mfcrf",         - MASK_MFCRF,                                   \
+                       N_("Do not generate single field mfcr instruction")},\
   SUBTARGET_SWITCHES                                                   \
   {"",                 TARGET_DEFAULT | MASK_SCHED_PROLOG,             \
                        ""}}
@@ -371,31 +401,78 @@ extern enum processor_type rs6000_cpu;
    and the old mnemonics are dialect zero.  */
 #define ASSEMBLER_DIALECT (TARGET_NEW_MNEMONICS ? 1 : 0)
 
+/* Types of costly dependences.  */
+enum rs6000_dependence_cost
+ {
+   max_dep_latency = 1000,
+   no_dep_costly,
+   all_deps_costly,
+   true_store_to_load_dep_costly,
+   store_to_load_dep_costly
+ };
+
+/* Types of nop insertion schemes in sched target hook sched_finish.  */
+enum rs6000_nop_insertion
+  {
+    sched_finish_regroup_exact = 1000,
+    sched_finish_pad_groups,
+    sched_finish_none
+  };
+
+/* Dispatch group termination caused by an insn.  */
+enum group_termination
+  {
+    current_group,
+    previous_group
+  };
+
 /* This is meant to be overridden in target specific files.  */
 #define        SUBTARGET_OPTIONS
 
 #define TARGET_OPTIONS                                                 \
 {                                                                      \
    {"cpu=",  &rs6000_select[1].string,                                 \
-    N_("Use features of and schedule code for given CPU") },           \
+    N_("Use features of and schedule code for given CPU"), 0},         \
    {"tune=", &rs6000_select[2].string,                                 \
-    N_("Schedule code for given CPU") },                               \
-   {"debug=", &rs6000_debug_name, N_("Enable debug output") },         \
+    N_("Schedule code for given CPU"), 0},                             \
+   {"debug=", &rs6000_debug_name, N_("Enable debug output"), 0},       \
    {"traceback=", &rs6000_traceback_name,                              \
-    N_("Select full, part, or no traceback table") },                  \
-   {"abi=", &rs6000_abi_string, N_("Specify ABI to use") },            \
+    N_("Select full, part, or no traceback table"), 0},                        \
+   {"abi=", &rs6000_abi_string, N_("Specify ABI to use"), 0},          \
    {"long-double-", &rs6000_long_double_size_string,                   \
-    N_("Specify size of long double (64 or 128 bits)") },              \
+    N_("Specify size of long double (64 or 128 bits)"), 0},            \
    {"isel=", &rs6000_isel_string,                                       \
-    N_("Specify yes/no if isel instructions should be generated") },    \
-   {"vrsave=", &rs6000_altivec_vrsave_string,                         \
-    N_("Specify yes/no if VRSAVE instructions should be generated for AltiVec") }, \
+    N_("Specify yes/no if isel instructions should be generated"), 0},  \
+   {"spe=", &rs6000_spe_string,                                         \
+    N_("Specify yes/no if SPE SIMD instructions should be generated"), 0},\
+   {"float-gprs=", &rs6000_float_gprs_string,                           \
+    N_("Specify yes/no if using floating point in the GPRs"), 0},       \
+   {"vrsave=", &rs6000_altivec_vrsave_string,                           \
+    N_("Specify yes/no if VRSAVE instructions should be generated for AltiVec"), 0}, \
    {"longcall", &rs6000_longcall_switch,                               \
-    N_("Avoid all range limits on call instructions") },               \
-   {"no-longcall", &rs6000_longcall_switch, "" },                      \
+    N_("Avoid all range limits on call instructions"), 0},             \
+   {"no-longcall", &rs6000_longcall_switch, "", 0},                    \
+   {"sched-costly-dep=", &rs6000_sched_costly_dep_str,                  \
+    N_("Determine which dependences between insns are considered costly"), 0}, \
+   {"insert-sched-nops=", &rs6000_sched_insert_nops_str,                \
+    N_("Specify which post scheduling nop insertion scheme to apply"), 0}, \
+   {"align-", &rs6000_alignment_string,                                        \
+    N_("Specify alignment of structure fields default/natural"), 0},   \
+   {"prioritize-restricted-insns=", &rs6000_sched_restricted_insns_priority_str, \
+    N_("Specify scheduling priority for dispatch slot restricted insns"), 0}, \
    SUBTARGET_OPTIONS                                                   \
 }
 
+/* Support for a compile-time default CPU, et cetera.  The rules are:
+   --with-cpu is ignored if -mcpu is specified.
+   --with-tune is ignored if -mtune is specified.
+   --with-float is ignored if -mhard-float or -msoft-float are
+    specified.  */
+#define OPTION_DEFAULT_SPECS \
+  {"cpu", "%{!mcpu=*:-mcpu=%(VALUE)}" }, \
+  {"tune", "%{!mtune=*:-mtune=%(VALUE)}" }, \
+  {"float", "%{!msoft-float:%{!mhard-float:-m%(VALUE)-float}}" }
+
 /* rs6000_select[0] is reserved for the default cpu defined via --with-cpu */
 struct rs6000_cpu_select
 {
@@ -425,12 +502,53 @@ 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 int rs6000_spe;
+extern int rs6000_float_gprs;
+extern const char *rs6000_float_gprs_string;
 extern const char *rs6000_isel_string;
+extern const char *rs6000_spe_string;
 extern const char *rs6000_altivec_vrsave_string;
 extern int rs6000_altivec_vrsave;
 extern const char *rs6000_longcall_switch;
 extern int rs6000_default_long_calls;
+extern const char* rs6000_alignment_string;
+extern int rs6000_alignment_flags;
+extern const char *rs6000_sched_restricted_insns_priority_str;
+extern int rs6000_sched_restricted_insns_priority;
+extern const char *rs6000_sched_costly_dep_str;
+extern enum rs6000_dependence_cost rs6000_sched_costly_dep;
+extern const char *rs6000_sched_insert_nops_str;
+extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
+
+/* Alignment options for fields in structures for sub-targets following
+   AIX-like ABI.
+   ALIGN_POWER word-aligns FP doubles (default AIX ABI).
+   ALIGN_NATURAL doubleword-aligns FP doubles (align to object size).
+
+   Override the macro definitions when compiling libobjc to avoid undefined
+   reference to rs6000_alignment_flags due to library's use of GCC alignment
+   macros which use the macros below.  */
+   
+#ifndef IN_TARGET_LIBS
+#define MASK_ALIGN_POWER   0x00000000
+#define MASK_ALIGN_NATURAL 0x00000001
+#define TARGET_ALIGN_NATURAL (rs6000_alignment_flags & MASK_ALIGN_NATURAL)
+#else
+#define TARGET_ALIGN_NATURAL 0
+#endif
+
+/* Set a default value for DEFAULT_SCHED_COSTLY_DEP used by target hook
+   is_costly_dependence.  */ 
+#define DEFAULT_SCHED_COSTLY_DEP                           \
+  (rs6000_cpu == PROCESSOR_POWER4 ? store_to_load_dep_costly : no_dep_costly)
+
+/* Define if the target has restricted dispatch slot instructions.  */
+#define DEFAULT_RESTRICTED_INSNS_PRIORITY (rs6000_cpu == PROCESSOR_POWER4 ? 1 : 0)
+
+/* Set a default value for post scheduling nop insertion scheme
+   (used by taget hook sched_finish).  */
+#define DEFAULT_SCHED_FINISH_NOP_INSERTION_SCHEME          \
+  (rs6000_cpu == PROCESSOR_POWER4 ? sched_finish_regroup_exact : sched_finish_none)
 
 #define TARGET_LONG_DOUBLE_128 (rs6000_long_double_type_size == 128)
 #define TARGET_ALTIVEC_ABI rs6000_altivec_abi
@@ -438,6 +556,7 @@ extern int rs6000_default_long_calls;
 
 #define TARGET_SPE_ABI 0
 #define TARGET_SPE 0
+#define TARGET_E500 0
 #define TARGET_ISEL 0
 #define TARGET_FPRS 1
 
@@ -447,7 +566,7 @@ extern int rs6000_default_long_calls;
    defined, is executed once just after all the command options have
    been parsed.
 
-   Don't use this macro to turn on various extra optimizations for
+   Do not use this macro to turn on various extra optimizations for
    `-O'.  That is what `OPTIMIZATION_OPTIONS' is for.
 
    On the RS/6000 this is used to define the target cpu type.  */
@@ -500,16 +619,7 @@ extern int rs6000_default_long_calls;
 #define PROMOTE_MODE(MODE,UNSIGNEDP,TYPE)      \
   if (GET_MODE_CLASS (MODE) == MODE_INT                \
       && GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \
-    (MODE) = word_mode;
-
-/* Define this if function arguments should also be promoted using the above
-   procedure.  */
-
-#define PROMOTE_FUNCTION_ARGS
-
-/* Likewise, if the function return value is promoted.  */
-
-#define PROMOTE_FUNCTION_RETURN
+    (MODE) = TARGET_32BIT ? SImode : DImode;
 
 /* Define this if most significant bit is lowest numbered
    in instructions that operate on numbered bit-fields.  */
@@ -567,7 +677,6 @@ extern int rs6000_default_long_calls;
    target machine.  If you don't define this, the default is one
    word.  */
 #define LONG_TYPE_SIZE (TARGET_32BIT ? 32 : 64)
-#define MAX_LONG_TYPE_SIZE 64
 
 /* A C expression for the size in bits of the type `long long' on the
    target machine.  If you don't define this, the default is two
@@ -589,9 +698,6 @@ extern int rs6000_default_long_calls;
    words.  */
 #define LONG_DOUBLE_TYPE_SIZE rs6000_long_double_type_size
 
-/* Constant which presents upper bound of the above value.  */
-#define MAX_LONG_DOUBLE_TYPE_SIZE 128
-
 /* Define this to set long double type size to use in libgcc2.c, which can
    not depend on target_flags.  */
 #ifdef __LONG_DOUBLE_128__
@@ -704,19 +810,27 @@ extern int rs6000_default_long_calls;
 /* This must be included for pre gcc 3.0 glibc compatibility.  */
 #define PRE_GCC3_DWARF_FRAME_REGISTERS 77
 
-/* Add 32 dwarf columns for synthetic SPE registers.  The SPE
-   synthetic registers are 113 through 145.  */
+/* Add 32 dwarf columns for synthetic SPE registers.  */
 #define DWARF_FRAME_REGISTERS (FIRST_PSEUDO_REGISTER + 32)
 
-/* The SPE has an additional 32 synthetic registers starting at 1200.
-   We must map them here to sane values in the unwinder to avoid a
-   huge hole in the unwind tables.
-
-   FIXME: the AltiVec ABI has AltiVec registers being 1124-1155, and
-   the VRSAVE SPR (SPR256) assigned to register 356.  When AltiVec EH
-   is verified to be working, this macro should be changed
-   accordingly.  */
-#define DWARF_REG_TO_UNWIND_COLUMN(r) ((r) > 1200 ? ((r) - 1200 + 113) : (r))
+/* The SPE has an additional 32 synthetic registers, with DWARF debug
+   info numbering for these registers starting at 1200.  While eh_frame
+   register numbering need not be the same as the debug info numbering,
+   we choose to number these regs for eh_frame at 1200 too.  This allows
+   future versions of the rs6000 backend to add hard registers and
+   continue to use the gcc hard register numbering for eh_frame.  If the
+   extra SPE registers in eh_frame were numbered starting from the
+   current value of FIRST_PSEUDO_REGISTER, then if FIRST_PSEUDO_REGISTER
+   changed we'd need to introduce a mapping in DWARF_FRAME_REGNUM to
+   avoid invalidating older SPE eh_frame info.
+
+   We must map them here to avoid huge unwinder tables mostly consisting
+   of unused space.  */ 
+#define DWARF_REG_TO_UNWIND_COLUMN(r) \
+  ((r) > 1200 ? ((r) - 1200 + FIRST_PSEUDO_REGISTER) : (r))
+
+/* Use gcc hard register numbering for eh_frame.  */
+#define DWARF_FRAME_REGNUM(REGNO) (REGNO)
 
 /* 1 for registers that have pervasive standard uses
    and are not available for the register allocator.
@@ -828,6 +942,13 @@ extern int rs6000_default_long_calls;
        v31 - v20       (saved; order given to save least number)
 */
                                                
+#if FIXED_R2 == 1
+#define MAYBE_R2_AVAILABLE
+#define MAYBE_R2_FIXED 2,
+#else
+#define MAYBE_R2_AVAILABLE 2,
+#define MAYBE_R2_FIXED
+#endif
 
 #define REG_ALLOC_ORDER                                        \
   {32,                                                         \
@@ -836,13 +957,13 @@ extern int rs6000_default_long_calls;
    63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, \
    50, 49, 48, 47, 46,                                         \
    75, 74, 69, 68, 72, 71, 70,                         \
-   0,                                                  \
+   0, MAYBE_R2_AVAILABLE                               \
    9, 11, 10, 8, 7, 6, 5, 4,                           \
    3,                                                  \
    31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, \
    18, 17, 16, 15, 14, 13, 12,                         \
    64, 66, 65,                                                 \
-   73, 1, 2, 67, 76,                                   \
+   73, 1, MAYBE_R2_FIXED 67, 76,                       \
    /* AltiVec registers.  */                           \
    77, 78,                                             \
    90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80,         \
@@ -895,6 +1016,11 @@ extern int rs6000_default_long_calls;
    ? ((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 HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE)    \
+  ((TARGET_32BIT && TARGET_POWERPC64                   \
+    && (MODE == DImode || MODE == DFmode)              \
+    && INT_REGNO_P (REGNO)) ? 1 : 0)
+
 #define ALTIVEC_VECTOR_MODE(MODE)      \
         ((MODE) == V16QImode           \
          || (MODE) == V8HImode         \
@@ -916,22 +1042,24 @@ extern int rs6000_default_long_calls;
         || (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
+   For POWER and PowerPC, the GPRs can hold any mode, but values bigger
+   than one register cannot go past R31.  The float
    registers only can hold floating modes and DImode, and CR register only
    can hold CC modes.  We cannot put TImode anywhere except general
    register and it must be able to fit within the register set.  */
 
 #define HARD_REGNO_MODE_OK(REGNO, MODE)                                        \
-  (FP_REGNO_P (REGNO) ?                                                        \
-   (GET_MODE_CLASS (MODE) == MODE_FLOAT                                        \
-    || (GET_MODE_CLASS (MODE) == MODE_INT                              \
-       && GET_MODE_SIZE (MODE) == UNITS_PER_FP_WORD))                  \
+  (INT_REGNO_P (REGNO) ?                                               \
+     INT_REGNO_P (REGNO + HARD_REGNO_NREGS (REGNO, MODE) - 1)          \
+   : FP_REGNO_P (REGNO) ?                                              \
+     (GET_MODE_CLASS (MODE) == MODE_FLOAT                              \
+      || (GET_MODE_CLASS (MODE) == MODE_INT                            \
+         && GET_MODE_SIZE (MODE) == UNITS_PER_FP_WORD))                \
    : ALTIVEC_REGNO_P (REGNO) ? ALTIVEC_VECTOR_MODE (MODE)              \
    : SPE_SIMD_REGNO_P (REGNO) && TARGET_SPE && SPE_VECTOR_MODE (MODE) ? 1 \
    : CR_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_CC             \
    : XER_REGNO_P (REGNO) ? (MODE) == PSImode                           \
-   : ! INT_REGNO_P (REGNO) ? GET_MODE_SIZE (MODE) <= UNITS_PER_WORD    \
-   : 1)
+   : GET_MODE_SIZE (MODE) <= UNITS_PER_WORD)
 
 /* Value is 1 if it is a good idea to tie two pseudo registers
    when one has mode MODE1 and one has mode MODE2.
@@ -946,12 +1074,22 @@ extern int rs6000_default_long_calls;
    ? GET_MODE_CLASS (MODE2) == MODE_CC         \
    : GET_MODE_CLASS (MODE2) == MODE_CC         \
    ? GET_MODE_CLASS (MODE1) == MODE_CC         \
+   : SPE_VECTOR_MODE (MODE1)                   \
+   ? SPE_VECTOR_MODE (MODE2)                   \
+   : SPE_VECTOR_MODE (MODE2)                   \
+   ? SPE_VECTOR_MODE (MODE1)                   \
    : ALTIVEC_VECTOR_MODE (MODE1)               \
    ? ALTIVEC_VECTOR_MODE (MODE2)               \
    : ALTIVEC_VECTOR_MODE (MODE2)               \
    ? ALTIVEC_VECTOR_MODE (MODE1)               \
    : 1)
 
+/* Post-reload, we can't use any new AltiVec registers, as we already
+   emitted the vrsave mask.  */
+
+#define HARD_REGNO_RENAME_OK(SRC, DST) \
+  (! ALTIVEC_REGNO_P (DST) || regs_ever_live[DST])
+
 /* A C expression returning the cost of moving data from a register of class
    CLASS1 to one of CLASS2.  */
 
@@ -970,6 +1108,10 @@ extern int rs6000_default_long_calls;
 
 #define BRANCH_COST 3
 
+/* Override BRANCH_COST heuristic which empirically produces worse
+   performance for fold_range_test().  */
+
+#define RANGE_TEST_NON_SHORT_CIRCUIT 0
 
 /* A fixed register used at prologue and epilogue generation to fix
    addressing modes.  The SPE needs heavy addressing fixes at the last
@@ -1067,11 +1209,6 @@ extern int rs6000_default_long_calls;
 
 /* Count register number.  */
 #define COUNT_REGISTER_REGNUM 66
-
-/* Place that structure value return address is placed.
-
-   On the RS/6000, it is passed as an extra parameter.  */
-#define STRUCT_VALUE 0
 \f
 /* Define the classes of registers for register constraints in the
    machine description.  Also define ranges of constants.
@@ -1277,11 +1414,13 @@ enum reg_class
    'S' is a constant that can be placed into a 64-bit mask operand
    'T' is a constant that can be placed into a 32-bit mask operand
    'U' is for V.4 small data references.
+   'W' is a vector constant that can be easily generated (no mem refs).
+   'Y' is a indexed or word-aligned displacement memory operand. 
    '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) == 'R' ? legitimate_constant_pool_address_p (OP)              \
    : (C) == 'S' ? mask64_operand (OP, DImode)                          \
    : (C) == 'T' ? mask_operand (OP, SImode)                            \
    : (C) == 'U' ? (DEFAULT_ABI == ABI_V4                               \
@@ -1290,8 +1429,17 @@ enum reg_class
                   && (fixed_regs[CR0_REGNO]                            \
                       || !logical_operand (OP, DImode))                \
                   && !mask64_operand (OP, DImode))                     \
+   : (C) == 'W' ? (easy_vector_constant (OP, GET_MODE (OP)))           \
+   : (C) == 'Y' ? (word_offset_memref_operand (OP, GET_MODE (OP)))      \
    : 0)
 
+/* Define which constraints are memory constraints.  Tell reload
+   that any memory address can be reloaded by copying the 
+   memory address into a base register if required.  */
+
+#define EXTRA_MEMORY_CONSTRAINT(C, STR)                                \
+  ((C) == 'Q' || (C) == 'Y')
+
 /* Given an rtx X being reloaded into a reg required to be
    in class CLASS, return the class of reg to actually use.
    In general this is just CLASS; but on some machines
@@ -1348,11 +1496,14 @@ enum reg_class
 
 /* Return a class of registers that cannot change FROM mode to TO mode.  */
 
-#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS)                      \
-  (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO)                          \
-   ? reg_classes_intersect_p (FLOAT_REGS, CLASS)                       \
-   : (SPE_VECTOR_MODE (FROM) + SPE_VECTOR_MODE (TO)) == 1              \
-   ? reg_classes_intersect_p (GENERAL_REGS, CLASS)                     \
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS)                        \
+  (((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)                \
+    && GET_MODE_SIZE (FROM) >= 8 && GET_MODE_SIZE (TO) >= 8)             \
+   ? 0                                                                   \
+   : GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO)                                  \
+   ? reg_classes_intersect_p (FLOAT_REGS, CLASS)                         \
+   : (TARGET_SPE && (SPE_VECTOR_MODE (FROM) + SPE_VECTOR_MODE (TO)) == 1) \
+   ? reg_classes_intersect_p (GENERAL_REGS, CLASS)                       \
    : 0)
 
 /* Stack layout; function entry, exit and calling.  */
@@ -1361,57 +1512,12 @@ enum reg_class
 enum rs6000_abi {
   ABI_NONE,
   ABI_AIX,                     /* IBM's AIX */
-  ABI_AIX_NODESC,              /* AIX calling sequence minus
-                                  function descriptors */
   ABI_V4,                      /* System V.4/eabi */
   ABI_DARWIN                   /* Apple's Darwin (OS X kernel) */
 };
 
 extern enum rs6000_abi rs6000_current_abi;     /* available for use by subtarget */
 
-/* Structure used to define the rs6000 stack */
-typedef struct rs6000_stack {
-  int first_gp_reg_save;       /* first callee saved GP register used */
-  int first_fp_reg_save;       /* first callee saved FP register used */
-  int first_altivec_reg_save;  /* first callee saved AltiVec register used */
-  int lr_save_p;               /* true if the link reg needs to be saved */
-  int cr_save_p;               /* true if the CR reg needs to be saved */
-  unsigned int vrsave_mask;    /* mask of vec registers to save */
-  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 */
-  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 */
-  int altivec_save_offset;     /* offset to save AltiVec regs from initial SP */
-  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 */
-  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 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 altivec_size;            /* size of saved AltiVec 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 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 */
-  int spe_64bit_regs_used;
-} rs6000_stack_t;
-
 /* Define this if pushing a word on the stack
    makes the stack pointer a smaller address.  */
 #define STACK_GROWS_DOWNWARD
@@ -1427,14 +1533,13 @@ typedef struct rs6000_stack {
 
 /* Size of the outgoing register save area */
 #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 \
-  (((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_DARWIN) ? 24 : 8)   \
+  (((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN) ? 24 : 8)    \
    << (TARGET_64BIT ? 1 : 0))
 
 /* MEM representing address to save the TOC register */
@@ -1524,62 +1629,19 @@ typedef struct rs6000_stack {
 /* Define how to find the value returned by a function.
    VALTYPE is the data type of the value (as a tree).
    If the precise function being called is known, FUNC is its FUNCTION_DECL;
-   otherwise, FUNC is 0.
-
-   On 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.  */
-
-#define FUNCTION_VALUE(VALTYPE, FUNC)                          \
-  gen_rtx_REG ((INTEGRAL_TYPE_P (VALTYPE)                      \
-               && TYPE_PRECISION (VALTYPE) < BITS_PER_WORD)    \
-              || POINTER_TYPE_P (VALTYPE)                      \
-              ? word_mode : TYPE_MODE (VALTYPE),               \
-              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)
+   otherwise, FUNC is 0.  */
+
+#define FUNCTION_VALUE(VALTYPE, FUNC) rs6000_function_value ((VALTYPE), (FUNC))
 
 /* 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, ALTIVEC_VECTOR_MODE (MODE) ? ALTIVEC_ARG_RETURN   \
-                    : GET_MODE_CLASS (MODE) == MODE_FLOAT              \
-                    && TARGET_HARD_FLOAT && TARGET_FPRS                \
-                    ? FP_ARG_RETURN : GP_ARG_RETURN)
-
-/* The AIX ABI for the RS/6000 specifies that all structures are
-   returned in memory.  The Darwin ABI does the same.  The SVR4 ABI
-   specifies that structures <= 8 bytes are returned in r3/r4, but a
-   draft put them in memory, and GCC used to implement the draft
-   instead of the final standard.  Therefore, TARGET_AIX_STRUCT_RET
-   controls this instead of DEFAULT_ABI; V.4 targets needing backward
-   compatibility can change DRAFT_V4_STRUCT_RET to override the
-   default, and -m switches get the final word.  See
-   rs6000_override_options for more details.
-
-   The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
-   long double support is enabled.  These values are returned in memory.
-
-   int_size_in_bytes returns -1 for variable size objects, which go in
-   memory always.  The cast to unsigned makes -1 > 8.  */
-
-#define RETURN_IN_MEMORY(TYPE) \
-  ((AGGREGATE_TYPE_P (TYPE)                                            \
-    && (TARGET_AIX_STRUCT_RET                                          \
-       || (unsigned HOST_WIDE_INT) int_size_in_bytes (TYPE) > 8))      \
-   || (DEFAULT_ABI == ABI_V4 && TYPE_MODE (TYPE) == TFmode))
+#define LIBCALL_VALUE(MODE) rs6000_libcall_value ((MODE))
 
 /* DRAFT_V4_STRUCT_RET defaults off.  */
 #define DRAFT_V4_STRUCT_RET 0
 
-/* Let RETURN_IN_MEMORY control what happens.  */
+/* Let TARGET_RETURN_IN_MEMORY control what happens.  */
 #define DEFAULT_PCC_STRUCT_RETURN 0
 
 /* Mode of stack savearea.
@@ -1600,7 +1662,6 @@ typedef struct rs6000_stack {
 #define        FP_ARG_AIX_MAX_REG 45
 #define        FP_ARG_V4_MAX_REG  40
 #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)
@@ -1621,25 +1682,26 @@ typedef struct rs6000_stack {
 #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 CALL_LIBCALL           0x00000010      /* libcall */
 
 /* 1 if N is a possible register number for a function value
    as seen by the caller.
 
    On RS/6000, this is r3, fp1, and v2 (for AltiVec).  */
-#define FUNCTION_VALUE_REGNO_P(N)  ((N) == GP_ARG_RETURN       \
-                                   || ((N) == FP_ARG_RETURN)   \
-                                   || (TARGET_ALTIVEC &&       \
-                                       (N) == ALTIVEC_ARG_RETURN))
+#define FUNCTION_VALUE_REGNO_P(N)                                      \
+  ((N) == GP_ARG_RETURN                                                        \
+   || ((N) == FP_ARG_RETURN && TARGET_HARD_FLOAT)                      \
+   || ((N) == ALTIVEC_ARG_RETURN && TARGET_ALTIVEC))
 
 /* 1 if N is a possible register number for function argument passing.
    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))     \
-   || (TARGET_ALTIVEC &&                                               \
-       (unsigned)((N) - ALTIVEC_ARG_MIN_REG) < (unsigned)(ALTIVEC_ARG_NUM_REG)) \
-   || ((unsigned)((N) - FP_ARG_MIN_REG) < (unsigned)(FP_ARG_NUM_REG)))
-
+  ((unsigned) (N) - GP_ARG_MIN_REG < GP_ARG_NUM_REG                    \
+   || ((unsigned) (N) - ALTIVEC_ARG_MIN_REG < ALTIVEC_ARG_NUM_REG      \
+       && TARGET_ALTIVEC)                                              \
+   || ((unsigned) (N) - FP_ARG_MIN_REG < FP_ARG_NUM_REG                        \
+       && TARGET_HARD_FLOAT))
 \f
 /* A C structure for machine-specific, per-function data.
    This is added to the cfun structure.  */
@@ -1649,8 +1711,12 @@ typedef struct machine_function GTY(())
   int sysv_varargs_p;
   /* Flags if __builtin_return_address (n) with n >= 1 was used.  */
   int ra_needs_full_frame;
+  /* Some local-dynamic symbol.  */
+  const char *some_ld_name;
   /* Whether the instruction chain has been scanned already.  */
   int insn_chain_scanned_p;
+  /* Flags if __builtin_return_address (0) was used.  */
+  int ra_need_lr;
 } machine_function;
 
 /* Define a data type for recording info about an argument list
@@ -1677,8 +1743,8 @@ typedef struct rs6000_args
   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 */
+  int stdarg;                  /* Whether function is a stdarg function.  */
   int call_cookie;             /* Do special things for this call */
   int sysv_gregno;             /* next available GP register */
 } CUMULATIVE_ARGS;
@@ -1686,23 +1752,30 @@ typedef struct rs6000_args
 /* Define intermediate macro to compute the size (in registers) of an argument
    for the RS/6000.  */
 
+#define UNITS_PER_ARG (TARGET_32BIT ? 4 : 8)
+
 #define RS6000_ARG_SIZE(MODE, TYPE)                                    \
 ((MODE) != BLKmode                                                     \
- ? (GET_MODE_SIZE (MODE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD      \
- : (int_size_in_bytes (TYPE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
+ ? (GET_MODE_SIZE (MODE) + (UNITS_PER_ARG - 1)) / UNITS_PER_ARG                \
+ : (int_size_in_bytes (TYPE) + (UNITS_PER_ARG - 1)) / UNITS_PER_ARG)
 
 /* Initialize a variable CUM of type CUMULATIVE_ARGS
    for a call to a function whose data type is FNTYPE.
    For a library call, FNTYPE is 0.  */
 
-#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT) \
-  init_cumulative_args (&CUM, FNTYPE, LIBNAME, FALSE)
+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
+  init_cumulative_args (&CUM, FNTYPE, LIBNAME, FALSE, FALSE, N_NAMED_ARGS)
 
 /* Similar, but when scanning the definition of a procedure.  We always
    set NARGS_PROTOTYPE large so we never return an EXPR_LIST.  */
 
-#define INIT_CUMULATIVE_INCOMING_ARGS(CUM,FNTYPE,LIBNAME) \
-  init_cumulative_args (&CUM, FNTYPE, LIBNAME, TRUE)
+#define INIT_CUMULATIVE_INCOMING_ARGS(CUM, FNTYPE, LIBNAME) \
+  init_cumulative_args (&CUM, FNTYPE, LIBNAME, TRUE, FALSE, 1000)
+
+/* Like INIT_CUMULATIVE_ARGS' but only used for outgoing libcalls.  */
+
+#define INIT_CUMULATIVE_LIBCALL_ARGS(CUM, MODE, LIBNAME) \
+  init_cumulative_args (&CUM, NULL_TREE, LIBNAME, FALSE, TRUE, 0)
 
 /* Update the data in CUM to advance over an argument
    of mode MODE and data type TYPE.
@@ -1711,18 +1784,6 @@ typedef struct rs6000_args
 #define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED)   \
   function_arg_advance (&CUM, MODE, TYPE, NAMED)
 
-/* Nonzero if we can use a floating-point register to pass this arg.  */
-#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_FPRS)
-
-/* Nonzero 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.
@@ -1779,26 +1840,12 @@ typedef struct rs6000_args
 #define FUNCTION_ARG_BOUNDARY(MODE, TYPE) \
   function_arg_boundary (MODE, TYPE)
 
-/* Perform any needed actions needed for a function that is receiving a
-   variable number of arguments.
+/* Define to nonzero if complex arguments should be split into their
+   corresponding components.
 
-   CUM is as above.
-
-   MODE and TYPE are the mode and type of the current parameter.
-
-   PRETEND_SIZE is a variable that should be set to the amount of stack
-   that must be pushed by the prolog to pretend that our caller pushed
-   it.
-
-   Normally, this macro will push all remaining incoming registers on the
-   stack and set PRETEND_SIZE to the length of the registers pushed.  */
-
-#define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL) \
-  setup_incoming_varargs (&CUM, MODE, TYPE, &PRETEND_SIZE, NO_RTL)
-
-/* Define the `__builtin_va_list' type for the ABI.  */
-#define BUILD_VA_LIST_TYPE(VALIST) \
-  (VALIST) = rs6000_build_va_list ()
+   This should be set for Linux and Darwin as well, but we can't break
+   the ABIs at the moment.  For now, only AIX gets fixed.  */
+#define SPLIT_COMPLEX_ARGS (DEFAULT_ABI == ABI_AIX)
 
 /* Implement `va_start' for varargs and stdarg.  */
 #define EXPAND_BUILTIN_VA_START(valist, nextarg) \
@@ -1808,17 +1855,8 @@ typedef struct rs6000_args
 #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
+#define PAD_VARARGS_DOWN \
+   (FUNCTION_ARG_PADDING (TYPE_MODE (type), type) == downward)
 
 /* Output assembler code to FILE to increment profiler label # LABELNO
    for profiling a function entry.  */
@@ -1844,7 +1882,7 @@ typedef struct rs6000_args
    || (TARGET_ALTIVEC && (REGNO) == VRSAVE_REGNO)              \
    || (current_function_calls_eh_return                                \
        && TARGET_AIX                                           \
-       && (REGNO) == TOC_REGISTER))
+       && (REGNO) == 2))
 
 \f
 /* TRAMPOLINE_TEMPLATE deleted */
@@ -1875,8 +1913,7 @@ typedef struct rs6000_args
    abi's store the return address.  */
 #define RETURN_ADDRESS_OFFSET                                          \
  ((DEFAULT_ABI == ABI_AIX                                              \
-   || DEFAULT_ABI == ABI_DARWIN                                                \
-   || DEFAULT_ABI == ABI_AIX_NODESC)   ? (TARGET_32BIT ? 8 : 16) :     \
+   || DEFAULT_ABI == ABI_DARWIN)       ? (TARGET_32BIT ? 8 : 16) :     \
   (DEFAULT_ABI == ABI_V4)              ? 4 :                           \
   (internal_error ("RETURN_ADDRESS_OFFSET not supported"), 0))
 
@@ -1927,21 +1964,8 @@ typedef struct rs6000_args
 
 /* Define the offset between two registers, one to be eliminated, and the other
    its replacement, at the start of a routine.  */
-#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET)                   \
-{                                                                      \
-  rs6000_stack_t *info = rs6000_stack_info ();                         \
-                                                                       \
- if ((FROM) == FRAME_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM)   \
-   (OFFSET) = (info->push_p) ? 0 : - info->total_size;                 \
- else if ((FROM) == ARG_POINTER_REGNUM && (TO) == FRAME_POINTER_REGNUM)        \
-   (OFFSET) = info->total_size;                                                \
- else if ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM)        \
-   (OFFSET) = (info->push_p) ? info->total_size : 0;                   \
-  else if ((FROM) == RS6000_PIC_OFFSET_TABLE_REGNUM)                   \
-    (OFFSET) = 0;                                                      \
-  else                                                                 \
-    abort ();                                                          \
-}
+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
+  ((OFFSET) = rs6000_initial_elimination_offset(FROM, TO))
 \f
 /* Addressing modes, and classification of registers for them.  */
 
@@ -1987,9 +2011,13 @@ typedef struct rs6000_args
    acceptable.  */
 
 #define LEGITIMATE_CONSTANT_P(X)                               \
-  (GET_CODE (X) != CONST_DOUBLE || GET_MODE (X) == VOIDmode    \
-   || (TARGET_POWERPC64 && GET_MODE (X) == DImode)             \
-   || easy_fp_constant (X, GET_MODE (X)))
+  (((GET_CODE (X) != CONST_DOUBLE                              \
+     && GET_CODE (X) != CONST_VECTOR)                          \
+    || GET_MODE (X) == VOIDmode                                        \
+    || (TARGET_POWERPC64 && GET_MODE (X) == DImode)            \
+    || easy_fp_constant (X, GET_MODE (X))                      \
+    || easy_vector_constant (X, GET_MODE (X)))                 \
+   && !rs6000_tls_referenced_p (X))
 
 /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
    and check its validity for a certain class.
@@ -2045,73 +2073,6 @@ typedef struct rs6000_args
    adjacent memory cells are accessed by adding word-sized offsets
    during assembly output.  */
 
-#define CONSTANT_POOL_EXPR_P(X) (constant_pool_expr_p (X))
-
-#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                                              \
-  && 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                                               \
-   && !flag_pic && !TARGET_TOC                                         \
-   && (GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == CONST)            \
-   && small_data_operand (X, MODE))
-
-#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, 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)                            \
-      || (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)       \
-         : ! (INTVAL (XEXP (X, 1)) & 3)))                      \
-  && (((MODE) != TFmode && (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, 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                       \
-   && GET_MODE_NUNITS (MODE) == 1                      \
-   && (GET_MODE_BITSIZE (MODE) <= 32                   \
-       || (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))    \
-   && CONSTANT_P (XEXP (X, 1)))
-
 #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)                        \
 { if (rs6000_legitimate_address (MODE, X, REG_OK_STRICT_FLAG)) \
     goto ADDR;                                                 \
@@ -2166,27 +2127,13 @@ do {                                                                         \
 } while (0)
 
 /* Go to LABEL if ADDR (a legitimate address expression)
-   has an effect that depends on the machine mode it is used for.
-
-   On the RS/6000 this is true if the address is valid with a zero offset
-   but not with an offset of four (this means it cannot be used as an
-   address for DImode or DFmode) or is a pre-increment or decrement.  Since
-   we know it is valid, we just check for an address that is not valid with
-   an offset of four.  */
+   has an effect that depends on the machine mode it is used for.  */
 
 #define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL)               \
-{ if (GET_CODE (ADDR) == PLUS                                  \
-      && LEGITIMATE_ADDRESS_INTEGER_P (XEXP (ADDR, 1), 0)      \
-      && ! LEGITIMATE_ADDRESS_INTEGER_P (XEXP (ADDR, 1),       \
-                                        (TARGET_32BIT ? 4 : 8))) \
-    goto LABEL;                                                        \
-  if (TARGET_UPDATE && GET_CODE (ADDR) == PRE_INC)             \
-    goto LABEL;                                                        \
-  if (TARGET_UPDATE && GET_CODE (ADDR) == PRE_DEC)             \
-    goto LABEL;                                                        \
-  if (GET_CODE (ADDR) == LO_SUM)                               \
+do {                                                           \
+  if (rs6000_mode_dependent_address (ADDR))                    \
     goto LABEL;                                                        \
-}
+} while (0)
 \f
 /* The register number of the register used to address a table of
    static data addresses in memory.  In some cases this register is
@@ -2233,14 +2180,6 @@ do {                                                                          \
    generating position independent code.  */
 
 /* #define LEGITIMATE_PIC_OPERAND_P (X) */
-
-/* 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.  */
-
-/* #define MACHINE_DEPENDENT_REORG(INSN) */
-
 \f
 /* Define this if some processing needs to be done immediately before
    emitting code for an insn.  */
@@ -2304,6 +2243,9 @@ do {                                                                           \
    between pointers and any other objects of this machine mode.  */
 #define Pmode (TARGET_32BIT ? SImode : DImode)
 
+/* Supply definition of STACK_SIZE_MODE for allocate_dynamic_stack_space.  */
+#define STACK_SIZE_MODE (TARGET_32BIT ? SImode : DImode)
+
 /* Mode of a function address in a call instruction (for indexing purposes).
    Doesn't matter on RS/6000.  */
 #define FUNCTION_MODE SImode
@@ -2342,9 +2284,16 @@ do {                                                                          \
    : (((OP) == EQ || (OP) == NE) && GET_RTX_CLASS (GET_CODE (X)) == '<'   \
       ? CCEQmode : CCmode))
 
+/* Can the condition code MODE be safely reversed?  This is safe in
+   all cases on this port, because at present it doesn't use the
+   trapping FP comparisons (fcmpo).  */
+#define REVERSIBLE_CC_MODE(MODE) 1
+
+/* Given a condition code and a mode, return the inverse condition.  */
+#define REVERSE_CONDITION(CODE, MODE) rs6000_reverse_condition (MODE, CODE)
+
 /* Define the information needed to generate branch and scc insns.  This is
-   stored from the compare operation.  Note that we can't use "rtx" here
-   since it hasn't been defined!  */
+   stored from the compare operation.  */
 
 extern GTY(()) rtx rs6000_compare_op0;
 extern GTY(()) rtx rs6000_compare_op1;
@@ -2451,6 +2400,8 @@ extern int toc_initialized;
     }                                                                  \
    while (0)
 
+#define TARGET_ASM_FILE_START rs6000_file_start
+
 /* Output to assembler file text saying following lines
    may contain character constants, extra white space, comments, etc.  */
 
@@ -2588,31 +2539,6 @@ extern char rs6000_reg_names[][8];       /* register names (0 vs. %r0).  */
   &rs6000_reg_names[112][0],   /* spefscr */                           \
 }
 
-/* print-rtl can't handle the above REGISTER_NAMES, so define the
-   following for it.  Switch to use the alternate names since
-   they are more mnemonic.  */
-
-#define DEBUG_REGISTER_NAMES                                           \
-{                                                                      \
-     "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",            \
-     "r8",  "r9", "r10", "r11", "r12", "r13", "r14", "r15",            \
-    "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",            \
-    "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",            \
-     "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",            \
-     "f8",  "f9", "f10", "f11", "f12", "f13", "f14", "f15",            \
-    "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",            \
-    "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",            \
-     "mq",  "lr", "ctr",  "ap",                                                \
-    "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",            \
-    "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", "vscr",                                                  \
-    "spe_acc", "spefscr"                                                \
-}
-
 /* Table of additional register names to use in user input.  */
 
 #define ADDITIONAL_REGISTER_NAMES \
@@ -2692,7 +2618,7 @@ extern char rs6000_reg_names[][8];        /* register names (0 vs. %r0).  */
 /* Define which CODE values are valid.  */
 
 #define PRINT_OPERAND_PUNCT_VALID_P(CODE)  \
-  ((CODE) == '.')
+  ((CODE) == '.' || (CODE) == '&')
 
 /* Print a memory address as an operand to reference that memory location.  */
 
@@ -2724,6 +2650,8 @@ extern char rs6000_reg_names[][8];        /* register names (0 vs. %r0).  */
   {"got_operand", {SYMBOL_REF, CONST, LABEL_REF}},                        \
   {"got_no_const_operand", {SYMBOL_REF, LABEL_REF}},                      \
   {"easy_fp_constant", {CONST_DOUBLE}},                                           \
+  {"easy_vector_constant", {CONST_VECTOR}},                               \
+  {"easy_vector_constant_add_self", {CONST_VECTOR}},                      \
   {"zero_fp_constant", {CONST_DOUBLE}},                                           \
   {"reg_or_mem_operand", {SUBREG, MEM, REG}},                             \
   {"lwa_operand", {SUBREG, MEM, REG}},                                    \
@@ -2744,6 +2672,7 @@ extern char rs6000_reg_names[][8];        /* register names (0 vs. %r0).  */
   {"count_register_operand", {REG}},                                      \
   {"xer_operand", {REG}},                                                 \
   {"symbol_ref_operand", {SYMBOL_REF}},                                           \
+  {"rs6000_tls_symbol_ref", {SYMBOL_REF}},                                \
   {"call_operand", {SYMBOL_REF, REG}},                                    \
   {"current_file_function_operand", {SYMBOL_REF}},                        \
   {"input_operand", {SUBREG, MEM, REG, CONST_INT,                         \