• Main Page
  • Modules
  • Data Types
  • Files

osprey-gcc-4.2.0/gcc/config/rs6000/rs6000.c

Go to the documentation of this file.
00001 /* Subroutines used for code generation on IBM RS/6000.
00002    Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
00003    2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
00004    Free Software Foundation, Inc.
00005    Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
00006 
00007    This file is part of GCC.
00008 
00009    GCC is free software; you can redistribute it and/or modify it
00010    under the terms of the GNU General Public License as published
00011    by the Free Software Foundation; either version 2, or (at your
00012    option) any later version.
00013 
00014    GCC is distributed in the hope that it will be useful, but WITHOUT
00015    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
00016    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
00017    License for more details.
00018 
00019    You should have received a copy of the GNU General Public License
00020    along with GCC; see the file COPYING.  If not, write to the
00021    Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
00022    MA 02110-1301, USA.  */
00023 
00024 #include "config.h"
00025 #include "system.h"
00026 #include "coretypes.h"
00027 #include "tm.h"
00028 #include "rtl.h"
00029 #include "regs.h"
00030 #include "hard-reg-set.h"
00031 #include "real.h"
00032 #include "insn-config.h"
00033 #include "conditions.h"
00034 #include "insn-attr.h"
00035 #include "flags.h"
00036 #include "recog.h"
00037 #include "obstack.h"
00038 #include "tree.h"
00039 #include "expr.h"
00040 #include "optabs.h"
00041 #include "except.h"
00042 #include "function.h"
00043 #include "output.h"
00044 #include "basic-block.h"
00045 #include "integrate.h"
00046 #include "toplev.h"
00047 #include "ggc.h"
00048 #include "hashtab.h"
00049 #include "tm_p.h"
00050 #include "target.h"
00051 #include "target-def.h"
00052 #include "langhooks.h"
00053 #include "reload.h"
00054 #include "cfglayout.h"
00055 #include "sched-int.h"
00056 #include "tree-gimple.h"
00057 #include "intl.h"
00058 #include "params.h"
00059 #include "tm-constrs.h"
00060 #if TARGET_XCOFF
00061 #include "xcoffout.h"  /* get declarations of xcoff_*_section_name */
00062 #endif
00063 #if TARGET_MACHO
00064 #include "gstab.h"  /* for N_SLINE */
00065 #endif
00066 
00067 #ifndef TARGET_NO_PROTOTYPE
00068 #define TARGET_NO_PROTOTYPE 0
00069 #endif
00070 
00071 #define min(A,B)  ((A) < (B) ? (A) : (B))
00072 #define max(A,B)  ((A) > (B) ? (A) : (B))
00073 
00074 /* Structure used to define the rs6000 stack */
00075 typedef struct rs6000_stack {
00076   int first_gp_reg_save;  /* first callee saved GP register used */
00077   int first_fp_reg_save;  /* first callee saved FP register used */
00078   int first_altivec_reg_save; /* first callee saved AltiVec register used */
00079   int lr_save_p;    /* true if the link reg needs to be saved */
00080   int cr_save_p;    /* true if the CR reg needs to be saved */
00081   unsigned int vrsave_mask; /* mask of vec registers to save */
00082   int push_p;     /* true if we need to allocate stack space */
00083   int calls_p;      /* true if the function makes any calls */
00084   int world_save_p;   /* true if we're saving *everything*:
00085            r13-r31, cr, f14-f31, vrsave, v20-v31  */
00086   enum rs6000_abi abi;    /* which ABI to use */
00087   int gp_save_offset;   /* offset to save GP regs from initial SP */
00088   int fp_save_offset;   /* offset to save FP regs from initial SP */
00089   int altivec_save_offset;  /* offset to save AltiVec regs from initial SP */
00090   int lr_save_offset;   /* offset to save LR from initial SP */
00091   int cr_save_offset;   /* offset to save CR from initial SP */
00092   int vrsave_save_offset; /* offset to save VRSAVE from initial SP */
00093   int spe_gp_save_offset; /* offset to save spe 64-bit gprs  */
00094   int varargs_save_offset;  /* offset to save the varargs registers */
00095   int ehrd_offset;    /* offset to EH return data */
00096   int reg_size;     /* register size (4 or 8) */
00097   HOST_WIDE_INT vars_size;  /* variable save area size */
00098   int parm_size;    /* outgoing parameter size */
00099   int save_size;    /* save area size */
00100   int fixed_size;   /* fixed size of stack frame */
00101   int gp_size;      /* size of saved GP registers */
00102   int fp_size;      /* size of saved FP registers */
00103   int altivec_size;   /* size of saved AltiVec registers */
00104   int cr_size;      /* size to hold CR if not in save_size */
00105   int vrsave_size;    /* size to hold VRSAVE if not in save_size */
00106   int altivec_padding_size; /* size of altivec alignment padding if
00107            not in save_size */
00108   int spe_gp_size;    /* size of 64-bit GPR save size for SPE */
00109   int spe_padding_size;
00110   HOST_WIDE_INT total_size; /* total bytes allocated for stack */
00111   int spe_64bit_regs_used;
00112 } rs6000_stack_t;
00113 
00114 /* A C structure for machine-specific, per-function data.
00115    This is added to the cfun structure.  */
00116 typedef struct machine_function GTY(())
00117 {
00118   /* Flags if __builtin_return_address (n) with n >= 1 was used.  */
00119   int ra_needs_full_frame;
00120   /* Some local-dynamic symbol.  */
00121   const char *some_ld_name;
00122   /* Whether the instruction chain has been scanned already.  */
00123   int insn_chain_scanned_p;
00124   /* Flags if __builtin_return_address (0) was used.  */
00125   int ra_need_lr;
00126   /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4
00127      varargs save area.  */
00128   HOST_WIDE_INT varargs_save_offset;
00129 } machine_function;
00130 
00131 /* Target cpu type */
00132 
00133 enum processor_type rs6000_cpu;
00134 struct rs6000_cpu_select rs6000_select[3] =
00135 {
00136   /* switch   name,     tune  arch */
00137   { (const char *)0,  "--with-cpu=",    1,  1 },
00138   { (const char *)0,  "-mcpu=",   1,  1 },
00139   { (const char *)0,  "-mtune=",    1,  0 },
00140 };
00141 
00142 /* Always emit branch hint bits.  */
00143 static GTY(()) bool rs6000_always_hint;
00144 
00145 /* Schedule instructions for group formation.  */
00146 static GTY(()) bool rs6000_sched_groups;
00147 
00148 /* Support for -msched-costly-dep option.  */
00149 const char *rs6000_sched_costly_dep_str;
00150 enum rs6000_dependence_cost rs6000_sched_costly_dep;
00151 
00152 /* Support for -minsert-sched-nops option.  */
00153 const char *rs6000_sched_insert_nops_str;
00154 enum rs6000_nop_insertion rs6000_sched_insert_nops;
00155 
00156 /* Support targetm.vectorize.builtin_mask_for_load.  */
00157 static GTY(()) tree altivec_builtin_mask_for_load;
00158 
00159 /* Size of long double.  */
00160 int rs6000_long_double_type_size;
00161 
00162 /* IEEE quad extended precision long double. */
00163 int rs6000_ieeequad;
00164 
00165 /* Whether -mabi=altivec has appeared.  */
00166 int rs6000_altivec_abi;
00167 
00168 /* Nonzero if we want SPE ABI extensions.  */
00169 int rs6000_spe_abi;
00170 
00171 /* Nonzero if floating point operations are done in the GPRs.  */
00172 int rs6000_float_gprs = 0;
00173 
00174 /* Nonzero if we want Darwin's struct-by-value-in-regs ABI.  */
00175 int rs6000_darwin64_abi;
00176 
00177 /* Set to nonzero once AIX common-mode calls have been defined.  */
00178 static GTY(()) int common_mode_defined;
00179 
00180 /* Save information from a "cmpxx" operation until the branch or scc is
00181    emitted.  */
00182 rtx rs6000_compare_op0, rs6000_compare_op1;
00183 int rs6000_compare_fp_p;
00184 
00185 /* Label number of label created for -mrelocatable, to call to so we can
00186    get the address of the GOT section */
00187 int rs6000_pic_labelno;
00188 
00189 #ifdef USING_ELFOS_H
00190 /* Which abi to adhere to */
00191 const char *rs6000_abi_name;
00192 
00193 /* Semantics of the small data area */
00194 enum rs6000_sdata_type rs6000_sdata = SDATA_DATA;
00195 
00196 /* Which small data model to use */
00197 const char *rs6000_sdata_name = (char *)0;
00198 
00199 /* Counter for labels which are to be placed in .fixup.  */
00200 int fixuplabelno = 0;
00201 #endif
00202 
00203 /* Bit size of immediate TLS offsets and string from which it is decoded.  */
00204 int rs6000_tls_size = 32;
00205 const char *rs6000_tls_size_string;
00206 
00207 /* ABI enumeration available for subtarget to use.  */
00208 enum rs6000_abi rs6000_current_abi;
00209 
00210 /* Whether to use variant of AIX ABI for PowerPC64 Linux.  */
00211 int dot_symbols;
00212 
00213 /* Debug flags */
00214 const char *rs6000_debug_name;
00215 int rs6000_debug_stack;   /* debug stack applications */
00216 int rs6000_debug_arg;   /* debug argument handling */
00217 
00218 /* Value is TRUE if register/mode pair is acceptable.  */
00219 bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
00220 
00221 /* Built in types.  */
00222 
00223 tree rs6000_builtin_types[RS6000_BTI_MAX];
00224 tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
00225 
00226 const char *rs6000_traceback_name;
00227 static enum {
00228   traceback_default = 0,
00229   traceback_none,
00230   traceback_part,
00231   traceback_full
00232 } rs6000_traceback;
00233 
00234 /* Flag to say the TOC is initialized */
00235 int toc_initialized;
00236 char toc_label_name[10];
00237 
00238 static GTY(()) section *read_only_data_section;
00239 static GTY(()) section *private_data_section;
00240 static GTY(()) section *read_only_private_data_section;
00241 static GTY(()) section *sdata2_section;
00242 static GTY(()) section *toc_section;
00243 
00244 /* Control alignment for fields within structures.  */
00245 /* String from -malign-XXXXX.  */
00246 int rs6000_alignment_flags;
00247 
00248 /* True for any options that were explicitly set.  */
00249 struct {
00250   bool aix_struct_ret;    /* True if -maix-struct-ret was used.  */
00251   bool alignment;   /* True if -malign- was used.  */
00252   bool abi;     /* True if -mabi=spe/nospe was used.  */
00253   bool spe;     /* True if -mspe= was used.  */
00254   bool float_gprs;    /* True if -mfloat-gprs= was used.  */
00255   bool isel;      /* True if -misel was used. */
00256   bool long_double;         /* True if -mlong-double- was used.  */
00257   bool ieee;      /* True if -mabi=ieee/ibmlongdouble used.  */
00258 } rs6000_explicit_options;
00259 
00260 struct builtin_description
00261 {
00262   /* mask is not const because we're going to alter it below.  This
00263      nonsense will go away when we rewrite the -march infrastructure
00264      to give us more target flag bits.  */
00265   unsigned int mask;
00266   const enum insn_code icode;
00267   const char *const name;
00268   const enum rs6000_builtins code;
00269 };
00270 
00271 /* Target cpu costs.  */
00272 
00273 struct processor_costs {
00274   const int mulsi;    /* cost of SImode multiplication.  */
00275   const int mulsi_const;  /* cost of SImode multiplication by constant.  */
00276   const int mulsi_const9; /* cost of SImode mult by short constant.  */
00277   const int muldi;    /* cost of DImode multiplication.  */
00278   const int divsi;    /* cost of SImode division.  */
00279   const int divdi;    /* cost of DImode division.  */
00280   const int fp;     /* cost of simple SFmode and DFmode insns.  */
00281   const int dmul;   /* cost of DFmode multiplication (and fmadd).  */
00282   const int sdiv;   /* cost of SFmode division (fdivs).  */
00283   const int ddiv;   /* cost of DFmode division (fdiv).  */
00284 };
00285 
00286 const struct processor_costs *rs6000_cost;
00287 
00288 /* Processor costs (relative to an add) */
00289 
00290 /* Instruction size costs on 32bit processors.  */
00291 static const
00292 struct processor_costs size32_cost = {
00293   COSTS_N_INSNS (1),    /* mulsi */
00294   COSTS_N_INSNS (1),    /* mulsi_const */
00295   COSTS_N_INSNS (1),    /* mulsi_const9 */
00296   COSTS_N_INSNS (1),    /* muldi */
00297   COSTS_N_INSNS (1),    /* divsi */
00298   COSTS_N_INSNS (1),    /* divdi */
00299   COSTS_N_INSNS (1),    /* fp */
00300   COSTS_N_INSNS (1),    /* dmul */
00301   COSTS_N_INSNS (1),    /* sdiv */
00302   COSTS_N_INSNS (1),    /* ddiv */
00303 };
00304 
00305 /* Instruction size costs on 64bit processors.  */
00306 static const
00307 struct processor_costs size64_cost = {
00308   COSTS_N_INSNS (1),    /* mulsi */
00309   COSTS_N_INSNS (1),    /* mulsi_const */
00310   COSTS_N_INSNS (1),    /* mulsi_const9 */
00311   COSTS_N_INSNS (1),    /* muldi */
00312   COSTS_N_INSNS (1),    /* divsi */
00313   COSTS_N_INSNS (1),    /* divdi */
00314   COSTS_N_INSNS (1),    /* fp */
00315   COSTS_N_INSNS (1),    /* dmul */
00316   COSTS_N_INSNS (1),    /* sdiv */
00317   COSTS_N_INSNS (1),    /* ddiv */
00318 };
00319 
00320 /* Instruction costs on RIOS1 processors.  */
00321 static const
00322 struct processor_costs rios1_cost = {
00323   COSTS_N_INSNS (5),    /* mulsi */
00324   COSTS_N_INSNS (4),    /* mulsi_const */
00325   COSTS_N_INSNS (3),    /* mulsi_const9 */
00326   COSTS_N_INSNS (5),    /* muldi */
00327   COSTS_N_INSNS (19),   /* divsi */
00328   COSTS_N_INSNS (19),   /* divdi */
00329   COSTS_N_INSNS (2),    /* fp */
00330   COSTS_N_INSNS (2),    /* dmul */
00331   COSTS_N_INSNS (19),   /* sdiv */
00332   COSTS_N_INSNS (19),   /* ddiv */
00333 };
00334 
00335 /* Instruction costs on RIOS2 processors.  */
00336 static const
00337 struct processor_costs rios2_cost = {
00338   COSTS_N_INSNS (2),    /* mulsi */
00339   COSTS_N_INSNS (2),    /* mulsi_const */
00340   COSTS_N_INSNS (2),    /* mulsi_const9 */
00341   COSTS_N_INSNS (2),    /* muldi */
00342   COSTS_N_INSNS (13),   /* divsi */
00343   COSTS_N_INSNS (13),   /* divdi */
00344   COSTS_N_INSNS (2),    /* fp */
00345   COSTS_N_INSNS (2),    /* dmul */
00346   COSTS_N_INSNS (17),   /* sdiv */
00347   COSTS_N_INSNS (17),   /* ddiv */
00348 };
00349 
00350 /* Instruction costs on RS64A processors.  */
00351 static const
00352 struct processor_costs rs64a_cost = {
00353   COSTS_N_INSNS (20),   /* mulsi */
00354   COSTS_N_INSNS (12),   /* mulsi_const */
00355   COSTS_N_INSNS (8),    /* mulsi_const9 */
00356   COSTS_N_INSNS (34),   /* muldi */
00357   COSTS_N_INSNS (65),   /* divsi */
00358   COSTS_N_INSNS (67),   /* divdi */
00359   COSTS_N_INSNS (4),    /* fp */
00360   COSTS_N_INSNS (4),    /* dmul */
00361   COSTS_N_INSNS (31),   /* sdiv */
00362   COSTS_N_INSNS (31),   /* ddiv */
00363 };
00364 
00365 /* Instruction costs on MPCCORE processors.  */
00366 static const
00367 struct processor_costs mpccore_cost = {
00368   COSTS_N_INSNS (2),    /* mulsi */
00369   COSTS_N_INSNS (2),    /* mulsi_const */
00370   COSTS_N_INSNS (2),    /* mulsi_const9 */
00371   COSTS_N_INSNS (2),    /* muldi */
00372   COSTS_N_INSNS (6),    /* divsi */
00373   COSTS_N_INSNS (6),    /* divdi */
00374   COSTS_N_INSNS (4),    /* fp */
00375   COSTS_N_INSNS (5),    /* dmul */
00376   COSTS_N_INSNS (10),   /* sdiv */
00377   COSTS_N_INSNS (17),   /* ddiv */
00378 };
00379 
00380 /* Instruction costs on PPC403 processors.  */
00381 static const
00382 struct processor_costs ppc403_cost = {
00383   COSTS_N_INSNS (4),    /* mulsi */
00384   COSTS_N_INSNS (4),    /* mulsi_const */
00385   COSTS_N_INSNS (4),    /* mulsi_const9 */
00386   COSTS_N_INSNS (4),    /* muldi */
00387   COSTS_N_INSNS (33),   /* divsi */
00388   COSTS_N_INSNS (33),   /* divdi */
00389   COSTS_N_INSNS (11),   /* fp */
00390   COSTS_N_INSNS (11),   /* dmul */
00391   COSTS_N_INSNS (11),   /* sdiv */
00392   COSTS_N_INSNS (11),   /* ddiv */
00393 };
00394 
00395 /* Instruction costs on PPC405 processors.  */
00396 static const
00397 struct processor_costs ppc405_cost = {
00398   COSTS_N_INSNS (5),    /* mulsi */
00399   COSTS_N_INSNS (4),    /* mulsi_const */
00400   COSTS_N_INSNS (3),    /* mulsi_const9 */
00401   COSTS_N_INSNS (5),    /* muldi */
00402   COSTS_N_INSNS (35),   /* divsi */
00403   COSTS_N_INSNS (35),   /* divdi */
00404   COSTS_N_INSNS (11),   /* fp */
00405   COSTS_N_INSNS (11),   /* dmul */
00406   COSTS_N_INSNS (11),   /* sdiv */
00407   COSTS_N_INSNS (11),   /* ddiv */
00408 };
00409 
00410 /* Instruction costs on PPC440 processors.  */
00411 static const
00412 struct processor_costs ppc440_cost = {
00413   COSTS_N_INSNS (3),    /* mulsi */
00414   COSTS_N_INSNS (2),    /* mulsi_const */
00415   COSTS_N_INSNS (2),    /* mulsi_const9 */
00416   COSTS_N_INSNS (3),    /* muldi */
00417   COSTS_N_INSNS (34),   /* divsi */
00418   COSTS_N_INSNS (34),   /* divdi */
00419   COSTS_N_INSNS (5),    /* fp */
00420   COSTS_N_INSNS (5),    /* dmul */
00421   COSTS_N_INSNS (19),   /* sdiv */
00422   COSTS_N_INSNS (33),   /* ddiv */
00423 };
00424 
00425 /* Instruction costs on PPC601 processors.  */
00426 static const
00427 struct processor_costs ppc601_cost = {
00428   COSTS_N_INSNS (5),    /* mulsi */
00429   COSTS_N_INSNS (5),    /* mulsi_const */
00430   COSTS_N_INSNS (5),    /* mulsi_const9 */
00431   COSTS_N_INSNS (5),    /* muldi */
00432   COSTS_N_INSNS (36),   /* divsi */
00433   COSTS_N_INSNS (36),   /* divdi */
00434   COSTS_N_INSNS (4),    /* fp */
00435   COSTS_N_INSNS (5),    /* dmul */
00436   COSTS_N_INSNS (17),   /* sdiv */
00437   COSTS_N_INSNS (31),   /* ddiv */
00438 };
00439 
00440 /* Instruction costs on PPC603 processors.  */
00441 static const
00442 struct processor_costs ppc603_cost = {
00443   COSTS_N_INSNS (5),    /* mulsi */
00444   COSTS_N_INSNS (3),    /* mulsi_const */
00445   COSTS_N_INSNS (2),    /* mulsi_const9 */
00446   COSTS_N_INSNS (5),    /* muldi */
00447   COSTS_N_INSNS (37),   /* divsi */
00448   COSTS_N_INSNS (37),   /* divdi */
00449   COSTS_N_INSNS (3),    /* fp */
00450   COSTS_N_INSNS (4),    /* dmul */
00451   COSTS_N_INSNS (18),   /* sdiv */
00452   COSTS_N_INSNS (33),   /* ddiv */
00453 };
00454 
00455 /* Instruction costs on PPC604 processors.  */
00456 static const
00457 struct processor_costs ppc604_cost = {
00458   COSTS_N_INSNS (4),    /* mulsi */
00459   COSTS_N_INSNS (4),    /* mulsi_const */
00460   COSTS_N_INSNS (4),    /* mulsi_const9 */
00461   COSTS_N_INSNS (4),    /* muldi */
00462   COSTS_N_INSNS (20),   /* divsi */
00463   COSTS_N_INSNS (20),   /* divdi */
00464   COSTS_N_INSNS (3),    /* fp */
00465   COSTS_N_INSNS (3),    /* dmul */
00466   COSTS_N_INSNS (18),   /* sdiv */
00467   COSTS_N_INSNS (32),   /* ddiv */
00468 };
00469 
00470 /* Instruction costs on PPC604e processors.  */
00471 static const
00472 struct processor_costs ppc604e_cost = {
00473   COSTS_N_INSNS (2),    /* mulsi */
00474   COSTS_N_INSNS (2),    /* mulsi_const */
00475   COSTS_N_INSNS (2),    /* mulsi_const9 */
00476   COSTS_N_INSNS (2),    /* muldi */
00477   COSTS_N_INSNS (20),   /* divsi */
00478   COSTS_N_INSNS (20),   /* divdi */
00479   COSTS_N_INSNS (3),    /* fp */
00480   COSTS_N_INSNS (3),    /* dmul */
00481   COSTS_N_INSNS (18),   /* sdiv */
00482   COSTS_N_INSNS (32),   /* ddiv */
00483 };
00484 
00485 /* Instruction costs on PPC620 processors.  */
00486 static const
00487 struct processor_costs ppc620_cost = {
00488   COSTS_N_INSNS (5),    /* mulsi */
00489   COSTS_N_INSNS (4),    /* mulsi_const */
00490   COSTS_N_INSNS (3),    /* mulsi_const9 */
00491   COSTS_N_INSNS (7),    /* muldi */
00492   COSTS_N_INSNS (21),   /* divsi */
00493   COSTS_N_INSNS (37),   /* divdi */
00494   COSTS_N_INSNS (3),    /* fp */
00495   COSTS_N_INSNS (3),    /* dmul */
00496   COSTS_N_INSNS (18),   /* sdiv */
00497   COSTS_N_INSNS (32),   /* ddiv */
00498 };
00499 
00500 /* Instruction costs on PPC630 processors.  */
00501 static const
00502 struct processor_costs ppc630_cost = {
00503   COSTS_N_INSNS (5),    /* mulsi */
00504   COSTS_N_INSNS (4),    /* mulsi_const */
00505   COSTS_N_INSNS (3),    /* mulsi_const9 */
00506   COSTS_N_INSNS (7),    /* muldi */
00507   COSTS_N_INSNS (21),   /* divsi */
00508   COSTS_N_INSNS (37),   /* divdi */
00509   COSTS_N_INSNS (3),    /* fp */
00510   COSTS_N_INSNS (3),    /* dmul */
00511   COSTS_N_INSNS (17),   /* sdiv */
00512   COSTS_N_INSNS (21),   /* ddiv */
00513 };
00514 
00515 /* Instruction costs on PPC750 and PPC7400 processors.  */
00516 static const
00517 struct processor_costs ppc750_cost = {
00518   COSTS_N_INSNS (5),    /* mulsi */
00519   COSTS_N_INSNS (3),    /* mulsi_const */
00520   COSTS_N_INSNS (2),    /* mulsi_const9 */
00521   COSTS_N_INSNS (5),    /* muldi */
00522   COSTS_N_INSNS (17),   /* divsi */
00523   COSTS_N_INSNS (17),   /* divdi */
00524   COSTS_N_INSNS (3),    /* fp */
00525   COSTS_N_INSNS (3),    /* dmul */
00526   COSTS_N_INSNS (17),   /* sdiv */
00527   COSTS_N_INSNS (31),   /* ddiv */
00528 };
00529 
00530 /* Instruction costs on PPC7450 processors.  */
00531 static const
00532 struct processor_costs ppc7450_cost = {
00533   COSTS_N_INSNS (4),    /* mulsi */
00534   COSTS_N_INSNS (3),    /* mulsi_const */
00535   COSTS_N_INSNS (3),    /* mulsi_const9 */
00536   COSTS_N_INSNS (4),    /* muldi */
00537   COSTS_N_INSNS (23),   /* divsi */
00538   COSTS_N_INSNS (23),   /* divdi */
00539   COSTS_N_INSNS (5),    /* fp */
00540   COSTS_N_INSNS (5),    /* dmul */
00541   COSTS_N_INSNS (21),   /* sdiv */
00542   COSTS_N_INSNS (35),   /* ddiv */
00543 };
00544 
00545 /* Instruction costs on PPC8540 processors.  */
00546 static const
00547 struct processor_costs ppc8540_cost = {
00548   COSTS_N_INSNS (4),    /* mulsi */
00549   COSTS_N_INSNS (4),    /* mulsi_const */
00550   COSTS_N_INSNS (4),    /* mulsi_const9 */
00551   COSTS_N_INSNS (4),    /* muldi */
00552   COSTS_N_INSNS (19),   /* divsi */
00553   COSTS_N_INSNS (19),   /* divdi */
00554   COSTS_N_INSNS (4),    /* fp */
00555   COSTS_N_INSNS (4),    /* dmul */
00556   COSTS_N_INSNS (29),   /* sdiv */
00557   COSTS_N_INSNS (29),   /* ddiv */
00558 };
00559 
00560 /* Instruction costs on POWER4 and POWER5 processors.  */
00561 static const
00562 struct processor_costs power4_cost = {
00563   COSTS_N_INSNS (3),    /* mulsi */
00564   COSTS_N_INSNS (2),    /* mulsi_const */
00565   COSTS_N_INSNS (2),    /* mulsi_const9 */
00566   COSTS_N_INSNS (4),    /* muldi */
00567   COSTS_N_INSNS (18),   /* divsi */
00568   COSTS_N_INSNS (34),   /* divdi */
00569   COSTS_N_INSNS (3),    /* fp */
00570   COSTS_N_INSNS (3),    /* dmul */
00571   COSTS_N_INSNS (17),   /* sdiv */
00572   COSTS_N_INSNS (17),   /* ddiv */
00573 };
00574 
00575 
00576 static bool rs6000_function_ok_for_sibcall (tree, tree);
00577 static const char *rs6000_invalid_within_doloop (rtx);
00578 static rtx rs6000_generate_compare (enum rtx_code);
00579 static void rs6000_maybe_dead (rtx);
00580 static void rs6000_emit_stack_tie (void);
00581 static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
00582 static rtx spe_synthesize_frame_save (rtx);
00583 static bool spe_func_has_64bit_regs_p (void);
00584 static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int,
00585            int, HOST_WIDE_INT);
00586 static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
00587 static void rs6000_emit_allocate_stack (HOST_WIDE_INT, int);
00588 static unsigned rs6000_hash_constant (rtx);
00589 static unsigned toc_hash_function (const void *);
00590 static int toc_hash_eq (const void *, const void *);
00591 static int constant_pool_expr_1 (rtx, int *, int *);
00592 static bool constant_pool_expr_p (rtx);
00593 static bool legitimate_small_data_p (enum machine_mode, rtx);
00594 static bool legitimate_indexed_address_p (rtx, int);
00595 static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
00596 static struct machine_function * rs6000_init_machine_status (void);
00597 static bool rs6000_assemble_integer (rtx, unsigned int, int);
00598 static bool no_global_regs_above (int);
00599 #ifdef HAVE_GAS_HIDDEN
00600 static void rs6000_assemble_visibility (tree, int);
00601 #endif
00602 static int rs6000_ra_ever_killed (void);
00603 static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
00604 static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
00605 static bool rs6000_ms_bitfield_layout_p (tree);
00606 static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *);
00607 static void rs6000_eliminate_indexed_memrefs (rtx operands[2]);
00608 static const char *rs6000_mangle_fundamental_type (tree);
00609 extern const struct attribute_spec rs6000_attribute_table[];
00610 static void rs6000_set_default_type_attributes (tree);
00611 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
00612 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
00613 static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
00614             tree);
00615 static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
00616 static bool rs6000_return_in_memory (tree, tree);
00617 static void rs6000_file_start (void);
00618 #if TARGET_ELF
00619 static int rs6000_elf_reloc_rw_mask (void);
00620 static void rs6000_elf_asm_out_constructor (rtx, int);
00621 static void rs6000_elf_asm_out_destructor (rtx, int);
00622 static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED;
00623 static void rs6000_elf_asm_init_sections (void);
00624 static section *rs6000_elf_select_rtx_section (enum machine_mode, rtx,
00625                  unsigned HOST_WIDE_INT);
00626 static void rs6000_elf_encode_section_info (tree, rtx, int)
00627      ATTRIBUTE_UNUSED;
00628 #endif
00629 static bool rs6000_use_blocks_for_constant_p (enum machine_mode, rtx);
00630 #if TARGET_XCOFF
00631 static void rs6000_xcoff_asm_output_anchor (rtx);
00632 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
00633 static void rs6000_xcoff_asm_init_sections (void);
00634 static int rs6000_xcoff_reloc_rw_mask (void);
00635 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree);
00636 static section *rs6000_xcoff_select_section (tree, int,
00637                unsigned HOST_WIDE_INT);
00638 static void rs6000_xcoff_unique_section (tree, int);
00639 static section *rs6000_xcoff_select_rtx_section
00640   (enum machine_mode, rtx, unsigned HOST_WIDE_INT);
00641 static const char * rs6000_xcoff_strip_name_encoding (const char *);
00642 static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
00643 static void rs6000_xcoff_file_start (void);
00644 static void rs6000_xcoff_file_end (void);
00645 #endif
00646 static int rs6000_variable_issue (FILE *, int, rtx, int);
00647 static bool rs6000_rtx_costs (rtx, int, int, int *);
00648 static int rs6000_adjust_cost (rtx, rtx, rtx, int);
00649 static bool is_microcoded_insn (rtx);
00650 static int is_dispatch_slot_restricted (rtx);
00651 static bool is_cracked_insn (rtx);
00652 static bool is_branch_slot_insn (rtx);
00653 static int rs6000_adjust_priority (rtx, int);
00654 static int rs6000_issue_rate (void);
00655 static bool rs6000_is_costly_dependence (rtx, rtx, rtx, int, int);
00656 static rtx get_next_active_insn (rtx, rtx);
00657 static bool insn_terminates_group_p (rtx , enum group_termination);
00658 static bool is_costly_group (rtx *, rtx);
00659 static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
00660 static int redefine_groups (FILE *, int, rtx, rtx);
00661 static int pad_groups (FILE *, int, rtx, rtx);
00662 static void rs6000_sched_finish (FILE *, int);
00663 static int rs6000_use_sched_lookahead (void);
00664 static tree rs6000_builtin_mask_for_load (void);
00665 
00666 static void def_builtin (int, const char *, tree, int);
00667 static void rs6000_init_builtins (void);
00668 static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
00669 static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
00670 static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
00671 static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
00672 static void altivec_init_builtins (void);
00673 static void rs6000_common_init_builtins (void);
00674 static void rs6000_init_libfuncs (void);
00675 
00676 static void enable_mask_for_builtins (struct builtin_description *, int,
00677               enum rs6000_builtins,
00678               enum rs6000_builtins);
00679 static tree build_opaque_vector_type (tree, int);
00680 static void spe_init_builtins (void);
00681 static rtx spe_expand_builtin (tree, rtx, bool *);
00682 static rtx spe_expand_stv_builtin (enum insn_code, tree);
00683 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
00684 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
00685 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
00686 static rs6000_stack_t *rs6000_stack_info (void);
00687 static void debug_stack_info (rs6000_stack_t *);
00688 
00689 static rtx altivec_expand_builtin (tree, rtx, bool *);
00690 static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
00691 static rtx altivec_expand_st_builtin (tree, rtx, bool *);
00692 static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
00693 static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
00694 static rtx altivec_expand_predicate_builtin (enum insn_code,
00695                const char *, tree, rtx);
00696 static rtx altivec_expand_lv_builtin (enum insn_code, tree, rtx);
00697 static rtx altivec_expand_stv_builtin (enum insn_code, tree);
00698 static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
00699 static rtx altivec_expand_vec_set_builtin (tree);
00700 static rtx altivec_expand_vec_ext_builtin (tree, rtx);
00701 static int get_element_number (tree, tree);
00702 static bool rs6000_handle_option (size_t, const char *, int);
00703 static void rs6000_parse_tls_size_option (void);
00704 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
00705 static int first_altivec_reg_to_save (void);
00706 static unsigned int compute_vrsave_mask (void);
00707 static void compute_save_world_info (rs6000_stack_t *info_ptr);
00708 static void is_altivec_return_reg (rtx, void *);
00709 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
00710 int easy_vector_constant (rtx, enum machine_mode);
00711 static bool rs6000_is_opaque_type (tree);
00712 static rtx rs6000_dwarf_register_span (rtx);
00713 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
00714 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
00715 static rtx rs6000_tls_get_addr (void);
00716 static rtx rs6000_got_sym (void);
00717 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
00718 static const char *rs6000_get_some_local_dynamic_name (void);
00719 static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
00720 static rtx rs6000_complex_function_value (enum machine_mode);
00721 static rtx rs6000_spe_function_arg (CUMULATIVE_ARGS *,
00722             enum machine_mode, tree);
00723 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
00724                   HOST_WIDE_INT);
00725 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
00726               tree, HOST_WIDE_INT);
00727 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
00728                 HOST_WIDE_INT,
00729                 rtx[], int *);
00730 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
00731                  tree, HOST_WIDE_INT,
00732                  rtx[], int *);
00733 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, tree, int, bool);
00734 static rtx rs6000_mixed_function_arg (enum machine_mode, tree, int);
00735 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
00736 static void setup_incoming_varargs (CUMULATIVE_ARGS *,
00737             enum machine_mode, tree,
00738             int *, int);
00739 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
00740               tree, bool);
00741 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
00742              tree, bool);
00743 static const char *invalid_arg_for_unprototyped_fn (tree, tree, tree);
00744 #if TARGET_MACHO
00745 static void macho_branch_islands (void);
00746 static int no_previous_def (tree function_name);
00747 static tree get_prev_label (tree function_name);
00748 static void rs6000_darwin_file_start (void);
00749 #endif
00750 
00751 static tree rs6000_build_builtin_va_list (void);
00752 static tree rs6000_gimplify_va_arg (tree, tree, tree *, tree *);
00753 static bool rs6000_must_pass_in_stack (enum machine_mode, tree);
00754 static bool rs6000_scalar_mode_supported_p (enum machine_mode);
00755 static bool rs6000_vector_mode_supported_p (enum machine_mode);
00756 static int get_vec_cmp_insn (enum rtx_code, enum machine_mode,
00757            enum machine_mode);
00758 static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
00759                enum machine_mode);
00760 static int get_vsel_insn (enum machine_mode);
00761 static void rs6000_emit_vector_select (rtx, rtx, rtx, rtx);
00762 static tree rs6000_stack_protect_fail (void);
00763 
00764 const int INSN_NOT_AVAILABLE = -1;
00765 static enum machine_mode rs6000_eh_return_filter_mode (void);
00766 
00767 /* Hash table stuff for keeping track of TOC entries.  */
00768 
00769 struct toc_hash_struct GTY(())
00770 {
00771   /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
00772      ASM_OUTPUT_SPECIAL_POOL_ENTRY_P.  */
00773   rtx key;
00774   enum machine_mode key_mode;
00775   int labelno;
00776 };
00777 
00778 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
00779 
00780 /* Default register names.  */
00781 char rs6000_reg_names[][8] =
00782 {
00783       "0",  "1",  "2",  "3",  "4",  "5",  "6",  "7",
00784       "8",  "9", "10", "11", "12", "13", "14", "15",
00785      "16", "17", "18", "19", "20", "21", "22", "23",
00786      "24", "25", "26", "27", "28", "29", "30", "31",
00787       "0",  "1",  "2",  "3",  "4",  "5",  "6",  "7",
00788       "8",  "9", "10", "11", "12", "13", "14", "15",
00789      "16", "17", "18", "19", "20", "21", "22", "23",
00790      "24", "25", "26", "27", "28", "29", "30", "31",
00791      "mq", "lr", "ctr","ap",
00792       "0",  "1",  "2",  "3",  "4",  "5",  "6",  "7",
00793       "xer",
00794       /* AltiVec registers.  */
00795       "0",  "1",  "2",  "3",  "4",  "5",  "6", "7",
00796       "8",  "9",  "10", "11", "12", "13", "14", "15",
00797       "16", "17", "18", "19", "20", "21", "22", "23",
00798       "24", "25", "26", "27", "28", "29", "30", "31",
00799       "vrsave", "vscr",
00800       /* SPE registers.  */
00801       "spe_acc", "spefscr",
00802       /* Soft frame pointer.  */
00803       "sfp"
00804 };
00805 
00806 #ifdef TARGET_REGNAMES
00807 static const char alt_reg_names[][8] =
00808 {
00809    "%r0",   "%r1",  "%r2",  "%r3",  "%r4",  "%r5",  "%r6",  "%r7",
00810    "%r8",   "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
00811   "%r16",  "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
00812   "%r24",  "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
00813    "%f0",   "%f1",  "%f2",  "%f3",  "%f4",  "%f5",  "%f6",  "%f7",
00814    "%f8",   "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
00815   "%f16",  "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
00816   "%f24",  "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
00817     "mq",    "lr",  "ctr",   "ap",
00818   "%cr0",  "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
00819    "xer",
00820   /* AltiVec registers.  */
00821    "%v0",  "%v1",  "%v2",  "%v3",  "%v4",  "%v5",  "%v6", "%v7",
00822    "%v8",  "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
00823   "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
00824   "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
00825   "vrsave", "vscr",
00826   /* SPE registers.  */
00827   "spe_acc", "spefscr",
00828   /* Soft frame pointer.  */
00829   "sfp"
00830 };
00831 #endif
00832 
00833 #ifndef MASK_STRICT_ALIGN
00834 #define MASK_STRICT_ALIGN 0
00835 #endif
00836 #ifndef TARGET_PROFILE_KERNEL
00837 #define TARGET_PROFILE_KERNEL 0
00838 #endif
00839 
00840 /* The VRSAVE bitmask puts bit %v0 as the most significant bit.  */
00841 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
00842 
00843 /* Initialize the GCC target structure.  */
00844 #undef TARGET_ATTRIBUTE_TABLE
00845 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
00846 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
00847 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
00848 
00849 #undef TARGET_ASM_ALIGNED_DI_OP
00850 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
00851 
00852 /* Default unaligned ops are only provided for ELF.  Find the ops needed
00853    for non-ELF systems.  */
00854 #ifndef OBJECT_FORMAT_ELF
00855 #if TARGET_XCOFF
00856 /* For XCOFF.  rs6000_assemble_integer will handle unaligned DIs on
00857    64-bit targets.  */
00858 #undef TARGET_ASM_UNALIGNED_HI_OP
00859 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
00860 #undef TARGET_ASM_UNALIGNED_SI_OP
00861 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
00862 #undef TARGET_ASM_UNALIGNED_DI_OP
00863 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
00864 #else
00865 /* For Darwin.  */
00866 #undef TARGET_ASM_UNALIGNED_HI_OP
00867 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
00868 #undef TARGET_ASM_UNALIGNED_SI_OP
00869 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
00870 #undef TARGET_ASM_UNALIGNED_DI_OP
00871 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
00872 #undef TARGET_ASM_ALIGNED_DI_OP
00873 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
00874 #endif
00875 #endif
00876 
00877 /* This hook deals with fixups for relocatable code and DI-mode objects
00878    in 64-bit code.  */
00879 #undef TARGET_ASM_INTEGER
00880 #define TARGET_ASM_INTEGER rs6000_assemble_integer
00881 
00882 #ifdef HAVE_GAS_HIDDEN
00883 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
00884 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
00885 #endif
00886 
00887 #undef TARGET_HAVE_TLS
00888 #define TARGET_HAVE_TLS HAVE_AS_TLS
00889 
00890 #undef TARGET_CANNOT_FORCE_CONST_MEM
00891 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
00892 
00893 #undef TARGET_ASM_FUNCTION_PROLOGUE
00894 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
00895 #undef TARGET_ASM_FUNCTION_EPILOGUE
00896 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
00897 
00898 #undef  TARGET_SCHED_VARIABLE_ISSUE
00899 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
00900 
00901 #undef TARGET_SCHED_ISSUE_RATE
00902 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
00903 #undef TARGET_SCHED_ADJUST_COST
00904 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
00905 #undef TARGET_SCHED_ADJUST_PRIORITY
00906 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
00907 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
00908 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
00909 #undef TARGET_SCHED_FINISH
00910 #define TARGET_SCHED_FINISH rs6000_sched_finish
00911 
00912 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
00913 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
00914 
00915 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
00916 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
00917 
00918 #undef TARGET_INIT_BUILTINS
00919 #define TARGET_INIT_BUILTINS rs6000_init_builtins
00920 
00921 #undef TARGET_EXPAND_BUILTIN
00922 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
00923 
00924 #undef TARGET_MANGLE_FUNDAMENTAL_TYPE
00925 #define TARGET_MANGLE_FUNDAMENTAL_TYPE rs6000_mangle_fundamental_type
00926 
00927 #undef TARGET_INIT_LIBFUNCS
00928 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
00929 
00930 #if TARGET_MACHO
00931 #undef TARGET_BINDS_LOCAL_P
00932 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
00933 #endif
00934 
00935 #undef TARGET_MS_BITFIELD_LAYOUT_P
00936 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
00937 
00938 #undef TARGET_ASM_OUTPUT_MI_THUNK
00939 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
00940 
00941 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
00942 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
00943 
00944 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
00945 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
00946 
00947 #undef TARGET_INVALID_WITHIN_DOLOOP
00948 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
00949 
00950 #undef TARGET_RTX_COSTS
00951 #define TARGET_RTX_COSTS rs6000_rtx_costs
00952 #undef TARGET_ADDRESS_COST
00953 #define TARGET_ADDRESS_COST hook_int_rtx_0
00954 
00955 #undef TARGET_VECTOR_OPAQUE_P
00956 #define TARGET_VECTOR_OPAQUE_P rs6000_is_opaque_type
00957 
00958 #undef TARGET_DWARF_REGISTER_SPAN
00959 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
00960 
00961 /* On rs6000, function arguments are promoted, as are function return
00962    values.  */
00963 #undef TARGET_PROMOTE_FUNCTION_ARGS
00964 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
00965 #undef TARGET_PROMOTE_FUNCTION_RETURN
00966 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
00967 
00968 #undef TARGET_RETURN_IN_MEMORY
00969 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
00970 
00971 #undef TARGET_SETUP_INCOMING_VARARGS
00972 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
00973 
00974 /* Always strict argument naming on rs6000.  */
00975 #undef TARGET_STRICT_ARGUMENT_NAMING
00976 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
00977 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
00978 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
00979 #undef TARGET_SPLIT_COMPLEX_ARG
00980 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_tree_true
00981 #undef TARGET_MUST_PASS_IN_STACK
00982 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
00983 #undef TARGET_PASS_BY_REFERENCE
00984 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
00985 #undef TARGET_ARG_PARTIAL_BYTES
00986 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
00987 
00988 #undef TARGET_BUILD_BUILTIN_VA_LIST
00989 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
00990 
00991 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
00992 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
00993 
00994 #undef TARGET_EH_RETURN_FILTER_MODE
00995 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
00996 
00997 #undef TARGET_SCALAR_MODE_SUPPORTED_P
00998 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
00999 
01000 #undef TARGET_VECTOR_MODE_SUPPORTED_P
01001 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
01002 
01003 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
01004 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
01005 
01006 #undef TARGET_HANDLE_OPTION
01007 #define TARGET_HANDLE_OPTION rs6000_handle_option
01008 
01009 #undef TARGET_DEFAULT_TARGET_FLAGS
01010 #define TARGET_DEFAULT_TARGET_FLAGS \
01011   (TARGET_DEFAULT)
01012 
01013 #undef TARGET_STACK_PROTECT_FAIL
01014 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
01015 
01016 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
01017    The PowerPC architecture requires only weak consistency among
01018    processors--that is, memory accesses between processors need not be
01019    sequentially consistent and memory accesses among processors can occur
01020    in any order. The ability to order memory accesses weakly provides
01021    opportunities for more efficient use of the system bus. Unless a
01022    dependency exists, the 604e allows read operations to precede store
01023    operations.  */
01024 #undef TARGET_RELAXED_ORDERING
01025 #define TARGET_RELAXED_ORDERING true
01026 
01027 #ifdef HAVE_AS_TLS
01028 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
01029 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
01030 #endif
01031 
01032 /* Use a 32-bit anchor range.  This leads to sequences like:
01033 
01034   addis tmp,anchor,high
01035   add dest,tmp,low
01036 
01037    where tmp itself acts as an anchor, and can be shared between
01038    accesses to the same 64k page.  */
01039 #undef TARGET_MIN_ANCHOR_OFFSET
01040 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
01041 #undef TARGET_MAX_ANCHOR_OFFSET
01042 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
01043 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
01044 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
01045 
01046 struct gcc_target targetm = TARGET_INITIALIZER;
01047 
01048 
01049 /* Value is 1 if hard register REGNO can hold a value of machine-mode
01050    MODE.  */
01051 static int
01052 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
01053 {
01054   /* The GPRs can hold any mode, but values bigger than one register
01055      cannot go past R31.  */
01056   if (INT_REGNO_P (regno))
01057     return INT_REGNO_P (regno + HARD_REGNO_NREGS (regno, mode) - 1);
01058 
01059   /* The float registers can only hold floating modes and DImode.
01060      This also excludes decimal float modes.  */
01061   if (FP_REGNO_P (regno))
01062     return
01063       (SCALAR_FLOAT_MODE_P (mode)
01064        && !DECIMAL_FLOAT_MODE_P (mode)
01065        && FP_REGNO_P (regno + HARD_REGNO_NREGS (regno, mode) - 1))
01066       || (GET_MODE_CLASS (mode) == MODE_INT
01067     && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD);
01068 
01069   /* The CR register can only hold CC modes.  */
01070   if (CR_REGNO_P (regno))
01071     return GET_MODE_CLASS (mode) == MODE_CC;
01072 
01073   if (XER_REGNO_P (regno))
01074     return mode == PSImode;
01075 
01076   /* AltiVec only in AldyVec registers.  */
01077   if (ALTIVEC_REGNO_P (regno))
01078     return ALTIVEC_VECTOR_MODE (mode);
01079 
01080   /* ...but GPRs can hold SIMD data on the SPE in one register.  */
01081   if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
01082     return 1;
01083 
01084   /* We cannot put TImode anywhere except general register and it must be
01085      able to fit within the register set.  */
01086 
01087   return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
01088 }
01089 
01090 /* Initialize rs6000_hard_regno_mode_ok_p table.  */
01091 static void
01092 rs6000_init_hard_regno_mode_ok (void)
01093 {
01094   int r, m;
01095 
01096   for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
01097     for (m = 0; m < NUM_MACHINE_MODES; ++m)
01098       if (rs6000_hard_regno_mode_ok (r, m))
01099   rs6000_hard_regno_mode_ok_p[m][r] = true;
01100 }
01101 
01102 /* If not otherwise specified by a target, make 'long double' equivalent to
01103    'double'.  */
01104 
01105 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
01106 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
01107 #endif
01108 
01109 /* Override command line options.  Mostly we process the processor
01110    type and sometimes adjust other TARGET_ options.  */
01111 
01112 void
01113 rs6000_override_options (const char *default_cpu)
01114 {
01115   size_t i, j;
01116   struct rs6000_cpu_select *ptr;
01117   int set_masks;
01118 
01119   /* Simplifications for entries below.  */
01120 
01121   enum {
01122     POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
01123     POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
01124   };
01125 
01126   /* This table occasionally claims that a processor does not support
01127      a particular feature even though it does, but the feature is slower
01128      than the alternative.  Thus, it shouldn't be relied on as a
01129      complete description of the processor's support.
01130 
01131      Please keep this list in order, and don't forget to update the
01132      documentation in invoke.texi when adding a new processor or
01133      flag.  */
01134   static struct ptt
01135     {
01136       const char *const name;   /* Canonical processor name.  */
01137       const enum processor_type processor; /* Processor type enum value.  */
01138       const int target_enable;  /* Target flags to enable.  */
01139     } const processor_target_table[]
01140       = {{"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
01141    {"403", PROCESSOR_PPC403,
01142     POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
01143    {"405", PROCESSOR_PPC405,
01144     POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
01145    {"405fp", PROCESSOR_PPC405,
01146     POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
01147    {"440", PROCESSOR_PPC440,
01148     POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
01149    {"440fp", PROCESSOR_PPC440,
01150     POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
01151    {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
01152    {"601", PROCESSOR_PPC601,
01153     MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
01154    {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
01155    {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
01156    {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
01157    {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
01158    {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
01159    {"620", PROCESSOR_PPC620,
01160     POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
01161    {"630", PROCESSOR_PPC630,
01162     POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
01163    {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
01164    {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
01165    {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
01166    {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
01167    {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
01168    {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
01169    {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
01170    {"8540", PROCESSOR_PPC8540,
01171     POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_STRICT_ALIGN},
01172    /* 8548 has a dummy entry for now.  */
01173    {"8548", PROCESSOR_PPC8540,
01174     POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_STRICT_ALIGN},
01175    {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
01176    {"970", PROCESSOR_POWER4,
01177     POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
01178    {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
01179    {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
01180    {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
01181    {"G4",  PROCESSOR_PPC7450, POWERPC_7400_MASK},
01182    {"G5", PROCESSOR_POWER4,
01183     POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
01184    {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
01185    {"power2", PROCESSOR_POWER,
01186     MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
01187    {"power3", PROCESSOR_PPC630,
01188     POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
01189    {"power4", PROCESSOR_POWER4,
01190     POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POWERPC64},
01191    {"power5", PROCESSOR_POWER5,
01192     POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GFXOPT
01193     | MASK_MFCRF | MASK_POPCNTB},
01194    {"power5+", PROCESSOR_POWER5,
01195     POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GFXOPT
01196     | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
01197    {"power6", PROCESSOR_POWER5,
01198     POWERPC_7400_MASK | MASK_POWERPC64 | MASK_MFCRF | MASK_POPCNTB
01199     | MASK_FPRND},
01200    {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
01201    {"powerpc64", PROCESSOR_POWERPC64,
01202     POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
01203    {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
01204    {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
01205    {"rios2", PROCESSOR_RIOS2,
01206     MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
01207    {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
01208    {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
01209    {"rs64", PROCESSOR_RS64A,
01210     POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
01211       };
01212 
01213   const size_t ptt_size = ARRAY_SIZE (processor_target_table);
01214 
01215   /* Some OSs don't support saving the high part of 64-bit registers on
01216      context switch.  Other OSs don't support saving Altivec registers.
01217      On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
01218      settings; if the user wants either, the user must explicitly specify
01219      them and we won't interfere with the user's specification.  */
01220 
01221   enum {
01222     POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
01223     POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
01224          | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
01225          | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
01226          | MASK_DLMZB)
01227   };
01228 
01229   rs6000_init_hard_regno_mode_ok ();
01230 
01231   set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
01232 #ifdef OS_MISSING_POWERPC64
01233   if (OS_MISSING_POWERPC64)
01234     set_masks &= ~MASK_POWERPC64;
01235 #endif
01236 #ifdef OS_MISSING_ALTIVEC
01237   if (OS_MISSING_ALTIVEC)
01238     set_masks &= ~MASK_ALTIVEC;
01239 #endif
01240 
01241   /* Don't override by the processor default if given explicitly.  */
01242   set_masks &= ~target_flags_explicit;
01243 
01244   /* Identify the processor type.  */
01245   rs6000_select[0].string = default_cpu;
01246   rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
01247 
01248   for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
01249     {
01250       ptr = &rs6000_select[i];
01251       if (ptr->string != (char *)0 && ptr->string[0] != '\0')
01252   {
01253     for (j = 0; j < ptt_size; j++)
01254       if (! strcmp (ptr->string, processor_target_table[j].name))
01255         {
01256     if (ptr->set_tune_p)
01257       rs6000_cpu = processor_target_table[j].processor;
01258 
01259     if (ptr->set_arch_p)
01260       {
01261         target_flags &= ~set_masks;
01262         target_flags |= (processor_target_table[j].target_enable
01263              & set_masks);
01264       }
01265     break;
01266         }
01267 
01268     if (j == ptt_size)
01269       error ("bad value (%s) for %s switch", ptr->string, ptr->name);
01270   }
01271     }
01272 
01273   if (TARGET_E500)
01274     rs6000_isel = 1;
01275 
01276   /* If we are optimizing big endian systems for space, use the load/store
01277      multiple and string instructions.  */
01278   if (BYTES_BIG_ENDIAN && optimize_size)
01279     target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
01280 
01281   /* Don't allow -mmultiple or -mstring on little endian systems
01282      unless the cpu is a 750, because the hardware doesn't support the
01283      instructions used in little endian mode, and causes an alignment
01284      trap.  The 750 does not cause an alignment trap (except when the
01285      target is unaligned).  */
01286 
01287   if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
01288     {
01289       if (TARGET_MULTIPLE)
01290   {
01291     target_flags &= ~MASK_MULTIPLE;
01292     if ((target_flags_explicit & MASK_MULTIPLE) != 0)
01293       warning (0, "-mmultiple is not supported on little endian systems");
01294   }
01295 
01296       if (TARGET_STRING)
01297   {
01298     target_flags &= ~MASK_STRING;
01299     if ((target_flags_explicit & MASK_STRING) != 0)
01300       warning (0, "-mstring is not supported on little endian systems");
01301   }
01302     }
01303 
01304   /* Set debug flags */
01305   if (rs6000_debug_name)
01306     {
01307       if (! strcmp (rs6000_debug_name, "all"))
01308   rs6000_debug_stack = rs6000_debug_arg = 1;
01309       else if (! strcmp (rs6000_debug_name, "stack"))
01310   rs6000_debug_stack = 1;
01311       else if (! strcmp (rs6000_debug_name, "arg"))
01312   rs6000_debug_arg = 1;
01313       else
01314   error ("unknown -mdebug-%s switch", rs6000_debug_name);
01315     }
01316 
01317   if (rs6000_traceback_name)
01318     {
01319       if (! strncmp (rs6000_traceback_name, "full", 4))
01320   rs6000_traceback = traceback_full;
01321       else if (! strncmp (rs6000_traceback_name, "part", 4))
01322   rs6000_traceback = traceback_part;
01323       else if (! strncmp (rs6000_traceback_name, "no", 2))
01324   rs6000_traceback = traceback_none;
01325       else
01326   error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
01327          rs6000_traceback_name);
01328     }
01329 
01330   if (!rs6000_explicit_options.long_double)
01331     rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
01332 
01333 #ifndef POWERPC_LINUX
01334   if (!rs6000_explicit_options.ieee)
01335     rs6000_ieeequad = 1;
01336 #endif
01337 
01338   /* Set Altivec ABI as default for powerpc64 linux.  */
01339   if (TARGET_ELF && TARGET_64BIT)
01340     {
01341       rs6000_altivec_abi = 1;
01342       TARGET_ALTIVEC_VRSAVE = 1;
01343     }
01344 
01345   /* Set the Darwin64 ABI as default for 64-bit Darwin.  */
01346   if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
01347     {
01348       rs6000_darwin64_abi = 1;
01349 #if TARGET_MACHO
01350       darwin_one_byte_bool = 1;
01351 #endif
01352       /* Default to natural alignment, for better performance.  */
01353       rs6000_alignment_flags = MASK_ALIGN_NATURAL;
01354     }
01355 
01356   /* Place FP constants in the constant pool instead of TOC
01357      if section anchors enabled.  */
01358   if (flag_section_anchors)
01359     TARGET_NO_FP_IN_TOC = 1;
01360 
01361   /* Handle -mtls-size option.  */
01362   rs6000_parse_tls_size_option ();
01363 
01364 #ifdef SUBTARGET_OVERRIDE_OPTIONS
01365   SUBTARGET_OVERRIDE_OPTIONS;
01366 #endif
01367 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
01368   SUBSUBTARGET_OVERRIDE_OPTIONS;
01369 #endif
01370 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
01371   SUB3TARGET_OVERRIDE_OPTIONS;
01372 #endif
01373 
01374   if (TARGET_E500)
01375     {
01376       if (TARGET_ALTIVEC)
01377   error ("AltiVec and E500 instructions cannot coexist");
01378 
01379       /* The e500 does not have string instructions, and we set
01380    MASK_STRING above when optimizing for size.  */
01381       if ((target_flags & MASK_STRING) != 0)
01382   target_flags = target_flags & ~MASK_STRING;
01383     }
01384   else if (rs6000_select[1].string != NULL)
01385     {
01386       /* For the powerpc-eabispe configuration, we set all these by
01387    default, so let's unset them if we manually set another
01388    CPU that is not the E500.  */
01389       if (!rs6000_explicit_options.abi)
01390   rs6000_spe_abi = 0;
01391       if (!rs6000_explicit_options.spe)
01392   rs6000_spe = 0;
01393       if (!rs6000_explicit_options.float_gprs)
01394   rs6000_float_gprs = 0;
01395       if (!rs6000_explicit_options.isel)
01396   rs6000_isel = 0;
01397       if (!rs6000_explicit_options.long_double)
01398   rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
01399     }
01400 
01401   rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
01402       && rs6000_cpu != PROCESSOR_POWER5);
01403   rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
01404        || rs6000_cpu == PROCESSOR_POWER5);
01405 
01406   rs6000_sched_restricted_insns_priority
01407     = (rs6000_sched_groups ? 1 : 0);
01408 
01409   /* Handle -msched-costly-dep option.  */
01410   rs6000_sched_costly_dep
01411     = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
01412 
01413   if (rs6000_sched_costly_dep_str)
01414     {
01415       if (! strcmp (rs6000_sched_costly_dep_str, "no"))
01416   rs6000_sched_costly_dep = no_dep_costly;
01417       else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
01418   rs6000_sched_costly_dep = all_deps_costly;
01419       else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
01420   rs6000_sched_costly_dep = true_store_to_load_dep_costly;
01421       else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
01422   rs6000_sched_costly_dep = store_to_load_dep_costly;
01423       else
01424   rs6000_sched_costly_dep = atoi (rs6000_sched_costly_dep_str);
01425     }
01426 
01427   /* Handle -minsert-sched-nops option.  */
01428   rs6000_sched_insert_nops
01429     = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
01430 
01431   if (rs6000_sched_insert_nops_str)
01432     {
01433       if (! strcmp (rs6000_sched_insert_nops_str, "no"))
01434   rs6000_sched_insert_nops = sched_finish_none;
01435       else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
01436   rs6000_sched_insert_nops = sched_finish_pad_groups;
01437       else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
01438   rs6000_sched_insert_nops = sched_finish_regroup_exact;
01439       else
01440   rs6000_sched_insert_nops = atoi (rs6000_sched_insert_nops_str);
01441     }
01442 
01443 #ifdef TARGET_REGNAMES
01444   /* If the user desires alternate register names, copy in the
01445      alternate names now.  */
01446   if (TARGET_REGNAMES)
01447     memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
01448 #endif
01449 
01450   /* Set aix_struct_return last, after the ABI is determined.
01451      If -maix-struct-return or -msvr4-struct-return was explicitly
01452      used, don't override with the ABI default.  */
01453   if (!rs6000_explicit_options.aix_struct_ret)
01454     aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
01455 
01456   if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
01457     REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
01458 
01459   if (TARGET_TOC)
01460     ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
01461 
01462   /* We can only guarantee the availability of DI pseudo-ops when
01463      assembling for 64-bit targets.  */
01464   if (!TARGET_64BIT)
01465     {
01466       targetm.asm_out.aligned_op.di = NULL;
01467       targetm.asm_out.unaligned_op.di = NULL;
01468     }
01469 
01470   /* Set branch target alignment, if not optimizing for size.  */
01471   if (!optimize_size)
01472     {
01473       if (rs6000_sched_groups)
01474   {
01475     if (align_functions <= 0)
01476       align_functions = 16;
01477     if (align_jumps <= 0)
01478       align_jumps = 16;
01479     if (align_loops <= 0)
01480       align_loops = 16;
01481   }
01482       if (align_jumps_max_skip <= 0)
01483   align_jumps_max_skip = 15;
01484       if (align_loops_max_skip <= 0)
01485   align_loops_max_skip = 15;
01486     }
01487 
01488   /* Arrange to save and restore machine status around nested functions.  */
01489   init_machine_status = rs6000_init_machine_status;
01490 
01491   /* We should always be splitting complex arguments, but we can't break
01492      Linux and Darwin ABIs at the moment.  For now, only AIX is fixed.  */
01493   if (DEFAULT_ABI != ABI_AIX)
01494     targetm.calls.split_complex_arg = NULL;
01495 
01496   /* Initialize rs6000_cost with the appropriate target costs.  */
01497   if (optimize_size)
01498     rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
01499   else
01500     switch (rs6000_cpu)
01501       {
01502       case PROCESSOR_RIOS1:
01503   rs6000_cost = &rios1_cost;
01504   break;
01505 
01506       case PROCESSOR_RIOS2:
01507   rs6000_cost = &rios2_cost;
01508   break;
01509 
01510       case PROCESSOR_RS64A:
01511   rs6000_cost = &rs64a_cost;
01512   break;
01513 
01514       case PROCESSOR_MPCCORE:
01515   rs6000_cost = &mpccore_cost;
01516   break;
01517 
01518       case PROCESSOR_PPC403:
01519   rs6000_cost = &ppc403_cost;
01520   break;
01521 
01522       case PROCESSOR_PPC405:
01523   rs6000_cost = &ppc405_cost;
01524   break;
01525 
01526       case PROCESSOR_PPC440:
01527   rs6000_cost = &ppc440_cost;
01528   break;
01529 
01530       case PROCESSOR_PPC601:
01531   rs6000_cost = &ppc601_cost;
01532   break;
01533 
01534       case PROCESSOR_PPC603:
01535   rs6000_cost = &ppc603_cost;
01536   break;
01537 
01538       case PROCESSOR_PPC604:
01539   rs6000_cost = &ppc604_cost;
01540   break;
01541 
01542       case PROCESSOR_PPC604e:
01543   rs6000_cost = &ppc604e_cost;
01544   break;
01545 
01546       case PROCESSOR_PPC620:
01547   rs6000_cost = &ppc620_cost;
01548   break;
01549 
01550       case PROCESSOR_PPC630:
01551   rs6000_cost = &ppc630_cost;
01552   break;
01553 
01554       case PROCESSOR_PPC750:
01555       case PROCESSOR_PPC7400:
01556   rs6000_cost = &ppc750_cost;
01557   break;
01558 
01559       case PROCESSOR_PPC7450:
01560   rs6000_cost = &ppc7450_cost;
01561   break;
01562 
01563       case PROCESSOR_PPC8540:
01564   rs6000_cost = &ppc8540_cost;
01565   break;
01566 
01567       case PROCESSOR_POWER4:
01568       case PROCESSOR_POWER5:
01569   rs6000_cost = &power4_cost;
01570   break;
01571 
01572       default:
01573   gcc_unreachable ();
01574       }
01575 }
01576 
01577 /* Implement targetm.vectorize.builtin_mask_for_load.  */
01578 static tree
01579 rs6000_builtin_mask_for_load (void)
01580 {
01581   if (TARGET_ALTIVEC)
01582     return altivec_builtin_mask_for_load;
01583   else
01584     return 0;
01585 }
01586 
01587 /* Handle generic options of the form -mfoo=yes/no.
01588    NAME is the option name.
01589    VALUE is the option value.
01590    FLAG is the pointer to the flag where to store a 1 or 0, depending on
01591    whether the option value is 'yes' or 'no' respectively.  */
01592 static void
01593 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
01594 {
01595   if (value == 0)
01596     return;
01597   else if (!strcmp (value, "yes"))
01598     *flag = 1;
01599   else if (!strcmp (value, "no"))
01600     *flag = 0;
01601   else
01602     error ("unknown -m%s= option specified: '%s'", name, value);
01603 }
01604 
01605 /* Validate and record the size specified with the -mtls-size option.  */
01606 
01607 static void
01608 rs6000_parse_tls_size_option (void)
01609 {
01610   if (rs6000_tls_size_string == 0)
01611     return;
01612   else if (strcmp (rs6000_tls_size_string, "16") == 0)
01613     rs6000_tls_size = 16;
01614   else if (strcmp (rs6000_tls_size_string, "32") == 0)
01615     rs6000_tls_size = 32;
01616   else if (strcmp (rs6000_tls_size_string, "64") == 0)
01617     rs6000_tls_size = 64;
01618   else
01619     error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string);
01620 }
01621 
01622 void
01623 optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
01624 {
01625   if (DEFAULT_ABI == ABI_DARWIN)
01626     /* The Darwin libraries never set errno, so we might as well
01627        avoid calling them when that's the only reason we would.  */
01628     flag_errno_math = 0;
01629 
01630   /* Double growth factor to counter reduced min jump length.  */
01631   set_param_value ("max-grow-copy-bb-insns", 16);
01632 
01633   /* Enable section anchors by default.
01634      Skip section anchors for Objective C and Objective C++
01635      until front-ends fixed.  */
01636   if (!TARGET_MACHO && lang_hooks.name[4] != 'O')
01637     flag_section_anchors = 1;
01638 }
01639 
01640 /* Implement TARGET_HANDLE_OPTION.  */
01641 
01642 static bool
01643 rs6000_handle_option (size_t code, const char *arg, int value)
01644 {
01645   switch (code)
01646     {
01647     case OPT_mno_power:
01648       target_flags &= ~(MASK_POWER | MASK_POWER2
01649       | MASK_MULTIPLE | MASK_STRING);
01650       target_flags_explicit |= (MASK_POWER | MASK_POWER2
01651         | MASK_MULTIPLE | MASK_STRING);
01652       break;
01653     case OPT_mno_powerpc:
01654       target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
01655       | MASK_PPC_GFXOPT | MASK_POWERPC64);
01656       target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
01657         | MASK_PPC_GFXOPT | MASK_POWERPC64);
01658       break;
01659     case OPT_mfull_toc:
01660       target_flags &= ~MASK_MINIMAL_TOC;
01661       TARGET_NO_FP_IN_TOC = 0;
01662       TARGET_NO_SUM_IN_TOC = 0;
01663       target_flags_explicit |= MASK_MINIMAL_TOC;
01664 #ifdef TARGET_USES_SYSV4_OPT
01665       /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
01666    just the same as -mminimal-toc.  */
01667       target_flags |= MASK_MINIMAL_TOC;
01668       target_flags_explicit |= MASK_MINIMAL_TOC;
01669 #endif
01670       break;
01671 
01672 #ifdef TARGET_USES_SYSV4_OPT
01673     case OPT_mtoc:
01674       /* Make -mtoc behave like -mminimal-toc.  */
01675       target_flags |= MASK_MINIMAL_TOC;
01676       target_flags_explicit |= MASK_MINIMAL_TOC;
01677       break;
01678 #endif
01679 
01680 #ifdef TARGET_USES_AIX64_OPT
01681     case OPT_maix64:
01682 #else
01683     case OPT_m64:
01684 #endif
01685       target_flags |= MASK_POWERPC64 | MASK_POWERPC;
01686       target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
01687       target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
01688       break;
01689 
01690 #ifdef TARGET_USES_AIX64_OPT
01691     case OPT_maix32:
01692 #else
01693     case OPT_m32:
01694 #endif
01695       target_flags &= ~MASK_POWERPC64;
01696       target_flags_explicit |= MASK_POWERPC64;
01697       break;
01698 
01699     case OPT_minsert_sched_nops_:
01700       rs6000_sched_insert_nops_str = arg;
01701       break;
01702 
01703     case OPT_mminimal_toc:
01704       if (value == 1)
01705   {
01706     TARGET_NO_FP_IN_TOC = 0;
01707     TARGET_NO_SUM_IN_TOC = 0;
01708   }
01709       break;
01710 
01711     case OPT_mpower:
01712       if (value == 1)
01713   {
01714     target_flags |= (MASK_MULTIPLE | MASK_STRING);
01715     target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
01716   }
01717       break;
01718 
01719     case OPT_mpower2:
01720       if (value == 1)
01721   {
01722     target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
01723     target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
01724   }
01725       break;
01726 
01727     case OPT_mpowerpc_gpopt:
01728     case OPT_mpowerpc_gfxopt:
01729       if (value == 1)
01730   {
01731     target_flags |= MASK_POWERPC;
01732     target_flags_explicit |= MASK_POWERPC;
01733   }
01734       break;
01735 
01736     case OPT_maix_struct_return:
01737     case OPT_msvr4_struct_return:
01738       rs6000_explicit_options.aix_struct_ret = true;
01739       break;
01740 
01741     case OPT_mvrsave_:
01742       rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
01743       break;
01744 
01745     case OPT_misel_:
01746       rs6000_explicit_options.isel = true;
01747       rs6000_parse_yes_no_option ("isel", arg, &(rs6000_isel));
01748       break;
01749 
01750     case OPT_mspe_:
01751       rs6000_explicit_options.spe = true;
01752       rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
01753       /* No SPE means 64-bit long doubles, even if an E500.  */
01754       if (!rs6000_spe)
01755   rs6000_long_double_type_size = 64;
01756       break;
01757 
01758     case OPT_mdebug_:
01759       rs6000_debug_name = arg;
01760       break;
01761 
01762 #ifdef TARGET_USES_SYSV4_OPT
01763     case OPT_mcall_:
01764       rs6000_abi_name = arg;
01765       break;
01766 
01767     case OPT_msdata_:
01768       rs6000_sdata_name = arg;
01769       break;
01770 
01771     case OPT_mtls_size_:
01772       rs6000_tls_size_string = arg;
01773       break;
01774 
01775     case OPT_mrelocatable:
01776       if (value == 1)
01777   {
01778     target_flags |= MASK_MINIMAL_TOC;
01779     target_flags_explicit |= MASK_MINIMAL_TOC;
01780     TARGET_NO_FP_IN_TOC = 1;
01781   }
01782       break;
01783 
01784     case OPT_mrelocatable_lib:
01785       if (value == 1)
01786   {
01787     target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
01788     target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
01789     TARGET_NO_FP_IN_TOC = 1;
01790   }
01791       else
01792   {
01793     target_flags &= ~MASK_RELOCATABLE;
01794     target_flags_explicit |= MASK_RELOCATABLE;
01795   }
01796       break;
01797 #endif
01798 
01799     case OPT_mabi_:
01800       if (!strcmp (arg, "altivec"))
01801   {
01802     rs6000_explicit_options.abi = true;
01803     rs6000_altivec_abi = 1;
01804     rs6000_spe_abi = 0;
01805   }
01806       else if (! strcmp (arg, "no-altivec"))
01807   {
01808     /* ??? Don't set rs6000_explicit_options.abi here, to allow
01809        the default for rs6000_spe_abi to be chosen later.  */
01810     rs6000_altivec_abi = 0;
01811   }
01812       else if (! strcmp (arg, "spe"))
01813   {
01814     rs6000_explicit_options.abi = true;
01815     rs6000_spe_abi = 1;
01816     rs6000_altivec_abi = 0;
01817     if (!TARGET_SPE_ABI)
01818       error ("not configured for ABI: '%s'", arg);
01819   }
01820       else if (! strcmp (arg, "no-spe"))
01821   {
01822     rs6000_explicit_options.abi = true;
01823     rs6000_spe_abi = 0;
01824   }
01825 
01826       /* These are here for testing during development only, do not
01827    document in the manual please.  */
01828       else if (! strcmp (arg, "d64"))
01829   {
01830     rs6000_darwin64_abi = 1;
01831     warning (0, "Using darwin64 ABI");
01832   }
01833       else if (! strcmp (arg, "d32"))
01834   {
01835     rs6000_darwin64_abi = 0;
01836     warning (0, "Using old darwin ABI");
01837   }
01838 
01839       else if (! strcmp (arg, "ibmlongdouble"))
01840   {
01841     rs6000_explicit_options.ieee = true;
01842     rs6000_ieeequad = 0;
01843     warning (0, "Using IBM extended precision long double");
01844   }
01845       else if (! strcmp (arg, "ieeelongdouble"))
01846   {
01847     rs6000_explicit_options.ieee = true;
01848     rs6000_ieeequad = 1;
01849     warning (0, "Using IEEE extended precision long double");
01850   }
01851 
01852       else
01853   {
01854     error ("unknown ABI specified: '%s'", arg);
01855     return false;
01856   }
01857       break;
01858 
01859     case OPT_mcpu_:
01860       rs6000_select[1].string = arg;
01861       break;
01862 
01863     case OPT_mtune_:
01864       rs6000_select[2].string = arg;
01865       break;
01866 
01867     case OPT_mtraceback_:
01868       rs6000_traceback_name = arg;
01869       break;
01870 
01871     case OPT_mfloat_gprs_:
01872       rs6000_explicit_options.float_gprs = true;
01873       if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
01874   rs6000_float_gprs = 1;
01875       else if (! strcmp (arg, "double"))
01876   rs6000_float_gprs = 2;
01877       else if (! strcmp (arg, "no"))
01878   rs6000_float_gprs = 0;
01879       else
01880   {
01881     error ("invalid option for -mfloat-gprs: '%s'", arg);
01882     return false;
01883   }
01884       break;
01885 
01886     case OPT_mlong_double_:
01887       rs6000_explicit_options.long_double = true;
01888       rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
01889       if (value != 64 && value != 128)
01890   {
01891     error ("Unknown switch -mlong-double-%s", arg);
01892     rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
01893     return false;
01894   }
01895       else
01896   rs6000_long_double_type_size = value;
01897       break;
01898 
01899     case OPT_msched_costly_dep_:
01900       rs6000_sched_costly_dep_str = arg;
01901       break;
01902 
01903     case OPT_malign_:
01904       rs6000_explicit_options.alignment = true;
01905       if (! strcmp (arg, "power"))
01906   {
01907     /* On 64-bit Darwin, power alignment is ABI-incompatible with
01908        some C library functions, so warn about it. The flag may be
01909        useful for performance studies from time to time though, so
01910        don't disable it entirely.  */
01911     if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
01912       warning (0, "-malign-power is not supported for 64-bit Darwin;"
01913          " it is incompatible with the installed C and C++ libraries");
01914     rs6000_alignment_flags = MASK_ALIGN_POWER;
01915   }
01916       else if (! strcmp (arg, "natural"))
01917   rs6000_alignment_flags = MASK_ALIGN_NATURAL;
01918       else
01919   {
01920     error ("unknown -malign-XXXXX option specified: '%s'", arg);
01921     return false;
01922   }
01923       break;
01924     }
01925   return true;
01926 }
01927 
01928 /* Do anything needed at the start of the asm file.  */
01929 
01930 static void
01931 rs6000_file_start (void)
01932 {
01933   size_t i;
01934   char buffer[80];
01935   const char *start = buffer;
01936   struct rs6000_cpu_select *ptr;
01937   const char *default_cpu = TARGET_CPU_DEFAULT;
01938   FILE *file = asm_out_file;
01939 
01940   default_file_start ();
01941 
01942 #ifdef TARGET_BI_ARCH
01943   if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
01944     default_cpu = 0;
01945 #endif
01946 
01947   if (flag_verbose_asm)
01948     {
01949       sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
01950       rs6000_select[0].string = default_cpu;
01951 
01952       for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
01953   {
01954     ptr = &rs6000_select[i];
01955     if (ptr->string != (char *)0 && ptr->string[0] != '\0')
01956       {
01957         fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
01958         start = "";
01959       }
01960   }
01961 
01962       if (PPC405_ERRATUM77)
01963   {
01964     fprintf (file, "%s PPC405CR_ERRATUM77", start);
01965     start = "";
01966   }
01967 
01968 #ifdef USING_ELFOS_H
01969       switch (rs6000_sdata)
01970   {
01971   case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
01972   case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
01973   case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
01974   case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
01975   }
01976 
01977       if (rs6000_sdata && g_switch_value)
01978   {
01979     fprintf (file, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED, start,
01980        g_switch_value);
01981     start = "";
01982   }
01983 #endif
01984 
01985       if (*start == '\0')
01986   putc ('\n', file);
01987     }
01988 
01989   if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
01990     {
01991       switch_to_section (toc_section);
01992       switch_to_section (text_section);
01993     }
01994 }
01995 
01996 
01997 /* Return nonzero if this function is known to have a null epilogue.  */
01998 
01999 int
02000 direct_return (void)
02001 {
02002   if (reload_completed)
02003     {
02004       rs6000_stack_t *info = rs6000_stack_info ();
02005 
02006       if (info->first_gp_reg_save == 32
02007     && info->first_fp_reg_save == 64
02008     && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
02009     && ! info->lr_save_p
02010     && ! info->cr_save_p
02011     && info->vrsave_mask == 0
02012     && ! info->push_p)
02013   return 1;
02014     }
02015 
02016   return 0;
02017 }
02018 
02019 /* Return the number of instructions it takes to form a constant in an
02020    integer register.  */
02021 
02022 int
02023 num_insns_constant_wide (HOST_WIDE_INT value)
02024 {
02025   /* signed constant loadable with {cal|addi} */
02026   if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
02027     return 1;
02028 
02029   /* constant loadable with {cau|addis} */
02030   else if ((value & 0xffff) == 0
02031      && (value >> 31 == -1 || value >> 31 == 0))
02032     return 1;
02033 
02034 #if HOST_BITS_PER_WIDE_INT == 64
02035   else if (TARGET_POWERPC64)
02036     {
02037       HOST_WIDE_INT low  = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
02038       HOST_WIDE_INT high = value >> 31;
02039 
02040       if (high == 0 || high == -1)
02041   return 2;
02042 
02043       high >>= 1;
02044 
02045       if (low == 0)
02046   return num_insns_constant_wide (high) + 1;
02047       else
02048   return (num_insns_constant_wide (high)
02049     + num_insns_constant_wide (low) + 1);
02050     }
02051 #endif
02052 
02053   else
02054     return 2;
02055 }
02056 
02057 int
02058 num_insns_constant (rtx op, enum machine_mode mode)
02059 {
02060   HOST_WIDE_INT low, high;
02061 
02062   switch (GET_CODE (op))
02063     {
02064     case CONST_INT:
02065 #if HOST_BITS_PER_WIDE_INT == 64
02066       if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
02067     && mask64_operand (op, mode))
02068   return 2;
02069       else
02070 #endif
02071   return num_insns_constant_wide (INTVAL (op));
02072 
02073       case CONST_DOUBLE:
02074   if (mode == SFmode)
02075     {
02076       long l;
02077       REAL_VALUE_TYPE rv;
02078 
02079       REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
02080       REAL_VALUE_TO_TARGET_SINGLE (rv, l);
02081       return num_insns_constant_wide ((HOST_WIDE_INT) l);
02082     }
02083 
02084   if (mode == VOIDmode || mode == DImode)
02085     {
02086       high = CONST_DOUBLE_HIGH (op);
02087       low  = CONST_DOUBLE_LOW (op);
02088     }
02089   else
02090     {
02091       long l[2];
02092       REAL_VALUE_TYPE rv;
02093 
02094       REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
02095       REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
02096       high = l[WORDS_BIG_ENDIAN == 0];
02097       low  = l[WORDS_BIG_ENDIAN != 0];
02098     }
02099 
02100   if (TARGET_32BIT)
02101     return (num_insns_constant_wide (low)
02102       + num_insns_constant_wide (high));
02103   else
02104     {
02105       if ((high == 0 && low >= 0)
02106     || (high == -1 && low < 0))
02107         return num_insns_constant_wide (low);
02108 
02109       else if (mask64_operand (op, mode))
02110         return 2;
02111 
02112       else if (low == 0)
02113         return num_insns_constant_wide (high) + 1;
02114 
02115       else
02116         return (num_insns_constant_wide (high)
02117           + num_insns_constant_wide (low) + 1);
02118     }
02119 
02120     default:
02121       gcc_unreachable ();
02122     }
02123 }
02124 
02125 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
02126    If the mode of OP is MODE_VECTOR_INT, this simply returns the
02127    corresponding element of the vector, but for V4SFmode and V2SFmode,
02128    the corresponding "float" is interpreted as an SImode integer.  */
02129 
02130 static HOST_WIDE_INT
02131 const_vector_elt_as_int (rtx op, unsigned int elt)
02132 {
02133   rtx tmp = CONST_VECTOR_ELT (op, elt);
02134   if (GET_MODE (op) == V4SFmode
02135       || GET_MODE (op) == V2SFmode)
02136     tmp = gen_lowpart (SImode, tmp);
02137   return INTVAL (tmp);
02138 }
02139 
02140 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
02141    or vspltisw instruction.  OP is a CONST_VECTOR.  Which instruction is used
02142    depends on STEP and COPIES, one of which will be 1.  If COPIES > 1,
02143    all items are set to the same value and contain COPIES replicas of the
02144    vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
02145    operand and the others are set to the value of the operand's msb.  */
02146 
02147 static bool
02148 vspltis_constant (rtx op, unsigned step, unsigned copies)
02149 {
02150   enum machine_mode mode = GET_MODE (op);
02151   enum machine_mode inner = GET_MODE_INNER (mode);
02152 
02153   unsigned i;
02154   unsigned nunits = GET_MODE_NUNITS (mode);
02155   unsigned bitsize = GET_MODE_BITSIZE (inner);
02156   unsigned mask = GET_MODE_MASK (inner);
02157 
02158   HOST_WIDE_INT val = const_vector_elt_as_int (op, nunits - 1);
02159   HOST_WIDE_INT splat_val = val;
02160   HOST_WIDE_INT msb_val = val > 0 ? 0 : -1;
02161 
02162   /* Construct the value to be splatted, if possible.  If not, return 0.  */
02163   for (i = 2; i <= copies; i *= 2)
02164     {
02165       HOST_WIDE_INT small_val;
02166       bitsize /= 2;
02167       small_val = splat_val >> bitsize;
02168       mask >>= bitsize;
02169       if (splat_val != ((small_val << bitsize) | (small_val & mask)))
02170   return false;
02171       splat_val = small_val;
02172     }
02173 
02174   /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw].  */
02175   if (EASY_VECTOR_15 (splat_val))
02176     ;
02177 
02178   /* Also check if we can splat, and then add the result to itself.  Do so if
02179      the value is positive, of if the splat instruction is using OP's mode;
02180      for splat_val < 0, the splat and the add should use the same mode.  */
02181   else if (EASY_VECTOR_15_ADD_SELF (splat_val)
02182            && (splat_val >= 0 || (step == 1 && copies == 1)))
02183     ;
02184 
02185   else
02186     return false;
02187 
02188   /* Check if VAL is present in every STEP-th element, and the
02189      other elements are filled with its most significant bit.  */
02190   for (i = 0; i < nunits - 1; ++i)
02191     {
02192       HOST_WIDE_INT desired_val;
02193       if (((i + 1) & (step - 1)) == 0)
02194   desired_val = val;
02195       else
02196   desired_val = msb_val;
02197 
02198       if (desired_val != const_vector_elt_as_int (op, i))
02199   return false;
02200     }
02201 
02202   return true;
02203 }
02204 
02205 
02206 /* Return true if OP is of the given MODE and can be synthesized
02207    with a vspltisb, vspltish or vspltisw.  */
02208 
02209 bool
02210 easy_altivec_constant (rtx op, enum machine_mode mode)
02211 {
02212   unsigned step, copies;
02213 
02214   if (mode == VOIDmode)
02215     mode = GET_MODE (op);
02216   else if (mode != GET_MODE (op))
02217     return false;
02218 
02219   /* Start with a vspltisw.  */
02220   step = GET_MODE_NUNITS (mode) / 4;
02221   copies = 1;
02222 
02223   if (vspltis_constant (op, step, copies))
02224     return true;
02225 
02226   /* Then try with a vspltish.  */
02227   if (step == 1)
02228     copies <<= 1;
02229   else
02230     step >>= 1;
02231 
02232   if (vspltis_constant (op, step, copies))
02233     return true;
02234 
02235   /* And finally a vspltisb.  */
02236   if (step == 1)
02237     copies <<= 1;
02238   else
02239     step >>= 1;
02240 
02241   if (vspltis_constant (op, step, copies))
02242     return true;
02243 
02244   return false;
02245 }
02246 
02247 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
02248    result is OP.  Abort if it is not possible.  */
02249 
02250 rtx
02251 gen_easy_altivec_constant (rtx op)
02252 {
02253   enum machine_mode mode = GET_MODE (op);
02254   int nunits = GET_MODE_NUNITS (mode);
02255   rtx last = CONST_VECTOR_ELT (op, nunits - 1);
02256   unsigned step = nunits / 4;
02257   unsigned copies = 1;
02258 
02259   /* Start with a vspltisw.  */
02260   if (vspltis_constant (op, step, copies))
02261     return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
02262 
02263   /* Then try with a vspltish.  */
02264   if (step == 1)
02265     copies <<= 1;
02266   else
02267     step >>= 1;
02268 
02269   if (vspltis_constant (op, step, copies))
02270     return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
02271 
02272   /* And finally a vspltisb.  */
02273   if (step == 1)
02274     copies <<= 1;
02275   else
02276     step >>= 1;
02277 
02278   if (vspltis_constant (op, step, copies))
02279     return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
02280 
02281   gcc_unreachable ();
02282 }
02283 
02284 const char *
02285 output_vec_const_move (rtx *operands)
02286 {
02287   int cst, cst2;
02288   enum machine_mode mode;
02289   rtx dest, vec;
02290 
02291   dest = operands[0];
02292   vec = operands[1];
02293   mode = GET_MODE (dest);
02294 
02295   if (TARGET_ALTIVEC)
02296     {
02297       rtx splat_vec;
02298       if (zero_constant (vec, mode))
02299   return "vxor %0,%0,%0";
02300 
02301       splat_vec = gen_easy_altivec_constant (vec);
02302       gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
02303       operands[1] = XEXP (splat_vec, 0);
02304       if (!EASY_VECTOR_15 (INTVAL (operands[1])))
02305   return "#";
02306 
02307       switch (GET_MODE (splat_vec))
02308   {
02309   case V4SImode:
02310     return "vspltisw %0,%1";
02311 
02312   case V8HImode:
02313     return "vspltish %0,%1";
02314 
02315   case V16QImode:
02316     return "vspltisb %0,%1";
02317 
02318   default:
02319     gcc_unreachable ();
02320   }
02321     }
02322 
02323   gcc_assert (TARGET_SPE);
02324 
02325   /* Vector constant 0 is handled as a splitter of V2SI, and in the
02326      pattern of V1DI, V4HI, and V2SF.
02327 
02328      FIXME: We should probably return # and add post reload
02329      splitters for these, but this way is so easy ;-).  */
02330   cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
02331   cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
02332   operands[1] = CONST_VECTOR_ELT (vec, 0);
02333   operands[2] = CONST_VECTOR_ELT (vec, 1);
02334   if (cst == cst2)
02335     return "li %0,%1\n\tevmergelo %0,%0,%0";
02336   else
02337     return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
02338 }
02339 
02340 /* Initialize vector TARGET to VALS.  */
02341 
02342 void
02343 rs6000_expand_vector_init (rtx target, rtx vals)
02344 {
02345   enum machine_mode mode = GET_MODE (target);
02346   enum machine_mode inner_mode = GET_MODE_INNER (mode);
02347   int n_elts = GET_MODE_NUNITS (mode);
02348   int n_var = 0, one_var = -1;
02349   bool all_same = true, all_const_zero = true;
02350   rtx x, mem;
02351   int i;
02352 
02353   for (i = 0; i < n_elts; ++i)
02354     {
02355       x = XVECEXP (vals, 0, i);
02356       if (!CONSTANT_P (x))
02357   ++n_var, one_var = i;
02358       else if (x != CONST0_RTX (inner_mode))
02359   all_const_zero = false;
02360 
02361       if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
02362   all_same = false;
02363     }
02364 
02365   if (n_var == 0)
02366     {
02367       if (mode != V4SFmode && all_const_zero)
02368   {
02369     /* Zero register.  */
02370     emit_insn (gen_rtx_SET (VOIDmode, target,
02371           gen_rtx_XOR (mode, target, target)));
02372     return;
02373   }
02374       else if (mode != V4SFmode && easy_vector_constant (vals, mode))
02375   {
02376     /* Splat immediate.  */
02377     emit_insn (gen_rtx_SET (VOIDmode, target, vals));
02378     return;
02379   }
02380       else if (all_same)
02381   ; /* Splat vector element.  */
02382       else
02383   {
02384     /* Load from constant pool.  */
02385     emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
02386     return;
02387   }
02388     }
02389 
02390   /* Store value to stack temp.  Load vector element.  Splat.  */
02391   if (all_same)
02392     {
02393       mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
02394       emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
02395           XVECEXP (vals, 0, 0));
02396       x = gen_rtx_UNSPEC (VOIDmode,
02397         gen_rtvec (1, const0_rtx), UNSPEC_LVE);
02398       emit_insn (gen_rtx_PARALLEL (VOIDmode,
02399            gen_rtvec (2,
02400                 gen_rtx_SET (VOIDmode,
02401                  target, mem),
02402                 x)));
02403       x = gen_rtx_VEC_SELECT (inner_mode, target,
02404             gen_rtx_PARALLEL (VOIDmode,
02405             gen_rtvec (1, const0_rtx)));
02406       emit_insn (gen_rtx_SET (VOIDmode, target,
02407             gen_rtx_VEC_DUPLICATE (mode, x)));
02408       return;
02409     }
02410 
02411   /* One field is non-constant.  Load constant then overwrite
02412      varying field.  */
02413   if (n_var == 1)
02414     {
02415       rtx copy = copy_rtx (vals);
02416 
02417       /* Load constant part of vector, substitute neighboring value for
02418    varying element.  */
02419       XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
02420       rs6000_expand_vector_init (target, copy);
02421 
02422       /* Insert variable.  */
02423       rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
02424       return;
02425     }
02426 
02427   /* Construct the vector in memory one field at a time
02428      and load the whole vector.  */
02429   mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
02430   for (i = 0; i < n_elts; i++)
02431     emit_move_insn (adjust_address_nv (mem, inner_mode,
02432             i * GET_MODE_SIZE (inner_mode)),
02433         XVECEXP (vals, 0, i));
02434   emit_move_insn (target, mem);
02435 }
02436 
02437 /* Set field ELT of TARGET to VAL.  */
02438 
02439 void
02440 rs6000_expand_vector_set (rtx target, rtx val, int elt)
02441 {
02442   enum machine_mode mode = GET_MODE (target);
02443   enum machine_mode inner_mode = GET_MODE_INNER (mode);
02444   rtx reg = gen_reg_rtx (mode);
02445   rtx mask, mem, x;
02446   int width = GET_MODE_SIZE (inner_mode);
02447   int i;
02448 
02449   /* Load single variable value.  */
02450   mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
02451   emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
02452   x = gen_rtx_UNSPEC (VOIDmode,
02453           gen_rtvec (1, const0_rtx), UNSPEC_LVE);
02454   emit_insn (gen_rtx_PARALLEL (VOIDmode,
02455              gen_rtvec (2,
02456             gen_rtx_SET (VOIDmode,
02457                    reg, mem),
02458             x)));
02459 
02460   /* Linear sequence.  */
02461   mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
02462   for (i = 0; i < 16; ++i)
02463     XVECEXP (mask, 0, i) = GEN_INT (i);
02464 
02465   /* Set permute mask to insert element into target.  */
02466   for (i = 0; i < width; ++i)
02467     XVECEXP (mask, 0, elt*width + i)
02468       = GEN_INT (i + 0x10);
02469   x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
02470   x = gen_rtx_UNSPEC (mode,
02471           gen_rtvec (3, target, reg,
02472          force_reg (V16QImode, x)),
02473           UNSPEC_VPERM);
02474   emit_insn (gen_rtx_SET (VOIDmode, target, x));
02475 }
02476 
02477 /* Extract field ELT from VEC into TARGET.  */
02478 
02479 void
02480 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
02481 {
02482   enum machine_mode mode = GET_MODE (vec);
02483   enum machine_mode inner_mode = GET_MODE_INNER (mode);
02484   rtx mem, x;
02485 
02486   /* Allocate mode-sized buffer.  */
02487   mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
02488 
02489   /* Add offset to field within buffer matching vector element.  */
02490   mem = adjust_address_nv (mem, mode, elt * GET_MODE_SIZE (inner_mode));
02491 
02492   /* Store single field into mode-sized buffer.  */
02493   x = gen_rtx_UNSPEC (VOIDmode,
02494           gen_rtvec (1, const0_rtx), UNSPEC_STVE);
02495   emit_insn (gen_rtx_PARALLEL (VOIDmode,
02496              gen_rtvec (2,
02497             gen_rtx_SET (VOIDmode,
02498                    mem, vec),
02499             x)));
02500   emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
02501 }
02502 
02503 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
02504    implement ANDing by the mask IN.  */
02505 void
02506 build_mask64_2_operands (rtx in, rtx *out)
02507 {
02508 #if HOST_BITS_PER_WIDE_INT >= 64
02509   unsigned HOST_WIDE_INT c, lsb, m1, m2;
02510   int shift;
02511 
02512   gcc_assert (GET_CODE (in) == CONST_INT);
02513 
02514   c = INTVAL (in);
02515   if (c & 1)
02516     {
02517       /* Assume c initially something like 0x00fff000000fffff.  The idea
02518    is to rotate the word so that the middle ^^^^^^ group of zeros
02519    is at the MS end and can be cleared with an rldicl mask.  We then
02520    rotate back and clear off the MS    ^^ group of zeros with a
02521    second rldicl.  */
02522       c = ~c;     /*   c == 0xff000ffffff00000 */
02523       lsb = c & -c;   /* lsb == 0x0000000000100000 */
02524       m1 = -lsb;    /*  m1 == 0xfffffffffff00000 */
02525       c = ~c;     /*   c == 0x00fff000000fffff */
02526       c &= -lsb;    /*   c == 0x00fff00000000000 */
02527       lsb = c & -c;   /* lsb == 0x0000100000000000 */
02528       c = ~c;     /*   c == 0xff000fffffffffff */
02529       c &= -lsb;    /*   c == 0xff00000000000000 */
02530       shift = 0;
02531       while ((lsb >>= 1) != 0)
02532   shift++;    /* shift == 44 on exit from loop */
02533       m1 <<= 64 - shift;  /*  m1 == 0xffffff0000000000 */
02534       m1 = ~m1;     /*  m1 == 0x000000ffffffffff */
02535       m2 = ~c;      /*  m2 == 0x00ffffffffffffff */
02536     }
02537   else
02538     {
02539       /* Assume c initially something like 0xff000f0000000000.  The idea
02540    is to rotate the word so that the     ^^^  middle group of zeros
02541    is at the LS end and can be cleared with an rldicr mask.  We then
02542    rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
02543    a second rldicr.  */
02544       lsb = c & -c;   /* lsb == 0x0000010000000000 */
02545       m2 = -lsb;    /*  m2 == 0xffffff0000000000 */
02546       c = ~c;     /*   c == 0x00fff0ffffffffff */
02547       c &= -lsb;    /*   c == 0x00fff00000000000 */
02548       lsb = c & -c;   /* lsb == 0x0000100000000000 */
02549       c = ~c;     /*   c == 0xff000fffffffffff */
02550       c &= -lsb;    /*   c == 0xff00000000000000 */
02551       shift = 0;
02552       while ((lsb >>= 1) != 0)
02553   shift++;    /* shift == 44 on exit from loop */
02554       m1 = ~c;      /*  m1 == 0x00ffffffffffffff */
02555       m1 >>= shift;   /*  m1 == 0x0000000000000fff */
02556       m1 = ~m1;     /*  m1 == 0xfffffffffffff000 */
02557     }
02558 
02559   /* Note that when we only have two 0->1 and 1->0 transitions, one of the
02560      masks will be all 1's.  We are guaranteed more than one transition.  */
02561   out[0] = GEN_INT (64 - shift);
02562   out[1] = GEN_INT (m1);
02563   out[2] = GEN_INT (shift);
02564   out[3] = GEN_INT (m2);
02565 #else
02566   (void)in;
02567   (void)out;
02568   gcc_unreachable ();
02569 #endif
02570 }
02571 
02572 /* Return TRUE if OP is an invalid SUBREG operation on the e500.  */
02573 
02574 bool
02575 invalid_e500_subreg (rtx op, enum machine_mode mode)
02576 {
02577   if (TARGET_E500_DOUBLE)
02578     {
02579       /* Reject (subreg:SI (reg:DF)).  */
02580       if (GET_CODE (op) == SUBREG
02581     && mode == SImode
02582     && REG_P (SUBREG_REG (op))
02583     && GET_MODE (SUBREG_REG (op)) == DFmode)
02584   return true;
02585 
02586       /* Reject (subreg:DF (reg:DI)).  */
02587       if (GET_CODE (op) == SUBREG
02588     && mode == DFmode
02589     && REG_P (SUBREG_REG (op))
02590     && GET_MODE (SUBREG_REG (op)) == DImode)
02591   return true;
02592     }
02593 
02594   if (TARGET_SPE
02595       && GET_CODE (op) == SUBREG
02596       && mode == SImode
02597       && REG_P (SUBREG_REG (op))
02598       && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
02599     return true;
02600 
02601   return false;
02602 }
02603 
02604 /* Darwin, AIX increases natural record alignment to doubleword if the first
02605    field is an FP double while the FP fields remain word aligned.  */
02606 
02607 unsigned int
02608 rs6000_special_round_type_align (tree type, unsigned int computed,
02609          unsigned int specified)
02610 {
02611   unsigned int align = MAX (computed, specified);
02612   tree field = TYPE_FIELDS (type);
02613 
02614   /* Skip all non field decls */
02615   while (field != NULL && TREE_CODE (field) != FIELD_DECL)
02616     field = TREE_CHAIN (field);
02617 
02618   if (field != NULL && field != type)
02619     {
02620       type = TREE_TYPE (field);
02621       while (TREE_CODE (type) == ARRAY_TYPE)
02622   type = TREE_TYPE (type);
02623 
02624       if (type != error_mark_node && TYPE_MODE (type) == DFmode)
02625   align = MAX (align, 64);
02626     }
02627 
02628   return align;
02629 }
02630 
02631 /* Return 1 for an operand in small memory on V.4/eabi.  */
02632 
02633 int
02634 small_data_operand (rtx op ATTRIBUTE_UNUSED,
02635         enum machine_mode mode ATTRIBUTE_UNUSED)
02636 {
02637 #if TARGET_ELF
02638   rtx sym_ref;
02639 
02640   if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
02641     return 0;
02642 
02643   if (DEFAULT_ABI != ABI_V4)
02644     return 0;
02645 
02646   if (GET_CODE (op) == SYMBOL_REF)
02647     sym_ref = op;
02648 
02649   else if (GET_CODE (op) != CONST
02650      || GET_CODE (XEXP (op, 0)) != PLUS
02651      || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
02652      || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
02653     return 0;
02654 
02655   else
02656     {
02657       rtx sum = XEXP (op, 0);
02658       HOST_WIDE_INT summand;
02659 
02660       /* We have to be careful here, because it is the referenced address
02661    that must be 32k from _SDA_BASE_, not just the symbol.  */
02662       summand = INTVAL (XEXP (sum, 1));
02663       if (summand < 0 || (unsigned HOST_WIDE_INT) summand > g_switch_value)
02664   return 0;
02665 
02666       sym_ref = XEXP (sum, 0);
02667     }
02668 
02669   return SYMBOL_REF_SMALL_P (sym_ref);
02670 #else
02671   return 0;
02672 #endif
02673 }
02674 
02675 /* Return true if either operand is a general purpose register.  */
02676 
02677 bool
02678 gpr_or_gpr_p (rtx op0, rtx op1)
02679 {
02680   return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
02681     || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
02682 }
02683 
02684 
02685 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address.  */
02686 
02687 static int
02688 constant_pool_expr_1 (rtx op, int *have_sym, int *have_toc)
02689 {
02690   switch (GET_CODE (op))
02691     {
02692     case SYMBOL_REF:
02693       if (RS6000_SYMBOL_REF_TLS_P (op))
02694   return 0;
02695       else if (CONSTANT_POOL_ADDRESS_P (op))
02696   {
02697     if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (op), Pmode))
02698       {
02699         *have_sym = 1;
02700         return 1;
02701       }
02702     else
02703       return 0;
02704   }
02705       else if (! strcmp (XSTR (op, 0), toc_label_name))
02706   {
02707     *have_toc = 1;
02708     return 1;
02709   }
02710       else
02711   return 0;
02712     case PLUS:
02713     case MINUS:
02714       return (constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc)
02715         && constant_pool_expr_1 (XEXP (op, 1), have_sym, have_toc));
02716     case CONST:
02717       return constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc);
02718     case CONST_INT:
02719       return 1;
02720     default:
02721       return 0;
02722     }
02723 }
02724 
02725 static bool
02726 constant_pool_expr_p (rtx op)
02727 {
02728   int have_sym = 0;
02729   int have_toc = 0;
02730   return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_sym;
02731 }
02732 
02733 bool
02734 toc_relative_expr_p (rtx op)
02735 {
02736   int have_sym = 0;
02737   int have_toc = 0;
02738   return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_toc;
02739 }
02740 
02741 bool
02742 legitimate_constant_pool_address_p (rtx x)
02743 {
02744   return (TARGET_TOC
02745     && GET_CODE (x) == PLUS
02746     && GET_CODE (XEXP (x, 0)) == REG
02747     && (TARGET_MINIMAL_TOC || REGNO (XEXP (x, 0)) == TOC_REGISTER)
02748     && constant_pool_expr_p (XEXP (x, 1)));
02749 }
02750 
02751 static bool
02752 legitimate_small_data_p (enum machine_mode mode, rtx x)
02753 {
02754   return (DEFAULT_ABI == ABI_V4
02755     && !flag_pic && !TARGET_TOC
02756     && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
02757     && small_data_operand (x, mode));
02758 }
02759 
02760 /* SPE offset addressing is limited to 5-bits worth of double words.  */
02761 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
02762 
02763 bool
02764 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
02765 {
02766   unsigned HOST_WIDE_INT offset, extra;
02767 
02768   if (GET_CODE (x) != PLUS)
02769     return false;
02770   if (GET_CODE (XEXP (x, 0)) != REG)
02771     return false;
02772   if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
02773     return false;
02774   if (legitimate_constant_pool_address_p (x))
02775     return true;
02776   if (GET_CODE (XEXP (x, 1)) != CONST_INT)
02777     return false;
02778 
02779   offset = INTVAL (XEXP (x, 1));
02780   extra = 0;
02781   switch (mode)
02782     {
02783     case V16QImode:
02784     case V8HImode:
02785     case V4SFmode:
02786     case V4SImode:
02787       /* AltiVec vector modes.  Only reg+reg addressing is valid and
02788    constant offset zero should not occur due to canonicalization.
02789    Allow any offset when not strict before reload.  */
02790       return !strict;
02791 
02792     case V4HImode:
02793     case V2SImode:
02794     case V1DImode:
02795     case V2SFmode:
02796       /* SPE vector modes.  */
02797       return SPE_CONST_OFFSET_OK (offset);
02798 
02799     case DFmode:
02800       if (TARGET_E500_DOUBLE)
02801   return SPE_CONST_OFFSET_OK (offset);
02802 
02803     case DImode:
02804       /* On e500v2, we may have:
02805 
02806      (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
02807 
02808          Which gets addressed with evldd instructions.  */
02809       if (TARGET_E500_DOUBLE)
02810   return SPE_CONST_OFFSET_OK (offset);
02811 
02812       if (mode == DFmode || !TARGET_POWERPC64)
02813   extra = 4;
02814       else if (offset & 3)
02815   return false;
02816       break;
02817 
02818     case TFmode:
02819     case TImode:
02820       if (mode == TFmode || !TARGET_POWERPC64)
02821   extra = 12;
02822       else if (offset & 3)
02823   return false;
02824       else
02825   extra = 8;
02826       break;
02827 
02828     default:
02829       break;
02830     }
02831 
02832   offset += 0x8000;
02833   return (offset < 0x10000) && (offset + extra < 0x10000);
02834 }
02835 
02836 static bool
02837 legitimate_indexed_address_p (rtx x, int strict)
02838 {
02839   rtx op0, op1;
02840 
02841   if (GET_CODE (x) != PLUS)
02842     return false;
02843 
02844   op0 = XEXP (x, 0);
02845   op1 = XEXP (x, 1);
02846 
02847   /* Recognize the rtl generated by reload which we know will later be
02848      replaced with proper base and index regs.  */
02849   if (!strict
02850       && reload_in_progress
02851       && (REG_P (op0) || GET_CODE (op0) == PLUS)
02852       && REG_P (op1))
02853     return true;
02854 
02855   return (REG_P (op0) && REG_P (op1)
02856     && ((INT_REG_OK_FOR_BASE_P (op0, strict)
02857          && INT_REG_OK_FOR_INDEX_P (op1, strict))
02858         || (INT_REG_OK_FOR_BASE_P (op1, strict)
02859       && INT_REG_OK_FOR_INDEX_P (op0, strict))));
02860 }
02861 
02862 inline bool
02863 legitimate_indirect_address_p (rtx x, int strict)
02864 {
02865   return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
02866 }
02867 
02868 bool
02869 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
02870 {
02871   if (!TARGET_MACHO || !flag_pic
02872       || mode != SImode || GET_CODE (x) != MEM)
02873     return false;
02874   x = XEXP (x, 0);
02875 
02876   if (GET_CODE (x) != LO_SUM)
02877     return false;
02878   if (GET_CODE (XEXP (x, 0)) != REG)
02879     return false;
02880   if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
02881     return false;
02882   x = XEXP (x, 1);
02883 
02884   return CONSTANT_P (x);
02885 }
02886 
02887 static bool
02888 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
02889 {
02890   if (GET_CODE (x) != LO_SUM)
02891     return false;
02892   if (GET_CODE (XEXP (x, 0)) != REG)
02893     return false;
02894   if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
02895     return false;
02896   /* Restrict addressing for DI because of our SUBREG hackery.  */
02897   if (TARGET_E500_DOUBLE && (mode == DFmode || mode == DImode))
02898     return false;
02899   x = XEXP (x, 1);
02900 
02901   if (TARGET_ELF || TARGET_MACHO)
02902     {
02903       if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
02904   return false;
02905       if (TARGET_TOC)
02906   return false;
02907       if (GET_MODE_NUNITS (mode) != 1)
02908   return false;
02909       if (GET_MODE_BITSIZE (mode) > 64
02910     || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
02911         && !(TARGET_HARD_FLOAT && TARGET_FPRS && mode == DFmode)))
02912   return false;
02913 
02914       return CONSTANT_P (x);
02915     }
02916 
02917   return false;
02918 }
02919 
02920 
02921 /* Try machine-dependent ways of modifying an illegitimate address
02922    to be legitimate.  If we find one, return the new, valid address.
02923    This is used from only one place: `memory_address' in explow.c.
02924 
02925    OLDX is the address as it was before break_out_memory_refs was
02926    called.  In some cases it is useful to look at this to decide what
02927    needs to be done.
02928 
02929    MODE is passed so that this function can use GO_IF_LEGITIMATE_ADDRESS.
02930 
02931    It is always safe for this function to do nothing.  It exists to
02932    recognize opportunities to optimize the output.
02933 
02934    On RS/6000, first check for the sum of a register with a constant
02935    integer that is out of range.  If so, generate code to add the
02936    constant with the low-order 16 bits masked to the register and force
02937    this result into another register (this can be done with `cau').
02938    Then generate an address of REG+(CONST&0xffff), allowing for the
02939    possibility of bit 16 being a one.
02940 
02941    Then check for the sum of a register and something not constant, try to
02942    load the other things into a register and return the sum.  */
02943 
02944 rtx
02945 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
02946          enum machine_mode mode)
02947 {
02948   if (GET_CODE (x) == SYMBOL_REF)
02949     {
02950       enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
02951       if (model != 0)
02952   return rs6000_legitimize_tls_address (x, model);
02953     }
02954 
02955   if (GET_CODE (x) == PLUS
02956       && GET_CODE (XEXP (x, 0)) == REG
02957       && GET_CODE (XEXP (x, 1)) == CONST_INT
02958       && (unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000) >= 0x10000)
02959     {
02960       HOST_WIDE_INT high_int, low_int;
02961       rtx sum;
02962       low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
02963       high_int = INTVAL (XEXP (x, 1)) - low_int;
02964       sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
02965            GEN_INT (high_int)), 0);
02966       return gen_rtx_PLUS (Pmode, sum, GEN_INT (low_int));
02967     }
02968   else if (GET_CODE (x) == PLUS
02969      && GET_CODE (XEXP (x, 0)) == REG
02970      && GET_CODE (XEXP (x, 1)) != CONST_INT
02971      && GET_MODE_NUNITS (mode) == 1
02972      && ((TARGET_HARD_FLOAT && TARGET_FPRS)
02973          || TARGET_POWERPC64
02974          || (((mode != DImode && mode != DFmode) || TARGET_E500_DOUBLE)
02975        && mode != TFmode))
02976      && (TARGET_POWERPC64 || mode != DImode)
02977      && mode != TImode)
02978     {
02979       return gen_rtx_PLUS (Pmode, XEXP (x, 0),
02980          force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
02981     }
02982   else if (ALTIVEC_VECTOR_MODE (mode))
02983     {
02984       rtx reg;
02985 
02986       /* Make sure both operands are registers.  */
02987       if (GET_CODE (x) == PLUS)
02988   return gen_rtx_PLUS (Pmode, force_reg (Pmode, XEXP (x, 0)),
02989            force_reg (Pmode, XEXP (x, 1)));
02990 
02991       reg = force_reg (Pmode, x);
02992       return reg;
02993     }
02994   else if (SPE_VECTOR_MODE (mode)
02995      || (TARGET_E500_DOUBLE && (mode == DFmode
02996               || mode == DImode)))
02997     {
02998       if (mode == DImode)
02999   return NULL_RTX;
03000       /* We accept [reg + reg] and [reg + OFFSET].  */
03001 
03002       if (GET_CODE (x) == PLUS)
03003   {
03004     rtx op1 = XEXP (x, 0);
03005     rtx op2 = XEXP (x, 1);
03006 
03007     op1 = force_reg (Pmode, op1);
03008 
03009     if (GET_CODE (op2) != REG
03010         && (GET_CODE (op2) != CONST_INT
03011       || !SPE_CONST_OFFSET_OK (INTVAL (op2))))
03012       op2 = force_reg (Pmode, op2);
03013 
03014     return gen_rtx_PLUS (Pmode, op1, op2);
03015   }
03016 
03017       return force_reg (Pmode, x);
03018     }
03019   else if (TARGET_ELF
03020      && TARGET_32BIT
03021      && TARGET_NO_TOC
03022      && ! flag_pic
03023      && GET_CODE (x) != CONST_INT
03024      && GET_CODE (x) != CONST_DOUBLE
03025      && CONSTANT_P (x)
03026      && GET_MODE_NUNITS (mode) == 1
03027      && (GET_MODE_BITSIZE (mode) <= 32
03028          || ((TARGET_HARD_FLOAT && TARGET_FPRS) && mode == DFmode)))
03029     {
03030       rtx reg = gen_reg_rtx (Pmode);
03031       emit_insn (gen_elf_high (reg, x));
03032       return gen_rtx_LO_SUM (Pmode, reg, x);
03033     }
03034   else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
03035      && ! flag_pic
03036 #if TARGET_MACHO
03037      && ! MACHO_DYNAMIC_NO_PIC_P
03038 #endif
03039      && GET_CODE (x) != CONST_INT
03040      && GET_CODE (x) != CONST_DOUBLE
03041      && CONSTANT_P (x)
03042      && ((TARGET_HARD_FLOAT && TARGET_FPRS) || mode != DFmode)
03043      && mode != DImode
03044      && mode != TImode)
03045     {
03046       rtx reg = gen_reg_rtx (Pmode);
03047       emit_insn (gen_macho_high (reg, x));
03048       return gen_rtx_LO_SUM (Pmode, reg, x);
03049     }
03050   else if (TARGET_TOC
03051      && constant_pool_expr_p (x)
03052      && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
03053     {
03054       return create_TOC_reference (x);
03055     }
03056   else
03057     return NULL_RTX;
03058 }
03059 
03060 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
03061    We need to emit DTP-relative relocations.  */
03062 
03063 static void
03064 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
03065 {
03066   switch (size)
03067     {
03068     case 4:
03069       fputs ("\t.long\t", file);
03070       break;
03071     case 8:
03072       fputs (DOUBLE_INT_ASM_OP, file);
03073       break;
03074     default:
03075       gcc_unreachable ();
03076     }
03077   output_addr_const (file, x);
03078   fputs ("@dtprel+0x8000", file);
03079 }
03080 
03081 /* Construct the SYMBOL_REF for the tls_get_addr function.  */
03082 
03083 static GTY(()) rtx rs6000_tls_symbol;
03084 static rtx
03085 rs6000_tls_get_addr (void)
03086 {
03087   if (!rs6000_tls_symbol)
03088     rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
03089 
03090   return rs6000_tls_symbol;
03091 }
03092 
03093 /* Construct the SYMBOL_REF for TLS GOT references.  */
03094 
03095 static GTY(()) rtx rs6000_got_symbol;
03096 static rtx
03097 rs6000_got_sym (void)
03098 {
03099   if (!rs6000_got_symbol)
03100     {
03101       rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
03102       SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
03103       SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
03104     }
03105 
03106   return rs6000_got_symbol;
03107 }
03108 
03109 /* ADDR contains a thread-local SYMBOL_REF.  Generate code to compute
03110    this (thread-local) address.  */
03111 
03112 static rtx
03113 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
03114 {
03115   rtx dest, insn;
03116 
03117   dest = gen_reg_rtx (Pmode);
03118   if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
03119     {
03120       rtx tlsreg;
03121 
03122       if (TARGET_64BIT)
03123   {
03124     tlsreg = gen_rtx_REG (Pmode, 13);
03125     insn = gen_tls_tprel_64 (dest, tlsreg, addr);
03126   }
03127       else
03128   {
03129     tlsreg = gen_rtx_REG (Pmode, 2);
03130     insn = gen_tls_tprel_32 (dest, tlsreg, addr);
03131   }
03132       emit_insn (insn);
03133     }
03134   else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
03135     {
03136       rtx tlsreg, tmp;
03137 
03138       tmp = gen_reg_rtx (Pmode);
03139       if (TARGET_64BIT)
03140   {
03141     tlsreg = gen_rtx_REG (Pmode, 13);
03142     insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
03143   }
03144       else
03145   {
03146     tlsreg = gen_rtx_REG (Pmode, 2);
03147     insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
03148   }
03149       emit_insn (insn);
03150       if (TARGET_64BIT)
03151   insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
03152       else
03153   insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
03154       emit_insn (insn);
03155     }
03156   else
03157     {
03158       rtx r3, got, tga, tmp1, tmp2, eqv;
03159 
03160       /* We currently use relocations like @got@tlsgd for tls, which
03161    means the linker will handle allocation of tls entries, placing
03162    them in the .got section.  So use a pointer to the .got section,
03163    not one to secondary TOC sections used by 64-bit -mminimal-toc,
03164    or to secondary GOT sections used by 32-bit -fPIC.  */
03165       if (TARGET_64BIT)
03166   got = gen_rtx_REG (Pmode, 2);
03167       else
03168   {
03169     if (flag_pic == 1)
03170       got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
03171     else
03172       {
03173         rtx gsym = rs6000_got_sym ();
03174         got = gen_reg_rtx (Pmode);
03175         if (flag_pic == 0)
03176     rs6000_emit_move (got, gsym, Pmode);
03177         else
03178     {
03179       rtx tempLR, tmp3, mem;
03180       rtx first, last;
03181 
03182       tempLR = gen_reg_rtx (Pmode);
03183       tmp1 = gen_reg_rtx (Pmode);
03184       tmp2 = gen_reg_rtx (Pmode);
03185       tmp3 = gen_reg_rtx (Pmode);
03186       mem = gen_const_mem (Pmode, tmp1);
03187 
03188       first = emit_insn (gen_load_toc_v4_PIC_1b (tempLR, gsym));
03189       emit_move_insn (tmp1, tempLR);
03190       emit_move_insn (tmp2, mem);
03191       emit_insn (gen_addsi3 (tmp3, tmp1, tmp2));
03192       last = emit_move_insn (got, tmp3);
03193       REG_NOTES (last) = gen_rtx_EXPR_LIST (REG_EQUAL, gsym,
03194               REG_NOTES (last));
03195       REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
03196                REG_NOTES (first));
03197       REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first,
03198               REG_NOTES (last));
03199     }
03200       }
03201   }
03202 
03203       if (model == TLS_MODEL_GLOBAL_DYNAMIC)
03204   {
03205     r3 = gen_rtx_REG (Pmode, 3);
03206     if (TARGET_64BIT)
03207       insn = gen_tls_gd_64 (r3, got, addr);
03208     else
03209       insn = gen_tls_gd_32 (r3, got, addr);
03210     start_sequence ();
03211     emit_insn (insn);
03212     tga = gen_rtx_MEM (Pmode, rs6000_tls_get_addr ());
03213     insn = gen_call_value (r3, tga, const0_rtx, const0_rtx);
03214     insn = emit_call_insn (insn);
03215     CONST_OR_PURE_CALL_P (insn) = 1;
03216     use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
03217     insn = get_insns ();
03218     end_sequence ();
03219     emit_libcall_block (insn, dest, r3, addr);
03220   }
03221       else if (model == TLS_MODEL_LOCAL_DYNAMIC)
03222   {
03223     r3 = gen_rtx_REG (Pmode, 3);
03224     if (TARGET_64BIT)
03225       insn = gen_tls_ld_64 (r3, got);
03226     else
03227       insn = gen_tls_ld_32 (r3, got);
03228     start_sequence ();
03229     emit_insn (insn);
03230     tga = gen_rtx_MEM (Pmode, rs6000_tls_get_addr ());
03231     insn = gen_call_value (r3, tga, const0_rtx, const0_rtx);
03232     insn = emit_call_insn (insn);
03233     CONST_OR_PURE_CALL_P (insn) = 1;
03234     use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
03235     insn = get_insns ();
03236     end_sequence ();
03237     tmp1 = gen_reg_rtx (Pmode);
03238     eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
03239         UNSPEC_TLSLD);
03240     emit_libcall_block (insn, tmp1, r3, eqv);
03241     if (rs6000_tls_size == 16)
03242       {
03243         if (TARGET_64BIT)
03244     insn = gen_tls_dtprel_64 (dest, tmp1, addr);
03245         else
03246     insn = gen_tls_dtprel_32 (dest, tmp1, addr);
03247       }
03248     else if (rs6000_tls_size == 32)
03249       {
03250         tmp2 = gen_reg_rtx (Pmode);
03251         if (TARGET_64BIT)
03252     insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
03253         else
03254     insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
03255         emit_insn (insn);
03256         if (TARGET_64BIT)
03257     insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
03258         else
03259     insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
03260       }
03261     else
03262       {
03263         tmp2 = gen_reg_rtx (Pmode);
03264         if (TARGET_64BIT)
03265     insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
03266         else
03267     insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
03268         emit_insn (insn);
03269         insn = gen_rtx_SET (Pmode, dest,
03270           gen_rtx_PLUS (Pmode, tmp2, tmp1));
03271       }
03272     emit_insn (insn);
03273   }
03274       else
03275   {
03276     /* IE, or 64 bit offset LE.  */
03277     tmp2 = gen_reg_rtx (Pmode);
03278     if (TARGET_64BIT)
03279       insn = gen_tls_got_tprel_64 (tmp2, got, addr);
03280     else
03281       insn = gen_tls_got_tprel_32 (tmp2, got, addr);
03282     emit_insn (insn);
03283     if (TARGET_64BIT)
03284       insn = gen_tls_tls_64 (dest, tmp2, addr);
03285     else
03286       insn = gen_tls_tls_32 (dest, tmp2, addr);
03287     emit_insn (insn);
03288   }
03289     }
03290 
03291   return dest;
03292 }
03293 
03294 /* Return 1 if X contains a thread-local symbol.  */
03295 
03296 bool
03297 rs6000_tls_referenced_p (rtx x)
03298 {
03299   if (! TARGET_HAVE_TLS)
03300     return false;
03301 
03302   return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
03303 }
03304 
03305 /* Return 1 if *X is a thread-local symbol.  This is the same as
03306    rs6000_tls_symbol_ref except for the type of the unused argument.  */
03307 
03308 static int
03309 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
03310 {
03311   return RS6000_SYMBOL_REF_TLS_P (*x);
03312 }
03313 
03314 /* The convention appears to be to define this wherever it is used.
03315    With legitimize_reload_address now defined here, REG_MODE_OK_FOR_BASE_P
03316    is now used here.  */
03317 #ifndef REG_MODE_OK_FOR_BASE_P
03318 #define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
03319 #endif
03320 
03321 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS.  Returns a value to
03322    replace the input X, or the original X if no replacement is called for.
03323    The output parameter *WIN is 1 if the calling macro should goto WIN,
03324    0 if it should not.
03325 
03326    For RS/6000, we wish to handle large displacements off a base
03327    register by splitting the addend across an addiu/addis and the mem insn.
03328    This cuts number of extra insns needed from 3 to 1.
03329 
03330    On Darwin, we use this to generate code for floating point constants.
03331    A movsf_low is generated so we wind up with 2 instructions rather than 3.
03332    The Darwin code is inside #if TARGET_MACHO because only then is
03333    machopic_function_base_name() defined.  */
03334 rtx
03335 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
03336           int opnum, int type,
03337           int ind_levels ATTRIBUTE_UNUSED, int *win)
03338 {
03339   /* We must recognize output that we have already generated ourselves.  */
03340   if (GET_CODE (x) == PLUS
03341       && GET_CODE (XEXP (x, 0)) == PLUS
03342       && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
03343       && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
03344       && GET_CODE (XEXP (x, 1)) == CONST_INT)
03345     {
03346       push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
03347        BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
03348        opnum, (enum reload_type)type);
03349       *win = 1;
03350       return x;
03351     }
03352 
03353 #if TARGET_MACHO
03354   if (DEFAULT_ABI == ABI_DARWIN && flag_pic
03355       && GET_CODE (x) == LO_SUM
03356       && GET_CODE (XEXP (x, 0)) == PLUS
03357       && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
03358       && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
03359       && GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 0)) == CONST
03360       && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
03361       && GET_CODE (XEXP (XEXP (x, 1), 0)) == MINUS
03362       && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 0)) == SYMBOL_REF
03363       && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 1)) == SYMBOL_REF)
03364     {
03365       /* Result of previous invocation of this function on Darwin
03366    floating point constant.  */
03367       push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
03368        BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
03369        opnum, (enum reload_type)type);
03370       *win = 1;
03371       return x;
03372     }
03373 #endif
03374 
03375   /* Force ld/std non-word aligned offset into base register by wrapping
03376      in offset 0.  */
03377   if (GET_CODE (x) == PLUS
03378       && GET_CODE (XEXP (x, 0)) == REG
03379       && REGNO (XEXP (x, 0)) < 32
03380       && REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode)
03381       && GET_CODE (XEXP (x, 1)) == CONST_INT
03382       && (INTVAL (XEXP (x, 1)) & 3) != 0
03383       && !ALTIVEC_VECTOR_MODE (mode)
03384       && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
03385       && TARGET_POWERPC64)
03386     {
03387       x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
03388       push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
03389        BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
03390        opnum, (enum reload_type) type);
03391       *win = 1;
03392       return x;
03393     }
03394 
03395   if (GET_CODE (x) == PLUS
03396       && GET_CODE (XEXP (x, 0)) == REG
03397       && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
03398       && REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode)
03399       && GET_CODE (XEXP (x, 1)) == CONST_INT
03400       && !SPE_VECTOR_MODE (mode)
03401       && !(TARGET_E500_DOUBLE && (mode == DFmode
03402           || mode == DImode))
03403       && !ALTIVEC_VECTOR_MODE (mode))
03404     {
03405       HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
03406       HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
03407       HOST_WIDE_INT high
03408   = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
03409 
03410       /* Check for 32-bit overflow.  */
03411       if (high + low != val)
03412   {
03413     *win = 0;
03414     return x;
03415   }
03416 
03417       /* Reload the high part into a base reg; leave the low part
03418    in the mem directly.  */
03419 
03420       x = gen_rtx_PLUS (GET_MODE (x),
03421       gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
03422               GEN_INT (high)),
03423       GEN_INT (low));
03424 
03425       push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
03426        BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
03427        opnum, (enum reload_type)type);
03428       *win = 1;
03429       return x;
03430     }
03431 
03432   if (GET_CODE (x) == SYMBOL_REF
03433       && !ALTIVEC_VECTOR_MODE (mode)
03434       && !SPE_VECTOR_MODE (mode)
03435 #if TARGET_MACHO
03436       && DEFAULT_ABI == ABI_DARWIN
03437       && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
03438 #else
03439       && DEFAULT_ABI == ABI_V4
03440       && !flag_pic
03441 #endif
03442       /* Don't do this for TFmode, since the result isn't offsettable.
03443    The same goes for DImode without 64-bit gprs and DFmode
03444    without fprs.  */
03445       && mode != TFmode
03446       && (mode != DImode || TARGET_POWERPC64)
03447       && (mode != DFmode || TARGET_POWERPC64
03448     || (TARGET_FPRS && TARGET_HARD_FLOAT)))
03449     {
03450 #if TARGET_MACHO
03451       if (flag_pic)
03452   {
03453     rtx offset = gen_rtx_CONST (Pmode,
03454        gen_rtx_MINUS (Pmode, x,
03455           machopic_function_base_sym ()));
03456     x = gen_rtx_LO_SUM (GET_MODE (x),
03457     gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
03458       gen_rtx_HIGH (Pmode, offset)), offset);
03459   }
03460       else
03461 #endif
03462   x = gen_rtx_LO_SUM (GET_MODE (x),
03463         gen_rtx_HIGH (Pmode, x), x);
03464 
03465       push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
03466        BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
03467        opnum, (enum reload_type)type);
03468       *win = 1;
03469       return x;
03470     }
03471 
03472   /* Reload an offset address wrapped by an AND that represents the
03473      masking of the lower bits.  Strip the outer AND and let reload
03474      convert the offset address into an indirect address.  */
03475   if (TARGET_ALTIVEC
03476       && ALTIVEC_VECTOR_MODE (mode)
03477       && GET_CODE (x) == AND
03478       && GET_CODE (XEXP (x, 0)) == PLUS
03479       && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
03480       && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
03481       && GET_CODE (XEXP (x, 1)) == CONST_INT
03482       && INTVAL (XEXP (x, 1)) == -16)
03483     {
03484       x = XEXP (x, 0);
03485       *win = 1;
03486       return x;
03487     }
03488 
03489   if (TARGET_TOC
03490       && constant_pool_expr_p (x)
03491       && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
03492     {
03493       x = create_TOC_reference (x);
03494       *win = 1;
03495       return x;
03496     }
03497   *win = 0;
03498   return x;
03499 }
03500 
03501 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
03502    that is a valid memory address for an instruction.
03503    The MODE argument is the machine mode for the MEM expression
03504    that wants to use this address.
03505 
03506    On the RS/6000, there are four valid address: a SYMBOL_REF that
03507    refers to a constant pool entry of an address (or the sum of it
03508    plus a constant), a short (16-bit signed) constant plus a register,
03509    the sum of two registers, or a register indirect, possibly with an
03510    auto-increment.  For DFmode and DImode with a constant plus register,
03511    we must ensure that both words are addressable or PowerPC64 with offset
03512    word aligned.
03513 
03514    For modes spanning multiple registers (DFmode in 32-bit GPRs,
03515    32-bit DImode, TImode, TFmode), indexed addressing cannot be used because
03516    adjacent memory cells are accessed by adding word-sized offsets
03517    during assembly output.  */
03518 int
03519 rs6000_legitimate_address (enum machine_mode mode, rtx x, int reg_ok_strict)
03520 {
03521   /* If this is an unaligned stvx/ldvx type address, discard the outer AND.  */
03522   if (TARGET_ALTIVEC
03523       && ALTIVEC_VECTOR_MODE (mode)
03524       && GET_CODE (x) == AND
03525       && GET_CODE (XEXP (x, 1)) == CONST_INT
03526       && INTVAL (XEXP (x, 1)) == -16)
03527     x = XEXP (x, 0);
03528 
03529   if (RS6000_SYMBOL_REF_TLS_P (x))
03530     return 0;
03531   if (legitimate_indirect_address_p (x, reg_ok_strict))
03532     return 1;
03533   if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
03534       && !ALTIVEC_VECTOR_MODE (mode)
03535       && !SPE_VECTOR_MODE (mode)
03536       && mode != TFmode
03537       /* Restrict addressing for DI because of our SUBREG hackery.  */
03538       && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == DImode))
03539       && TARGET_UPDATE
03540       && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
03541     return 1;
03542   if (legitimate_small_data_p (mode, x))
03543     return 1;
03544   if (legitimate_constant_pool_address_p (x))
03545     return 1;
03546   /* If not REG_OK_STRICT (before reload) let pass any stack offset.  */
03547   if (! reg_ok_strict
03548       && GET_CODE (x) == PLUS
03549       && GET_CODE (XEXP (x, 0)) == REG
03550       && (XEXP (x, 0) == virtual_stack_vars_rtx
03551     || XEXP (x, 0) == arg_pointer_rtx)
03552       && GET_CODE (XEXP (x, 1)) == CONST_INT)
03553     return 1;
03554   if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
03555     return 1;
03556   if (mode != TImode
03557       && mode != TFmode
03558       && ((TARGET_HARD_FLOAT && TARGET_FPRS)
03559     || TARGET_POWERPC64
03560     || ((mode != DFmode || TARGET_E500_DOUBLE) && mode != TFmode))
03561       && (TARGET_POWERPC64 || mode != DImode)
03562       && legitimate_indexed_address_p (x, reg_ok_strict))
03563     return 1;
03564   if (legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
03565     return 1;
03566   return 0;
03567 }
03568 
03569 /* Go to LABEL if ADDR (a legitimate address expression)
03570    has an effect that depends on the machine mode it is used for.
03571 
03572    On the RS/6000 this is true of all integral offsets (since AltiVec
03573    modes don't allow them) or is a pre-increment or decrement.
03574 
03575    ??? Except that due to conceptual problems in offsettable_address_p
03576    we can't really report the problems of integral offsets.  So leave
03577    this assuming that the adjustable offset must be valid for the
03578    sub-words of a TFmode operand, which is what we had before.  */
03579 
03580 bool
03581 rs6000_mode_dependent_address (rtx addr)
03582 {
03583   switch (GET_CODE (addr))
03584     {
03585     case PLUS:
03586       if (GET_CODE (XEXP (addr, 1)) == CONST_INT)
03587   {
03588     unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
03589     return val + 12 + 0x8000 >= 0x10000;
03590   }
03591       break;
03592 
03593     case LO_SUM:
03594       return true;
03595 
03596     case PRE_INC:
03597     case PRE_DEC:
03598       return TARGET_UPDATE;
03599 
03600     default:
03601       break;
03602     }
03603 
03604   return false;
03605 }
03606 
03607 /* More elaborate version of recog's offsettable_memref_p predicate
03608    that works around the ??? note of rs6000_mode_dependent_address.
03609    In particular it accepts
03610 
03611      (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
03612 
03613    in 32-bit mode, that the recog predicate rejects.  */
03614 
03615 bool
03616 rs6000_offsettable_memref_p (rtx op)
03617 {
03618   if (!MEM_P (op))
03619     return false;
03620 
03621   /* First mimic offsettable_memref_p.  */
03622   if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
03623     return true;
03624 
03625   /* offsettable_address_p invokes rs6000_mode_dependent_address, but
03626      the latter predicate knows nothing about the mode of the memory
03627      reference and, therefore, assumes that it is the largest supported
03628      mode (TFmode).  As a consequence, legitimate offsettable memory
03629      references are rejected.  rs6000_legitimate_offset_address_p contains
03630      the correct logic for the PLUS case of rs6000_mode_dependent_address.  */
03631   return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
03632 }
03633 
03634 /* Return number of consecutive hard regs needed starting at reg REGNO
03635    to hold something of mode MODE.
03636    This is ordinarily the length in words of a value of mode MODE
03637    but can be less for certain modes in special long registers.
03638 
03639    For the SPE, GPRs are 64 bits but only 32 bits are visible in
03640    scalar instructions.  The upper 32 bits are only available to the
03641    SIMD instructions.
03642 
03643    POWER and PowerPC GPRs hold 32 bits worth;
03644    PowerPC64 GPRs and FPRs point register holds 64 bits worth.  */
03645 
03646 int
03647 rs6000_hard_regno_nregs (int regno, enum machine_mode mode)
03648 {
03649   if (FP_REGNO_P (regno))
03650     return (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
03651 
03652   if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
03653     return (GET_MODE_SIZE (mode) + UNITS_PER_SPE_WORD - 1) / UNITS_PER_SPE_WORD;
03654 
03655   if (ALTIVEC_REGNO_P (regno))
03656     return
03657       (GET_MODE_SIZE (mode) + UNITS_PER_ALTIVEC_WORD - 1) / UNITS_PER_ALTIVEC_WORD;
03658 
03659   /* The value returned for SCmode in the E500 double case is 2 for
03660      ABI compatibility; storing an SCmode value in a single register
03661      would require function_arg and rs6000_spe_function_arg to handle
03662      SCmode so as to pass the value correctly in a pair of
03663      registers.  */
03664   if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode)
03665     return (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
03666 
03667   return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
03668 }
03669 
03670 /* Change register usage conditional on target flags.  */
03671 void
03672 rs6000_conditional_register_usage (void)
03673 {
03674   int i;
03675 
03676   /* Set MQ register fixed (already call_used) if not POWER
03677      architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
03678      be allocated.  */
03679   if (! TARGET_POWER)
03680     fixed_regs[64] = 1;
03681 
03682   /* 64-bit AIX and Linux reserve GPR13 for thread-private data.  */
03683   if (TARGET_64BIT)
03684     fixed_regs[13] = call_used_regs[13]
03685       = call_really_used_regs[13] = 1;
03686 
03687   /* Conditionally disable FPRs.  */
03688   if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
03689     for (i = 32; i < 64; i++)
03690       fixed_regs[i] = call_used_regs[i]
03691   = call_really_used_regs[i] = 1;
03692 
03693   /* The TOC register is not killed across calls in a way that is
03694      visible to the compiler.  */
03695   if (DEFAULT_ABI == ABI_AIX)
03696     call_really_used_regs[2] = 0;
03697 
03698   if (DEFAULT_ABI == ABI_V4
03699       && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
03700       && flag_pic == 2)
03701     fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
03702 
03703   if (DEFAULT_ABI == ABI_V4
03704       && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
03705       && flag_pic == 1)
03706     fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
03707       = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
03708       = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
03709 
03710   if (DEFAULT_ABI == ABI_DARWIN
03711       && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
03712       fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
03713       = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
03714       = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
03715 
03716   if (TARGET_TOC && TARGET_MINIMAL_TOC)
03717     fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
03718       = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
03719 
03720   if (TARGET_ALTIVEC)
03721     global_regs[VSCR_REGNO] = 1;
03722 
03723   if (TARGET_SPE)
03724     {
03725       global_regs[SPEFSCR_REGNO] = 1;
03726       fixed_regs[FIXED_SCRATCH]
03727   = call_used_regs[FIXED_SCRATCH]
03728   = call_really_used_regs[FIXED_SCRATCH] = 1;
03729     }
03730 
03731   if (! TARGET_ALTIVEC)
03732     {
03733       for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
03734   fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
03735       call_really_used_regs[VRSAVE_REGNO] = 1;
03736     }
03737 
03738   if (TARGET_ALTIVEC_ABI)
03739     for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
03740       call_used_regs[i] = call_really_used_regs[i] = 1;
03741 }
03742 
03743 /* Try to output insns to set TARGET equal to the constant C if it can
03744    be done in less than N insns.  Do all computations in MODE.
03745    Returns the place where the output has been placed if it can be
03746    done and the insns have been emitted.  If it would take more than N
03747    insns, zero is returned and no insns and emitted.  */
03748 
03749 rtx
03750 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
03751            rtx source, int n ATTRIBUTE_UNUSED)
03752 {
03753   rtx result, insn, set;
03754   HOST_WIDE_INT c0, c1;
03755 
03756   switch (mode)
03757     {
03758       case  QImode:
03759     case HImode:
03760       if (dest == NULL)
03761   dest = gen_reg_rtx (mode);
03762       emit_insn (gen_rtx_SET (VOIDmode, dest, source));
03763       return dest;
03764 
03765     case SImode:
03766       result = no_new_pseudos ? dest : gen_reg_rtx (SImode);
03767 
03768       emit_insn (gen_rtx_SET (VOIDmode, result,
03769             GEN_INT (INTVAL (source)
03770                & (~ (HOST_WIDE_INT) 0xffff))));
03771       emit_insn (gen_rtx_SET (VOIDmode, dest,
03772             gen_rtx_IOR (SImode, result,
03773              GEN_INT (INTVAL (source) & 0xffff))));
03774       result = dest;
03775       break;
03776 
03777     case DImode:
03778       switch (GET_CODE (source))
03779   {
03780   case CONST_INT:
03781     c0 = INTVAL (source);
03782     c1 = -(c0 < 0);
03783     break;
03784 
03785   case CONST_DOUBLE:
03786 #if HOST_BITS_PER_WIDE_INT >= 64
03787     c0 = CONST_DOUBLE_LOW (source);
03788     c1 = -(c0 < 0);
03789 #else
03790     c0 = CONST_DOUBLE_LOW (source);
03791     c1 = CONST_DOUBLE_HIGH (source);
03792 #endif
03793     break;
03794 
03795   default:
03796     gcc_unreachable ();
03797   }
03798 
03799       result = rs6000_emit_set_long_const (dest, c0, c1);
03800       break;
03801 
03802     default:
03803       gcc_unreachable ();
03804     }
03805 
03806   insn = get_last_insn ();
03807   set = single_set (insn);
03808   if (! CONSTANT_P (SET_SRC (set)))
03809     set_unique_reg_note (insn, REG_EQUAL, source);
03810 
03811   return result;
03812 }
03813 
03814 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
03815    fall back to a straight forward decomposition.  We do this to avoid
03816    exponential run times encountered when looking for longer sequences
03817    with rs6000_emit_set_const.  */
03818 static rtx
03819 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
03820 {
03821   if (!TARGET_POWERPC64)
03822     {
03823       rtx operand1, operand2;
03824 
03825       operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
03826           DImode);
03827       operand2 = operand_subword_force (dest, WORDS_BIG_ENDIAN != 0,
03828           DImode);
03829       emit_move_insn (operand1, GEN_INT (c1));
03830       emit_move_insn (operand2, GEN_INT (c2));
03831     }
03832   else
03833     {
03834       HOST_WIDE_INT ud1, ud2, ud3, ud4;
03835 
03836       ud1 = c1 & 0xffff;
03837       ud2 = (c1 & 0xffff0000) >> 16;
03838 #if HOST_BITS_PER_WIDE_INT >= 64
03839       c2 = c1 >> 32;
03840 #endif
03841       ud3 = c2 & 0xffff;
03842       ud4 = (c2 & 0xffff0000) >> 16;
03843 
03844       if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
03845     || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
03846   {
03847     if (ud1 & 0x8000)
03848       emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) -  0x8000)));
03849     else
03850       emit_move_insn (dest, GEN_INT (ud1));
03851   }
03852 
03853       else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
03854          || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
03855   {
03856     if (ud2 & 0x8000)
03857       emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
03858              - 0x80000000));
03859     else
03860       emit_move_insn (dest, GEN_INT (ud2 << 16));
03861     if (ud1 != 0)
03862       emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
03863   }
03864       else if ((ud4 == 0xffff && (ud3 & 0x8000))
03865          || (ud4 == 0 && ! (ud3 & 0x8000)))
03866   {
03867     if (ud3 & 0x8000)
03868       emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
03869              - 0x80000000));
03870     else
03871       emit_move_insn (dest, GEN_INT (ud3 << 16));
03872 
03873     if (ud2 != 0)
03874       emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud2)));
03875     emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (16)));
03876     if (ud1 != 0)
03877       emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
03878   }
03879       else
03880   {
03881     if (ud4 & 0x8000)
03882       emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
03883              - 0x80000000));
03884     else
03885       emit_move_insn (dest, GEN_INT (ud4 << 16));
03886 
03887     if (ud3 != 0)
03888       emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud3)));
03889 
03890     emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (32)));
03891     if (ud2 != 0)
03892       emit_move_insn (dest, gen_rtx_IOR (DImode, dest,
03893                  GEN_INT (ud2 << 16)));
03894     if (ud1 != 0)
03895       emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
03896   }
03897     }
03898   return dest;
03899 }
03900 
03901 /* Helper for the following.  Get rid of [r+r] memory refs
03902    in cases where it won't work (TImode, TFmode).  */
03903 
03904 static void
03905 rs6000_eliminate_indexed_memrefs (rtx operands[2])
03906 {
03907   if (GET_CODE (operands[0]) == MEM
03908       && GET_CODE (XEXP (operands[0], 0)) != REG
03909       && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0))
03910       && ! reload_in_progress)
03911     operands[0]
03912       = replace_equiv_address (operands[0],
03913              copy_addr_to_reg (XEXP (operands[0], 0)));
03914 
03915   if (GET_CODE (operands[1]) == MEM
03916       && GET_CODE (XEXP (operands[1], 0)) != REG
03917       && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0))
03918       && ! reload_in_progress)
03919     operands[1]
03920       = replace_equiv_address (operands[1],
03921              copy_addr_to_reg (XEXP (operands[1], 0)));
03922 }
03923 
03924 /* Emit a move from SOURCE to DEST in mode MODE.  */
03925 void
03926 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
03927 {
03928   rtx operands[2];
03929   operands[0] = dest;
03930   operands[1] = source;
03931 
03932   /* Sanity checks.  Check that we get CONST_DOUBLE only when we should.  */
03933   if (GET_CODE (operands[1]) == CONST_DOUBLE
03934       && ! FLOAT_MODE_P (mode)
03935       && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
03936     {
03937       /* FIXME.  This should never happen.  */
03938       /* Since it seems that it does, do the safe thing and convert
03939    to a CONST_INT.  */
03940       operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
03941     }
03942   gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
03943         || FLOAT_MODE_P (mode)
03944         || ((CONST_DOUBLE_HIGH (operands[1]) != 0
03945        || CONST_DOUBLE_LOW (operands[1]) < 0)
03946       && (CONST_DOUBLE_HIGH (operands[1]) != -1
03947           || CONST_DOUBLE_LOW (operands[1]) >= 0)));
03948 
03949   /* Check if GCC is setting up a block move that will end up using FP
03950      registers as temporaries.  We must make sure this is acceptable.  */
03951   if (GET_CODE (operands[0]) == MEM
03952       && GET_CODE (operands[1]) == MEM
03953       && mode == DImode
03954       && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
03955     || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
03956       && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
03957               ? 32 : MEM_ALIGN (operands[0])))
03958       || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
03959                  ? 32
03960                  : MEM_ALIGN (operands[1]))))
03961       && ! MEM_VOLATILE_P (operands [0])
03962       && ! MEM_VOLATILE_P (operands [1]))
03963     {
03964       emit_move_insn (adjust_address (operands[0], SImode, 0),
03965           adjust_address (operands[1], SImode, 0));
03966       emit_move_insn (adjust_address (operands[0], SImode, 4),
03967           adjust_address (operands[1], SImode, 4));
03968       return;
03969     }
03970 
03971   if (!no_new_pseudos && GET_CODE (operands[0]) == MEM
03972       && !gpc_reg_operand (operands[1], mode))
03973     operands[1] = force_reg (mode, operands[1]);
03974 
03975   if (mode == SFmode && ! TARGET_POWERPC
03976       && TARGET_HARD_FLOAT && TARGET_FPRS
03977       && GET_CODE (operands[0]) == MEM)
03978     {
03979       int regnum;
03980 
03981       if (reload_in_progress || reload_completed)
03982   regnum = true_regnum (operands[1]);
03983       else if (GET_CODE (operands[1]) == REG)
03984   regnum = REGNO (operands[1]);
03985       else
03986   regnum = -1;
03987 
03988       /* If operands[1] is a register, on POWER it may have
03989    double-precision data in it, so truncate it to single
03990    precision.  */
03991       if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
03992   {
03993     rtx newreg;
03994     newreg = (no_new_pseudos ? operands[1] : gen_reg_rtx (mode));
03995     emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
03996     operands[1] = newreg;
03997   }
03998     }
03999 
04000   /* Recognize the case where operand[1] is a reference to thread-local
04001      data and load its address to a register.  */
04002   if (rs6000_tls_referenced_p (operands[1]))
04003     {
04004       enum tls_model model;
04005       rtx tmp = operands[1];
04006       rtx addend = NULL;
04007 
04008       if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
04009   {
04010           addend = XEXP (XEXP (tmp, 0), 1);
04011     tmp = XEXP (XEXP (tmp, 0), 0);
04012   }
04013 
04014       gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
04015       model = SYMBOL_REF_TLS_MODEL (tmp);
04016       gcc_assert (model != 0);
04017 
04018       tmp = rs6000_legitimize_tls_address (tmp, model);
04019       if (addend)
04020   {
04021     tmp = gen_rtx_PLUS (mode, tmp, addend);
04022     tmp = force_operand (tmp, operands[0]);
04023   }
04024       operands[1] = tmp;
04025     }
04026 
04027   /* Handle the case where reload calls us with an invalid address.  */
04028   if (reload_in_progress && mode == Pmode
04029       && (! general_operand (operands[1], mode)
04030     || ! nonimmediate_operand (operands[0], mode)))
04031     goto emit_set;
04032 
04033   /* 128-bit constant floating-point values on Darwin should really be
04034      loaded as two parts.  */
04035   if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
04036       && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
04037     {
04038       /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
04039    know how to get a DFmode SUBREG of a TFmode.  */
04040       rs6000_emit_move (simplify_gen_subreg (DImode, operands[0], mode, 0),
04041       simplify_gen_subreg (DImode, operands[1], mode, 0),
04042       DImode);
04043       rs6000_emit_move (simplify_gen_subreg (DImode, operands[0], mode,
04044                GET_MODE_SIZE (DImode)),
04045       simplify_gen_subreg (DImode, operands[1], mode,
04046                GET_MODE_SIZE (DImode)),
04047       DImode);
04048       return;
04049     }
04050 
04051   /* FIXME:  In the long term, this switch statement should go away
04052      and be replaced by a sequence of tests based on things like
04053      mode == Pmode.  */
04054   switch (mode)
04055     {
04056     case HImode:
04057     case QImode:
04058       if (CONSTANT_P (operands[1])
04059     && GET_CODE (operands[1]) != CONST_INT)
04060   operands[1] = force_const_mem (mode, operands[1]);
04061       break;
04062 
04063     case TFmode:
04064       rs6000_eliminate_indexed_memrefs (operands);
04065       /* fall through */
04066 
04067     case DFmode:
04068     case SFmode:
04069       if (CONSTANT_P (operands[1])
04070     && ! easy_fp_constant (operands[1], mode))
04071   operands[1] = force_const_mem (mode, operands[1]);
04072       break;
04073 
04074     case V16QImode:
04075     case V8HImode:
04076     case V4SFmode:
04077     case V4SImode:
04078     case V4HImode:
04079     case V2SFmode:
04080     case V2SImode:
04081     case V1DImode:
04082       if (CONSTANT_P (operands[1])
04083     && !easy_vector_constant (operands[1], mode))
04084   operands[1] = force_const_mem (mode, operands[1]);
04085       break;
04086 
04087     case SImode:
04088     case DImode:
04089       /* Use default pattern for address of ELF small data */
04090       if (TARGET_ELF
04091     && mode == Pmode
04092     && DEFAULT_ABI == ABI_V4
04093     && (GET_CODE (operands[1]) == SYMBOL_REF
04094         || GET_CODE (operands[1]) == CONST)
04095     && small_data_operand (operands[1], mode))
04096   {
04097     emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
04098     return;
04099   }
04100 
04101       if (DEFAULT_ABI == ABI_V4
04102     && mode == Pmode && mode == SImode
04103     && flag_pic == 1 && got_operand (operands[1], mode))
04104   {
04105     emit_insn (gen_movsi_got (operands[0], operands[1]));
04106     return;
04107   }
04108 
04109       if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
04110     && TARGET_NO_TOC
04111     && ! flag_pic
04112     && mode == Pmode
04113     && CONSTANT_P (operands[1])
04114     && GET_CODE (operands[1]) != HIGH
04115     && GET_CODE (operands[1]) != CONST_INT)
04116   {
04117     rtx target = (no_new_pseudos ? operands[0] : gen_reg_rtx (mode));
04118 
04119     /* If this is a function address on -mcall-aixdesc,
04120        convert it to the address of the descriptor.  */
04121     if (DEFAULT_ABI == ABI_AIX
04122         && GET_CODE (operands[1]) == SYMBOL_REF
04123         && XSTR (operands[1], 0)[0] == '.')
04124       {
04125         const char *name = XSTR (operands[1], 0);
04126         rtx new_ref;
04127         while (*name == '.')
04128     name++;
04129         new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
04130         CONSTANT_POOL_ADDRESS_P (new_ref)
04131     = CONSTANT_POOL_ADDRESS_P (operands[1]);
04132         SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
04133         SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
04134         SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
04135         operands[1] = new_ref;
04136       }
04137 
04138     if (DEFAULT_ABI == ABI_DARWIN)
04139       {
04140 #if TARGET_MACHO
04141         if (MACHO_DYNAMIC_NO_PIC_P)
04142     {
04143       /* Take care of any required data indirection.  */
04144       operands[1] = rs6000_machopic_legitimize_pic_address (
04145           operands[1], mode, operands[0]);
04146       if (operands[0] != operands[1])
04147         emit_insn (gen_rtx_SET (VOIDmode,
04148               operands[0], operands[1]));
04149       return;
04150     }
04151 #endif
04152         emit_insn (gen_macho_high (target, operands[1]));
04153         emit_insn (gen_macho_low (operands[0], target, operands[1]));
04154         return;
04155       }
04156 
04157     emit_insn (gen_elf_high (target, operands[1]));
04158     emit_insn (gen_elf_low (operands[0], target, operands[1]));
04159     return;
04160   }
04161 
04162       /* If this is a SYMBOL_REF that refers to a constant pool entry,
04163    and we have put it in the TOC, we just need to make a TOC-relative
04164    reference to it.  */
04165       if (TARGET_TOC
04166     && GET_CODE (operands[1]) == SYMBOL_REF
04167     && constant_pool_expr_p (operands[1])
04168     && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
04169                 get_pool_mode (operands[1])))
04170   {
04171     operands[1] = create_TOC_reference (operands[1]);
04172   }
04173       else if (mode == Pmode
04174          && CONSTANT_P (operands[1])
04175          && ((GET_CODE (operands[1]) != CONST_INT
04176         && ! easy_fp_constant (operands[1], mode))
04177        || (GET_CODE (operands[1]) == CONST_INT
04178            && num_insns_constant (operands[1], mode) > 2)
04179        || (GET_CODE (operands[0]) == REG
04180            && FP_REGNO_P (REGNO (operands[0]))))
04181          && GET_CODE (operands[1]) != HIGH
04182          && ! legitimate_constant_pool_address_p (operands[1])
04183          && ! toc_relative_expr_p (operands[1]))
04184   {
04185     /* Emit a USE operation so that the constant isn't deleted if
04186        expensive optimizations are turned on because nobody
04187        references it.  This should only be done for operands that
04188        contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set.
04189        This should not be done for operands that contain LABEL_REFs.
04190        For now, we just handle the obvious case.  */
04191     if (GET_CODE (operands[1]) != LABEL_REF)
04192       emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
04193 
04194 #if TARGET_MACHO
04195     /* Darwin uses a special PIC legitimizer.  */
04196     if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
04197       {
04198         operands[1] =
04199     rs6000_machopic_legitimize_pic_address (operands[1], mode,
04200               operands[0]);
04201         if (operands[0] != operands[1])
04202     emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
04203         return;
04204       }
04205 #endif
04206 
04207     /* If we are to limit the number of things we put in the TOC and
04208        this is a symbol plus a constant we can add in one insn,
04209        just put the symbol in the TOC and add the constant.  Don't do
04210        this if reload is in progress.  */
04211     if (GET_CODE (operands[1]) == CONST
04212         && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
04213         && GET_CODE (XEXP (operands[1], 0)) == PLUS
04214         && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
04215         && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
04216       || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
04217         && ! side_effects_p (operands[0]))
04218       {
04219         rtx sym =
04220     force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
04221         rtx other = XEXP (XEXP (operands[1], 0), 1);
04222 
04223         sym = force_reg (mode, sym);
04224         if (mode == SImode)
04225     emit_insn (gen_addsi3 (operands[0], sym, other));
04226         else
04227     emit_insn (gen_adddi3 (operands[0], sym, other));
04228         return;
04229       }
04230 
04231     operands[1] = force_const_mem (mode, operands[1]);
04232 
04233     if (TARGET_TOC
04234         && constant_pool_expr_p (XEXP (operands[1], 0))
04235         && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
04236       get_pool_constant (XEXP (operands[1], 0)),
04237       get_pool_mode (XEXP (operands[1], 0))))
04238       {
04239         operands[1]
04240     = gen_const_mem (mode,
04241          create_TOC_reference (XEXP (operands[1], 0)));
04242         set_mem_alias_set (operands[1], get_TOC_alias_set ());
04243       }
04244   }
04245       break;
04246 
04247     case TImode:
04248       rs6000_eliminate_indexed_memrefs (operands);
04249 
04250       if (TARGET_POWER)
04251   {
04252     emit_insn (gen_rtx_PARALLEL (VOIDmode,
04253            gen_rtvec (2,
04254           gen_rtx_SET (VOIDmode,
04255                  operands[0], operands[1]),
04256           gen_rtx_CLOBBER (VOIDmode,
04257                gen_rtx_SCRATCH (SImode)))));
04258     return;
04259   }
04260       break;
04261 
04262     default:
04263       gcc_unreachable ();
04264     }
04265 
04266   /* Above, we may have called force_const_mem which may have returned
04267      an invalid address.  If we can, fix this up; otherwise, reload will
04268      have to deal with it.  */
04269   if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
04270     operands[1] = validize_mem (operands[1]);
04271 
04272  emit_set:
04273   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
04274 }
04275 
04276 /* Nonzero if we can use a floating-point register to pass this arg.  */
04277 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE)   \
04278   (SCALAR_FLOAT_MODE_P (MODE)     \
04279    && !DECIMAL_FLOAT_MODE_P (MODE)    \
04280    && (CUM)->fregno <= FP_ARG_MAX_REG   \
04281    && TARGET_HARD_FLOAT && TARGET_FPRS)
04282 
04283 /* Nonzero if we can use an AltiVec register to pass this arg.  */
04284 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED)  \
04285   (ALTIVEC_VECTOR_MODE (MODE)       \
04286    && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG    \
04287    && TARGET_ALTIVEC_ABI        \
04288    && (NAMED))
04289 
04290 /* Return a nonzero value to say to return the function value in
04291    memory, just as large structures are always returned.  TYPE will be
04292    the data type of the value, and FNTYPE will be the type of the
04293    function doing the returning, or @code{NULL} for libcalls.
04294 
04295    The AIX ABI for the RS/6000 specifies that all structures are
04296    returned in memory.  The Darwin ABI does the same.  The SVR4 ABI
04297    specifies that structures <= 8 bytes are returned in r3/r4, but a
04298    draft put them in memory, and GCC used to implement the draft
04299    instead of the final standard.  Therefore, aix_struct_return
04300    controls this instead of DEFAULT_ABI; V.4 targets needing backward
04301    compatibility can change DRAFT_V4_STRUCT_RET to override the
04302    default, and -m switches get the final word.  See
04303    rs6000_override_options for more details.
04304 
04305    The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
04306    long double support is enabled.  These values are returned in memory.
04307 
04308    int_size_in_bytes returns -1 for variable size objects, which go in
04309    memory always.  The cast to unsigned makes -1 > 8.  */
04310 
04311 static bool
04312 rs6000_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
04313 {
04314   /* In the darwin64 abi, try to use registers for larger structs
04315      if possible.  */
04316   if (rs6000_darwin64_abi
04317       && TREE_CODE (type) == RECORD_TYPE
04318       && int_size_in_bytes (type) > 0)
04319     {
04320       CUMULATIVE_ARGS valcum;
04321       rtx valret;
04322 
04323       valcum.words = 0;
04324       valcum.fregno = FP_ARG_MIN_REG;
04325       valcum.vregno = ALTIVEC_ARG_MIN_REG;
04326       /* Do a trial code generation as if this were going to be passed
04327    as an argument; if any part goes in memory, we return NULL.  */
04328       valret = rs6000_darwin64_record_arg (&valcum, type, 1, true);
04329       if (valret)
04330   return false;
04331       /* Otherwise fall through to more conventional ABI rules.  */
04332     }
04333 
04334   if (AGGREGATE_TYPE_P (type)
04335       && (aix_struct_return
04336     || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
04337     return true;
04338 
04339   /* Allow -maltivec -mabi=no-altivec without warning.  Altivec vector
04340      modes only exist for GCC vector types if -maltivec.  */
04341   if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
04342       && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
04343     return false;
04344 
04345   /* Return synthetic vectors in memory.  */
04346   if (TREE_CODE (type) == VECTOR_TYPE
04347       && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
04348     {
04349       static bool warned_for_return_big_vectors = false;
04350       if (!warned_for_return_big_vectors)
04351   {
04352     warning (0, "GCC vector returned by reference: "
04353        "non-standard ABI extension with no compatibility guarantee");
04354     warned_for_return_big_vectors = true;
04355   }
04356       return true;
04357     }
04358 
04359   if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
04360     return true;
04361 
04362   return false;
04363 }
04364 
04365 /* Initialize a variable CUM of type CUMULATIVE_ARGS
04366    for a call to a function whose data type is FNTYPE.
04367    For a library call, FNTYPE is 0.
04368 
04369    For incoming args we set the number of arguments in the prototype large
04370    so we never return a PARALLEL.  */
04371 
04372 void
04373 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
04374           rtx libname ATTRIBUTE_UNUSED, int incoming,
04375           int libcall, int n_named_args)
04376 {
04377   static CUMULATIVE_ARGS zero_cumulative;
04378 
04379   *cum = zero_cumulative;
04380   cum->words = 0;
04381   cum->fregno = FP_ARG_MIN_REG;
04382   cum->vregno = ALTIVEC_ARG_MIN_REG;
04383   cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
04384   cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
04385           ? CALL_LIBCALL : CALL_NORMAL);
04386   cum->sysv_gregno = GP_ARG_MIN_REG;
04387   cum->stdarg = fntype
04388     && (TYPE_ARG_TYPES (fntype) != 0
04389   && (TREE_VALUE (tree_last  (TYPE_ARG_TYPES (fntype)))
04390       != void_type_node));
04391 
04392   cum->nargs_prototype = 0;
04393   if (incoming || cum->prototype)
04394     cum->nargs_prototype = n_named_args;
04395 
04396   /* Check for a longcall attribute.  */
04397   if ((!fntype && rs6000_default_long_calls)
04398       || (fntype
04399     && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
04400     && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
04401     cum->call_cookie |= CALL_LONG;
04402 
04403   if (TARGET_DEBUG_ARG)
04404     {
04405       fprintf (stderr, "\ninit_cumulative_args:");
04406       if (fntype)
04407   {
04408     tree ret_type = TREE_TYPE (fntype);
04409     fprintf (stderr, " ret code = %s,",
04410        tree_code_name[ (int)TREE_CODE (ret_type) ]);
04411   }
04412 
04413       if (cum->call_cookie & CALL_LONG)
04414   fprintf (stderr, " longcall,");
04415 
04416       fprintf (stderr, " proto = %d, nargs = %d\n",
04417          cum->prototype, cum->nargs_prototype);
04418     }
04419 
04420   if (fntype
04421       && !TARGET_ALTIVEC
04422       && TARGET_ALTIVEC_ABI
04423       && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
04424     {
04425       error ("cannot return value in vector register because"
04426        " altivec instructions are disabled, use -maltivec"
04427        " to enable them");
04428     }
04429 }
04430 
04431 /* Return true if TYPE must be passed on the stack and not in registers.  */
04432 
04433 static bool
04434 rs6000_must_pass_in_stack (enum machine_mode mode, tree type)
04435 {
04436   if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
04437     return must_pass_in_stack_var_size (mode, type);
04438   else
04439     return must_pass_in_stack_var_size_or_pad (mode, type);
04440 }
04441 
04442 /* If defined, a C expression which determines whether, and in which
04443    direction, to pad out an argument with extra space.  The value
04444    should be of type `enum direction': either `upward' to pad above
04445    the argument, `downward' to pad below, or `none' to inhibit
04446    padding.
04447 
04448    For the AIX ABI structs are always stored left shifted in their
04449    argument slot.  */
04450 
04451 enum direction
04452 function_arg_padding (enum machine_mode mode, tree type)
04453 {
04454 #ifndef AGGREGATE_PADDING_FIXED
04455 #define AGGREGATE_PADDING_FIXED 0
04456 #endif
04457 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
04458 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
04459 #endif
04460 
04461   if (!AGGREGATE_PADDING_FIXED)
04462     {
04463       /* GCC used to pass structures of the same size as integer types as
04464    if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
04465    i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
04466    passed padded downward, except that -mstrict-align further
04467    muddied the water in that multi-component structures of 2 and 4
04468    bytes in size were passed padded upward.
04469 
04470    The following arranges for best compatibility with previous
04471    versions of gcc, but removes the -mstrict-align dependency.  */
04472       if (BYTES_BIG_ENDIAN)
04473   {
04474     HOST_WIDE_INT size = 0;
04475 
04476     if (mode == BLKmode)
04477       {
04478         if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
04479     size = int_size_in_bytes (type);
04480       }
04481     else
04482       size = GET_MODE_SIZE (mode);
04483 
04484     if (size == 1 || size == 2 || size == 4)
04485       return downward;
04486   }
04487       return upward;
04488     }
04489 
04490   if (AGGREGATES_PAD_UPWARD_ALWAYS)
04491     {
04492       if (type != 0 && AGGREGATE_TYPE_P (type))
04493   return upward;
04494     }
04495 
04496   /* Fall back to the default.  */
04497   return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
04498 }
04499 
04500 /* If defined, a C expression that gives the alignment boundary, in bits,
04501    of an argument with the specified mode and type.  If it is not defined,
04502    PARM_BOUNDARY is used for all arguments.
04503 
04504    V.4 wants long longs and doubles to be double word aligned.  Just
04505    testing the mode size is a boneheaded way to do this as it means
04506    that other types such as complex int are also double word aligned.
04507    However, we're stuck with this because changing the ABI might break
04508    existing library interfaces.
04509 
04510    Doubleword align SPE vectors.
04511    Quadword align Altivec vectors.
04512    Quadword align large synthetic vector types.   */
04513 
04514 int
04515 function_arg_boundary (enum machine_mode mode, tree type)
04516 {
04517   if (DEFAULT_ABI == ABI_V4
04518       && (GET_MODE_SIZE (mode) == 8
04519     || (TARGET_HARD_FLOAT
04520         && TARGET_FPRS
04521         && mode == TFmode)))
04522     return 64;
04523   else if (SPE_VECTOR_MODE (mode)
04524      || (type && TREE_CODE (type) == VECTOR_TYPE
04525          && int_size_in_bytes (type) >= 8
04526          && int_size_in_bytes (type) < 16))
04527     return 64;
04528   else if (ALTIVEC_VECTOR_MODE (mode)
04529      || (type && TREE_CODE (type) == VECTOR_TYPE
04530          && int_size_in_bytes (type) >= 16))
04531     return 128;
04532   else if (rs6000_darwin64_abi && mode == BLKmode
04533      && type && TYPE_ALIGN (type) > 64)
04534     return 128;
04535   else
04536     return PARM_BOUNDARY;
04537 }
04538 
04539 /* For a function parm of MODE and TYPE, return the starting word in
04540    the parameter area.  NWORDS of the parameter area are already used.  */
04541 
04542 static unsigned int
04543 rs6000_parm_start (enum machine_mode mode, tree type, unsigned int nwords)
04544 {
04545   unsigned int align;
04546   unsigned int parm_offset;
04547 
04548   align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
04549   parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
04550   return nwords + (-(parm_offset + nwords) & align);
04551 }
04552 
04553 /* Compute the size (in words) of a function argument.  */
04554 
04555 static unsigned long
04556 rs6000_arg_size (enum machine_mode mode, tree type)
04557 {
04558   unsigned long size;
04559 
04560   if (mode != BLKmode)
04561     size = GET_MODE_SIZE (mode);
04562   else
04563     size = int_size_in_bytes (type);
04564 
04565   if (TARGET_32BIT)
04566     return (size + 3) >> 2;
04567   else
04568     return (size + 7) >> 3;
04569 }
04570 
04571 /* Use this to flush pending int fields.  */
04572 
04573 static void
04574 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
04575             HOST_WIDE_INT bitpos)
04576 {
04577   unsigned int startbit, endbit;
04578   int intregs, intoffset;
04579   enum machine_mode mode;
04580 
04581   if (cum->intoffset == -1)
04582     return;
04583 
04584   intoffset = cum->intoffset;
04585   cum->intoffset = -1;
04586 
04587   if (intoffset % BITS_PER_WORD != 0)
04588     {
04589       mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
04590           MODE_INT, 0);
04591       if (mode == BLKmode)
04592   {
04593     /* We couldn't find an appropriate mode, which happens,
04594        e.g., in packed structs when there are 3 bytes to load.
04595        Back intoffset back to the beginning of the word in this
04596        case.  */
04597     intoffset = intoffset & -BITS_PER_WORD;
04598   }
04599     }
04600 
04601   startbit = intoffset & -BITS_PER_WORD;
04602   endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
04603   intregs = (endbit - startbit) / BITS_PER_WORD;
04604   cum->words += intregs;
04605 }
04606 
04607 /* The darwin64 ABI calls for us to recurse down through structs,
04608    looking for elements passed in registers.  Unfortunately, we have
04609    to track int register count here also because of misalignments
04610    in powerpc alignment mode.  */
04611 
04612 static void
04613 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
04614               tree type,
04615               HOST_WIDE_INT startbitpos)
04616 {
04617   tree f;
04618 
04619   for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
04620     if (TREE_CODE (f) == FIELD_DECL)
04621       {
04622   HOST_WIDE_INT bitpos = startbitpos;
04623   tree ftype = TREE_TYPE (f);
04624   enum machine_mode mode;
04625   if (ftype == error_mark_node)
04626     continue;
04627   mode = TYPE_MODE (ftype);
04628 
04629   if (DECL_SIZE (f) != 0
04630       && host_integerp (bit_position (f), 1))
04631     bitpos += int_bit_position (f);
04632 
04633   /* ??? FIXME: else assume zero offset.  */
04634 
04635   if (TREE_CODE (ftype) == RECORD_TYPE)
04636     rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
04637   else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
04638     {
04639       rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
04640       cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
04641       cum->words += (GET_MODE_SIZE (mode) + 7) >> 3;
04642     }
04643   else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
04644     {
04645       rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
04646       cum->vregno++;
04647       cum->words += 2;
04648     }
04649   else if (cum->intoffset == -1)
04650     cum->intoffset = bitpos;
04651       }
04652 }
04653 
04654 /* Update the data in CUM to advance over an argument
04655    of mode MODE and data type TYPE.
04656    (TYPE is null for libcalls where that information may not be available.)
04657 
04658    Note that for args passed by reference, function_arg will be called
04659    with MODE and TYPE set to that of the pointer to the arg, not the arg
04660    itself.  */
04661 
04662 void
04663 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
04664           tree type, int named, int depth)
04665 {
04666   int size;
04667 
04668   /* Only tick off an argument if we're not recursing.  */
04669   if (depth == 0)
04670     cum->nargs_prototype--;
04671 
04672   if (TARGET_ALTIVEC_ABI
04673       && (ALTIVEC_VECTOR_MODE (mode)
04674     || (type && TREE_CODE (type) == VECTOR_TYPE
04675         && int_size_in_bytes (type) == 16)))
04676     {
04677       bool stack = false;
04678 
04679       if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
04680   {
04681     cum->vregno++;
04682     if (!TARGET_ALTIVEC)
04683       error ("cannot pass argument in vector register because"
04684        " altivec instructions are disabled, use -maltivec"
04685        " to enable them");
04686 
04687     /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
04688        even if it is going to be passed in a vector register.
04689        Darwin does the same for variable-argument functions.  */
04690     if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
04691         || (cum->stdarg && DEFAULT_ABI != ABI_V4))
04692       stack = true;
04693   }
04694       else
04695   stack = true;
04696 
04697       if (stack)
04698   {
04699     int align;
04700 
04701     /* Vector parameters must be 16-byte aligned.  This places
04702        them at 2 mod 4 in terms of words in 32-bit mode, since
04703        the parameter save area starts at offset 24 from the
04704        stack.  In 64-bit mode, they just have to start on an
04705        even word, since the parameter save area is 16-byte
04706        aligned.  Space for GPRs is reserved even if the argument
04707        will be passed in memory.  */
04708     if (TARGET_32BIT)
04709       align = (2 - cum->words) & 3;
04710     else
04711       align = cum->words & 1;
04712     cum->words += align + rs6000_arg_size (mode, type);
04713 
04714     if (TARGET_DEBUG_ARG)
04715       {
04716         fprintf (stderr, "function_adv: words = %2d, align=%d, ",
04717            cum->words, align);
04718         fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
04719            cum->nargs_prototype, cum->prototype,
04720            GET_MODE_NAME (mode));
04721       }
04722   }
04723     }
04724   else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
04725      && !cum->stdarg
04726      && cum->sysv_gregno <= GP_ARG_MAX_REG)
04727     cum->sysv_gregno++;
04728 
04729   else if (rs6000_darwin64_abi
04730      && mode == BLKmode
04731          && TREE_CODE (type) == RECORD_TYPE
04732      && (size = int_size_in_bytes (type)) > 0)
04733     {
04734       /* Variable sized types have size == -1 and are
04735    treated as if consisting entirely of ints.
04736    Pad to 16 byte boundary if needed.  */
04737       if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
04738     && (cum->words % 2) != 0)
04739   cum->words++;
04740       /* For varargs, we can just go up by the size of the struct. */
04741       if (!named)
04742   cum->words += (size + 7) / 8;
04743       else
04744   {
04745     /* It is tempting to say int register count just goes up by
04746        sizeof(type)/8, but this is wrong in a case such as
04747        { int; double; int; } [powerpc alignment].  We have to
04748        grovel through the fields for these too.  */
04749     cum->intoffset = 0;
04750     rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
04751     rs6000_darwin64_record_arg_advance_flush (cum,
04752                 size * BITS_PER_UNIT);
04753   }
04754     }
04755   else if (DEFAULT_ABI == ABI_V4)
04756     {
04757       if (TARGET_HARD_FLOAT && TARGET_FPRS
04758     && (mode == SFmode || mode == DFmode
04759         || (mode == TFmode && !TARGET_IEEEQUAD)))
04760   {
04761     if (cum->fregno + (mode == TFmode ? 1 : 0) <= FP_ARG_V4_MAX_REG)
04762       cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
04763     else
04764       {
04765         cum->fregno = FP_ARG_V4_MAX_REG + 1;
04766         if (mode == DFmode || mode == TFmode)
04767     cum->words += cum->words & 1;
04768         cum->words += rs6000_arg_size (mode, type);
04769       }
04770   }
04771       else
04772   {
04773     int n_words = rs6000_arg_size (mode, type);
04774     int gregno = cum->sysv_gregno;
04775 
04776     /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
04777        (r7,r8) or (r9,r10).  As does any other 2 word item such
04778        as complex int due to a historical mistake.  */
04779     if (n_words == 2)
04780       gregno += (1 - gregno) & 1;
04781 
04782     /* Multi-reg args are not split between registers and stack.  */
04783     if (gregno + n_words - 1 > GP_ARG_MAX_REG)
04784       {
04785         /* Long long and SPE vectors are aligned on the stack.
04786      So are other 2 word items such as complex int due to
04787      a historical mistake.  */
04788         if (n_words == 2)
04789     cum->words += cum->words & 1;
04790         cum->words += n_words;
04791       }
04792 
04793     /* Note: continuing to accumulate gregno past when we've started
04794        spilling to the stack indicates the fact that we've started
04795        spilling to the stack to expand_builtin_saveregs.  */
04796     cum->sysv_gregno = gregno + n_words;
04797   }
04798 
04799       if (TARGET_DEBUG_ARG)
04800   {
04801     fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
04802        cum->words, cum->fregno);
04803     fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
04804        cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
04805     fprintf (stderr, "mode = %4s, named = %d\n",
04806        GET_MODE_NAME (mode), named);
04807   }
04808     }
04809   else
04810     {
04811       int n_words = rs6000_arg_size (mode, type);
04812       int start_words = cum->words;
04813       int align_words = rs6000_parm_start (mode, type, start_words);
04814 
04815       cum->words = align_words + n_words;
04816 
04817       if (SCALAR_FLOAT_MODE_P (mode)
04818     && !DECIMAL_FLOAT_MODE_P (mode)
04819     && TARGET_HARD_FLOAT && TARGET_FPRS)
04820   cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
04821 
04822       if (TARGET_DEBUG_ARG)
04823   {
04824     fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
04825        cum->words, cum->fregno);
04826     fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
04827        cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
04828     fprintf (stderr, "named = %d, align = %d, depth = %d\n",
04829        named, align_words - start_words, depth);
04830   }
04831     }
04832 }
04833 
04834 static rtx
04835 spe_build_register_parallel (enum machine_mode mode, int gregno)
04836 {
04837   rtx r1, r3;
04838 
04839   switch (mode)
04840     {
04841     case DFmode:
04842       r1 = gen_rtx_REG (DImode, gregno);
04843       r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
04844       return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
04845 
04846     case DCmode:
04847       r1 = gen_rtx_REG (DImode, gregno);
04848       r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
04849       r3 = gen_rtx_REG (DImode, gregno + 2);
04850       r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
04851       return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
04852 
04853     default:
04854       gcc_unreachable ();
04855     }
04856 }
04857 
04858 /* Determine where to put a SIMD argument on the SPE.  */
04859 static rtx
04860 rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
04861        tree type)
04862 {
04863   int gregno = cum->sysv_gregno;
04864 
04865   /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
04866      are passed and returned in a pair of GPRs for ABI compatibility.  */
04867   if (TARGET_E500_DOUBLE && (mode == DFmode || mode == DCmode))
04868     {
04869       int n_words = rs6000_arg_size (mode, type);
04870 
04871       /* Doubles go in an odd/even register pair (r5/r6, etc).  */
04872       if (mode == DFmode)
04873   gregno += (1 - gregno) & 1;
04874 
04875       /* Multi-reg args are not split between registers and stack.  */
04876       if (gregno + n_words - 1 > GP_ARG_MAX_REG)
04877   return NULL_RTX;
04878 
04879       return spe_build_register_parallel (mode, gregno);
04880     }
04881   if (cum->stdarg)
04882     {
04883       int n_words = rs6000_arg_size (mode, type);
04884 
04885       /* SPE vectors are put in odd registers.  */
04886       if (n_words == 2 && (gregno & 1) == 0)
04887   gregno += 1;
04888 
04889       if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
04890   {
04891     rtx r1, r2;
04892     enum machine_mode m = SImode;
04893 
04894     r1 = gen_rtx_REG (m, gregno);
04895     r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
04896     r2 = gen_rtx_REG (m, gregno + 1);
04897     r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
04898     return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
04899   }
04900       else
04901   return NULL_RTX;
04902     }
04903   else
04904     {
04905       if (gregno <= GP_ARG_MAX_REG)
04906   return gen_rtx_REG (mode, gregno);
04907       else
04908   return NULL_RTX;
04909     }
04910 }
04911 
04912 /* A subroutine of rs6000_darwin64_record_arg.  Assign the bits of the
04913    structure between cum->intoffset and bitpos to integer registers.  */
04914 
04915 static void
04916 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
04917           HOST_WIDE_INT bitpos, rtx rvec[], int *k)
04918 {
04919   enum machine_mode mode;
04920   unsigned int regno;
04921   unsigned int startbit, endbit;
04922   int this_regno, intregs, intoffset;
04923   rtx reg;
04924 
04925   if (cum->intoffset == -1)
04926     return;
04927 
04928   intoffset = cum->intoffset;
04929   cum->intoffset = -1;
04930 
04931   /* If this is the trailing part of a word, try to only load that
04932      much into the register.  Otherwise load the whole register.  Note
04933      that in the latter case we may pick up unwanted bits.  It's not a
04934      problem at the moment but may wish to revisit.  */
04935 
04936   if (intoffset % BITS_PER_WORD != 0)
04937     {
04938       mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
04939         MODE_INT, 0);
04940       if (mode == BLKmode)
04941   {
04942     /* We couldn't find an appropriate mode, which happens,
04943        e.g., in packed structs when there are 3 bytes to load.
04944        Back intoffset back to the beginning of the word in this
04945        case.  */
04946    intoffset = intoffset & -BITS_PER_WORD;
04947    mode = word_mode;
04948   }
04949     }
04950   else
04951     mode = word_mode;
04952 
04953   startbit = intoffset & -BITS_PER_WORD;
04954   endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
04955   intregs = (endbit - startbit) / BITS_PER_WORD;
04956   this_regno = cum->words + intoffset / BITS_PER_WORD;
04957 
04958   if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
04959     cum->use_stack = 1;
04960 
04961   intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
04962   if (intregs <= 0)
04963     return;
04964 
04965   intoffset /= BITS_PER_UNIT;
04966   do
04967     {
04968       regno = GP_ARG_MIN_REG + this_regno;
04969       reg = gen_rtx_REG (mode, regno);
04970       rvec[(*k)++] =
04971   gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
04972 
04973       this_regno += 1;
04974       intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
04975       mode = word_mode;
04976       intregs -= 1;
04977     }
04978   while (intregs > 0);
04979 }
04980 
04981 /* Recursive workhorse for the following.  */
04982 
04983 static void
04984 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, tree type,
04985             HOST_WIDE_INT startbitpos, rtx rvec[],
04986             int *k)
04987 {
04988   tree f;
04989 
04990   for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
04991     if (TREE_CODE (f) == FIELD_DECL)
04992       {
04993   HOST_WIDE_INT bitpos = startbitpos;
04994   tree ftype = TREE_TYPE (f);
04995   enum machine_mode mode;
04996   if (ftype == error_mark_node)
04997     continue;
04998   mode = TYPE_MODE (ftype);
04999 
05000   if (DECL_SIZE (f) != 0
05001       && host_integerp (bit_position (f), 1))
05002     bitpos += int_bit_position (f);
05003 
05004   /* ??? FIXME: else assume zero offset.  */
05005 
05006   if (TREE_CODE (ftype) == RECORD_TYPE)
05007     rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
05008   else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
05009     {
05010 #if 0
05011       switch (mode)
05012         {
05013         case SCmode: mode = SFmode; break;
05014         case DCmode: mode = DFmode; break;
05015         case TCmode: mode = TFmode; break;
05016         default: break;
05017         }
05018 #endif
05019       rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
05020       rvec[(*k)++]
05021         = gen_rtx_EXPR_LIST (VOIDmode,
05022            gen_rtx_REG (mode, cum->fregno++),
05023            GEN_INT (bitpos / BITS_PER_UNIT));
05024       if (mode == TFmode)
05025         cum->fregno++;
05026     }
05027   else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
05028     {
05029       rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
05030       rvec[(*k)++]
05031         = gen_rtx_EXPR_LIST (VOIDmode,
05032            gen_rtx_REG (mode, cum->vregno++),
05033            GEN_INT (bitpos / BITS_PER_UNIT));
05034     }
05035   else if (cum->intoffset == -1)
05036     cum->intoffset = bitpos;
05037       }
05038 }
05039 
05040 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
05041    the register(s) to be used for each field and subfield of a struct
05042    being passed by value, along with the offset of where the
05043    register's value may be found in the block.  FP fields go in FP
05044    register, vector fields go in vector registers, and everything
05045    else goes in int registers, packed as in memory.
05046 
05047    This code is also used for function return values.  RETVAL indicates
05048    whether this is the case.
05049 
05050    Much of this is taken from the SPARC V9 port, which has a similar
05051    calling convention.  */
05052 
05053 static rtx
05054 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, tree type,
05055           int named, bool retval)
05056 {
05057   rtx rvec[FIRST_PSEUDO_REGISTER];
05058   int k = 1, kbase = 1;
05059   HOST_WIDE_INT typesize = int_size_in_bytes (type);
05060   /* This is a copy; modifications are not visible to our caller.  */
05061   CUMULATIVE_ARGS copy_cum = *orig_cum;
05062   CUMULATIVE_ARGS *cum = &copy_cum;
05063 
05064   /* Pad to 16 byte boundary if needed.  */
05065   if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
05066       && (cum->words % 2) != 0)
05067     cum->words++;
05068 
05069   cum->intoffset = 0;
05070   cum->use_stack = 0;
05071   cum->named = named;
05072 
05073   /* Put entries into rvec[] for individual FP and vector fields, and
05074      for the chunks of memory that go in int regs.  Note we start at
05075      element 1; 0 is reserved for an indication of using memory, and
05076      may or may not be filled in below. */
05077   rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k);
05078   rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
05079 
05080   /* If any part of the struct went on the stack put all of it there.
05081      This hack is because the generic code for
05082      FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
05083      parts of the struct are not at the beginning.  */
05084   if (cum->use_stack)
05085     {
05086       if (retval)
05087   return NULL_RTX;    /* doesn't go in registers at all */
05088       kbase = 0;
05089       rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
05090     }
05091   if (k > 1 || cum->use_stack)
05092     return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
05093   else
05094     return NULL_RTX;
05095 }
05096 
05097 /* Determine where to place an argument in 64-bit mode with 32-bit ABI.  */
05098 
05099 static rtx
05100 rs6000_mixed_function_arg (enum machine_mode mode, tree type, int align_words)
05101 {
05102   int n_units;
05103   int i, k;
05104   rtx rvec[GP_ARG_NUM_REG + 1];
05105 
05106   if (align_words >= GP_ARG_NUM_REG)
05107     return NULL_RTX;
05108 
05109   n_units = rs6000_arg_size (mode, type);
05110 
05111   /* Optimize the simple case where the arg fits in one gpr, except in
05112      the case of BLKmode due to assign_parms assuming that registers are
05113      BITS_PER_WORD wide.  */
05114   if (n_units == 0
05115       || (n_units == 1 && mode != BLKmode))
05116     return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
05117 
05118   k = 0;
05119   if (align_words + n_units > GP_ARG_NUM_REG)
05120     /* Not all of the arg fits in gprs.  Say that it goes in memory too,
05121        using a magic NULL_RTX component.
05122        This is not strictly correct.  Only some of the arg belongs in
05123        memory, not all of it.  However, the normal scheme using
05124        function_arg_partial_nregs can result in unusual subregs, eg.
05125        (subreg:SI (reg:DF) 4), which are not handled well.  The code to
05126        store the whole arg to memory is often more efficient than code
05127        to store pieces, and we know that space is available in the right
05128        place for the whole arg.  */
05129     rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
05130 
05131   i = 0;
05132   do
05133     {
05134       rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
05135       rtx off = GEN_INT (i++ * 4);
05136       rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
05137     }
05138   while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
05139 
05140   return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
05141 }
05142 
05143 /* Determine where to put an argument to a function.
05144    Value is zero to push the argument on the stack,
05145    or a hard register in which to store the argument.
05146 
05147    MODE is the argument's machine mode.
05148    TYPE is the data type of the argument (as a tree).
05149     This is null for libcalls where that information may
05150     not be available.
05151    CUM is a variable of type CUMULATIVE_ARGS which gives info about
05152     the preceding args and about the function being called.  It is
05153     not modified in this routine.
05154    NAMED is nonzero if this argument is a named parameter
05155     (otherwise it is an extra parameter matching an ellipsis).
05156 
05157    On RS/6000 the first eight words of non-FP are normally in registers
05158    and the rest are pushed.  Under AIX, the first 13 FP args are in registers.
05159    Under V.4, the first 8 FP args are in registers.
05160 
05161    If this is floating-point and no prototype is specified, we use
05162    both an FP and integer register (or possibly FP reg and stack).  Library
05163    functions (when CALL_LIBCALL is set) always have the proper types for args,
05164    so we can pass the FP value just in one register.  emit_library_function
05165    doesn't support PARALLEL anyway.
05166 
05167    Note that for args passed by reference, function_arg will be called
05168    with MODE and TYPE set to that of the pointer to the arg, not the arg
05169    itself.  */
05170 
05171 rtx
05172 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
05173         tree type, int named)
05174 {
05175   enum rs6000_abi abi = DEFAULT_ABI;
05176 
05177   /* Return a marker to indicate whether CR1 needs to set or clear the
05178      bit that V.4 uses to say fp args were passed in registers.
05179      Assume that we don't need the marker for software floating point,
05180      or compiler generated library calls.  */
05181   if (mode == VOIDmode)
05182     {
05183       if (abi == ABI_V4
05184     && (cum->call_cookie & CALL_LIBCALL) == 0
05185     && (cum->stdarg
05186         || (cum->nargs_prototype < 0
05187       && (cum->prototype || TARGET_NO_PROTOTYPE))))
05188   {
05189     /* For the SPE, we need to crxor CR6 always.  */
05190     if (TARGET_SPE_ABI)
05191       return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
05192     else if (TARGET_HARD_FLOAT && TARGET_FPRS)
05193       return GEN_INT (cum->call_cookie
05194           | ((cum->fregno == FP_ARG_MIN_REG)
05195              ? CALL_V4_SET_FP_ARGS
05196              : CALL_V4_CLEAR_FP_ARGS));
05197   }
05198 
05199       return GEN_INT (cum->call_cookie);
05200     }
05201 
05202   if (rs6000_darwin64_abi && mode == BLKmode
05203       && TREE_CODE (type) == RECORD_TYPE)
05204     {
05205       rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
05206       if (rslt != NULL_RTX)
05207   return rslt;
05208       /* Else fall through to usual handling.  */
05209     }
05210 
05211   if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
05212     if (TARGET_64BIT && ! cum->prototype)
05213       {
05214   /* Vector parameters get passed in vector register
05215      and also in GPRs or memory, in absence of prototype.  */
05216   int align_words;
05217   rtx slot;
05218   align_words = (cum->words + 1) & ~1;
05219 
05220   if (align_words >= GP_ARG_NUM_REG)
05221     {
05222       slot = NULL_RTX;
05223     }
05224   else
05225     {
05226       slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
05227     }
05228   return gen_rtx_PARALLEL (mode,
05229      gen_rtvec (2,
05230           gen_rtx_EXPR_LIST (VOIDmode,
05231                  slot, const0_rtx),
05232           gen_rtx_EXPR_LIST (VOIDmode,
05233                  gen_rtx_REG (mode, cum->vregno),
05234                  const0_rtx)));
05235       }
05236     else
05237       return gen_rtx_REG (mode, cum->vregno);
05238   else if (TARGET_ALTIVEC_ABI
05239      && (ALTIVEC_VECTOR_MODE (mode)
05240          || (type && TREE_CODE (type) == VECTOR_TYPE
05241        && int_size_in_bytes (type) == 16)))
05242     {
05243       if (named || abi == ABI_V4)
05244   return NULL_RTX;
05245       else
05246   {
05247     /* Vector parameters to varargs functions under AIX or Darwin
05248        get passed in memory and possibly also in GPRs.  */
05249     int align, align_words, n_words;
05250     enum machine_mode part_mode;
05251 
05252     /* Vector parameters must be 16-byte aligned.  This places them at
05253        2 mod 4 in terms of words in 32-bit mode, since the parameter
05254        save area starts at offset 24 from the stack.  In 64-bit mode,
05255        they just have to start on an even word, since the parameter
05256        save area is 16-byte aligned.  */
05257     if (TARGET_32BIT)
05258       align = (2 - cum->words) & 3;
05259     else
05260       align = cum->words & 1;
05261     align_words = cum->words + align;
05262 
05263     /* Out of registers?  Memory, then.  */
05264     if (align_words >= GP_ARG_NUM_REG)
05265       return NULL_RTX;
05266 
05267     if (TARGET_32BIT && TARGET_POWERPC64)
05268       return rs6000_mixed_function_arg (mode, type, align_words);
05269 
05270     /* The vector value goes in GPRs.  Only the part of the
05271        value in GPRs is reported here.  */
05272     part_mode = mode;
05273     n_words = rs6000_arg_size (mode, type);
05274     if (align_words + n_words > GP_ARG_NUM_REG)
05275       /* Fortunately, there are only two possibilities, the value
05276          is either wholly in GPRs or half in GPRs and half not.  */
05277       part_mode = DImode;
05278 
05279     return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
05280   }
05281     }
05282   else if (TARGET_SPE_ABI && TARGET_SPE
05283      && (SPE_VECTOR_MODE (mode)
05284          || (TARGET_E500_DOUBLE && (mode == DFmode
05285             || mode == DCmode))))
05286     return rs6000_spe_function_arg (cum, mode, type);
05287 
05288   else if (abi == ABI_V4)
05289     {
05290       if (TARGET_HARD_FLOAT && TARGET_FPRS
05291     && (mode == SFmode || mode == DFmode
05292         || (mode == TFmode && !TARGET_IEEEQUAD)))
05293   {
05294     if (cum->fregno + (mode == TFmode ? 1 : 0) <= FP_ARG_V4_MAX_REG)
05295       return gen_rtx_REG (mode, cum->fregno);
05296     else
05297       return NULL_RTX;
05298   }
05299       else
05300   {
05301     int n_words = rs6000_arg_size (mode, type);
05302     int gregno = cum->sysv_gregno;
05303 
05304     /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
05305        (r7,r8) or (r9,r10).  As does any other 2 word item such
05306        as complex int due to a historical mistake.  */
05307     if (n_words == 2)
05308       gregno += (1 - gregno) & 1;
05309 
05310     /* Multi-reg args are not split between registers and stack.  */
05311     if (gregno + n_words - 1 > GP_ARG_MAX_REG)
05312       return NULL_RTX;
05313 
05314     if (TARGET_32BIT && TARGET_POWERPC64)
05315       return rs6000_mixed_function_arg (mode, type,
05316                 gregno - GP_ARG_MIN_REG);
05317     return gen_rtx_REG (mode, gregno);
05318   }
05319     }
05320   else
05321     {
05322       int align_words = rs6000_parm_start (mode, type, cum->words);
05323 
05324       if (USE_FP_FOR_ARG_P (cum, mode, type))
05325   {
05326     rtx rvec[GP_ARG_NUM_REG + 1];
05327     rtx r;
05328     int k;
05329     bool needs_psave;
05330     enum machine_mode fmode = mode;
05331     unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
05332 
05333     if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
05334       {
05335         /* Currently, we only ever need one reg here because complex
05336      doubles are split.  */
05337         gcc_assert (cum->fregno == FP_ARG_MAX_REG && fmode == TFmode);
05338 
05339         /* Long double split over regs and memory.  */
05340         fmode = DFmode;
05341       }
05342 
05343     /* Do we also need to pass this arg in the parameter save
05344        area?  */
05345     needs_psave = (type
05346        && (cum->nargs_prototype <= 0
05347            || (DEFAULT_ABI == ABI_AIX
05348          && TARGET_XL_COMPAT
05349          && align_words >= GP_ARG_NUM_REG)));
05350 
05351     if (!needs_psave && mode == fmode)
05352       return gen_rtx_REG (fmode, cum->fregno);
05353 
05354     k = 0;
05355     if (needs_psave)
05356       {
05357         /* Describe the part that goes in gprs or the stack.
05358      This piece must come first, before the fprs.  */
05359         if (align_words < GP_ARG_NUM_REG)
05360     {
05361       unsigned long n_words = rs6000_arg_size (mode, type);
05362 
05363       if (align_words + n_words > GP_ARG_NUM_REG
05364           || (TARGET_32BIT && TARGET_POWERPC64))
05365         {
05366           /* If this is partially on the stack, then we only
05367        include the portion actually in registers here.  */
05368           enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
05369           rtx off;
05370           int i = 0;
05371           if (align_words + n_words > GP_ARG_NUM_REG)
05372       /* Not all of the arg fits in gprs.  Say that it
05373          goes in memory too, using a magic NULL_RTX
05374          component.  Also see comment in
05375          rs6000_mixed_function_arg for why the normal
05376          function_arg_partial_nregs scheme doesn't work
05377          in this case. */
05378       rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
05379                    const0_rtx);
05380           do
05381       {
05382         r = gen_rtx_REG (rmode,
05383              GP_ARG_MIN_REG + align_words);
05384         off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
05385         rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
05386       }
05387           while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
05388         }
05389       else
05390         {
05391           /* The whole arg fits in gprs.  */
05392           r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
05393           rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
05394         }
05395     }
05396         else
05397     /* It's entirely in memory.  */
05398     rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
05399       }
05400 
05401     /* Describe where this piece goes in the fprs.  */
05402     r = gen_rtx_REG (fmode, cum->fregno);
05403     rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
05404 
05405     return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
05406   }
05407       else if (align_words < GP_ARG_NUM_REG)
05408   {
05409     if (TARGET_32BIT && TARGET_POWERPC64)
05410       return rs6000_mixed_function_arg (mode, type, align_words);
05411 
05412     if (mode == BLKmode)
05413       mode = Pmode;
05414 
05415     return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
05416   }
05417       else
05418   return NULL_RTX;
05419     }
05420 }
05421 
05422 /* For an arg passed partly in registers and partly in memory, this is
05423    the number of bytes passed in registers.  For args passed entirely in
05424    registers or entirely in memory, zero.  When an arg is described by a
05425    PARALLEL, perhaps using more than one register type, this function
05426    returns the number of bytes used by the first element of the PARALLEL.  */
05427 
05428 static int
05429 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
05430         tree type, bool named)
05431 {
05432   int ret = 0;
05433   int align_words;
05434 
05435   if (DEFAULT_ABI == ABI_V4)
05436     return 0;
05437 
05438   if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
05439       && cum->nargs_prototype >= 0)
05440     return 0;
05441 
05442   /* In this complicated case we just disable the partial_nregs code.  */
05443   if (rs6000_darwin64_abi && mode == BLKmode
05444       && TREE_CODE (type) == RECORD_TYPE
05445       && int_size_in_bytes (type) > 0)
05446     return 0;
05447 
05448   align_words = rs6000_parm_start (mode, type, cum->words);
05449 
05450   if (USE_FP_FOR_ARG_P (cum, mode, type))
05451     {
05452       /* If we are passing this arg in the fixed parameter save area
05453    (gprs or memory) as well as fprs, then this function should
05454    return the number of partial bytes passed in the parameter
05455    save area rather than partial bytes passed in fprs.  */
05456       if (type
05457     && (cum->nargs_prototype <= 0
05458         || (DEFAULT_ABI == ABI_AIX
05459       && TARGET_XL_COMPAT
05460       && align_words >= GP_ARG_NUM_REG)))
05461   return 0;
05462       else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
05463          > FP_ARG_MAX_REG + 1)
05464   ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
05465       else if (cum->nargs_prototype >= 0)
05466   return 0;
05467     }
05468 
05469   if (align_words < GP_ARG_NUM_REG
05470       && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
05471     ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
05472 
05473   if (ret != 0 && TARGET_DEBUG_ARG)
05474     fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
05475 
05476   return ret;
05477 }
05478 
05479 /* A C expression that indicates when an argument must be passed by
05480    reference.  If nonzero for an argument, a copy of that argument is
05481    made in memory and a pointer to the argument is passed instead of
05482    the argument itself.  The pointer is passed in whatever way is
05483    appropriate for passing a pointer to that type.
05484 
05485    Under V.4, aggregates and long double are passed by reference.
05486 
05487    As an extension to all 32-bit ABIs, AltiVec vectors are passed by
05488    reference unless the AltiVec vector extension ABI is in force.
05489 
05490    As an extension to all ABIs, variable sized types are passed by
05491    reference.  */
05492 
05493 static bool
05494 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
05495         enum machine_mode mode, tree type,
05496         bool named ATTRIBUTE_UNUSED)
05497 {
05498   if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
05499     {
05500       if (TARGET_DEBUG_ARG)
05501   fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
05502       return 1;
05503     }
05504 
05505   if (!type)
05506     return 0;
05507 
05508   if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
05509     {
05510       if (TARGET_DEBUG_ARG)
05511   fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
05512       return 1;
05513     }
05514 
05515   if (int_size_in_bytes (type) < 0)
05516     {
05517       if (TARGET_DEBUG_ARG)
05518   fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
05519       return 1;
05520     }
05521 
05522   /* Allow -maltivec -mabi=no-altivec without warning.  Altivec vector
05523      modes only exist for GCC vector types if -maltivec.  */
05524   if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
05525     {
05526       if (TARGET_DEBUG_ARG)
05527   fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
05528       return 1;
05529     }
05530 
05531   /* Pass synthetic vectors in memory.  */
05532   if (TREE_CODE (type) == VECTOR_TYPE
05533       && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
05534     {
05535       static bool warned_for_pass_big_vectors = false;
05536       if (TARGET_DEBUG_ARG)
05537   fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
05538       if (!warned_for_pass_big_vectors)
05539   {
05540     warning (0, "GCC vector passed by reference: "
05541        "non-standard ABI extension with no compatibility guarantee");
05542     warned_for_pass_big_vectors = true;
05543   }
05544       return 1;
05545     }
05546 
05547   return 0;
05548 }
05549 
05550 static void
05551 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
05552 {
05553   int i;
05554   enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
05555 
05556   if (nregs == 0)
05557     return;
05558 
05559   for (i = 0; i < nregs; i++)
05560     {
05561       rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
05562       if (reload_completed)
05563   {
05564     if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
05565       tem = NULL_RTX;
05566     else
05567       tem = simplify_gen_subreg (reg_mode, x, BLKmode,
05568                i * GET_MODE_SIZE (reg_mode));
05569   }
05570       else
05571   tem = replace_equiv_address (tem, XEXP (tem, 0));
05572 
05573       gcc_assert (tem);
05574 
05575       emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
05576     }
05577 }
05578 
05579 /* Perform any needed actions needed for a function that is receiving a
05580    variable number of arguments.
05581 
05582    CUM is as above.
05583 
05584    MODE and TYPE are the mode and type of the current parameter.
05585 
05586    PRETEND_SIZE is a variable that should be set to the amount of stack
05587    that must be pushed by the prolog to pretend that our caller pushed
05588    it.
05589 
05590    Normally, this macro will push all remaining incoming registers on the
05591    stack and set PRETEND_SIZE to the length of the registers pushed.  */
05592 
05593 static void
05594 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
05595       tree type, int *pretend_size ATTRIBUTE_UNUSED,
05596       int no_rtl)
05597 {
05598   CUMULATIVE_ARGS next_cum;
05599   int reg_size = TARGET_32BIT ? 4 : 8;
05600   rtx save_area = NULL_RTX, mem;
05601   int first_reg_offset, set;
05602 
05603   /* Skip the last named argument.  */
05604   next_cum = *cum;
05605   function_arg_advance (&next_cum, mode, type, 1, 0);
05606 
05607   if (DEFAULT_ABI == ABI_V4)
05608     {
05609       first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
05610 
05611       if (! no_rtl)
05612   {
05613     int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
05614     HOST_WIDE_INT offset = 0;
05615 
05616     /* Try to optimize the size of the varargs save area.
05617        The ABI requires that ap.reg_save_area is doubleword
05618        aligned, but we don't need to allocate space for all
05619        the bytes, only those to which we actually will save
05620        anything.  */
05621     if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
05622       gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
05623     if (TARGET_HARD_FLOAT && TARGET_FPRS
05624         && next_cum.fregno <= FP_ARG_V4_MAX_REG
05625         && cfun->va_list_fpr_size)
05626       {
05627         if (gpr_reg_num)
05628     fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
05629          * UNITS_PER_FP_WORD;
05630         if (cfun->va_list_fpr_size
05631       < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
05632     fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
05633         else
05634     fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
05635           * UNITS_PER_FP_WORD;
05636       }
05637     if (gpr_reg_num)
05638       {
05639         offset = -((first_reg_offset * reg_size) & ~7);
05640         if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
05641     {
05642       gpr_reg_num = cfun->va_list_gpr_size;
05643       if (reg_size == 4 && (first_reg_offset & 1))
05644         gpr_reg_num++;
05645     }
05646         gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
05647       }
05648     else if (fpr_size)
05649       offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
05650            * UNITS_PER_FP_WORD
05651          - (int) (GP_ARG_NUM_REG * reg_size);
05652 
05653     if (gpr_size + fpr_size)
05654       {
05655         rtx reg_save_area
05656     = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
05657         gcc_assert (GET_CODE (reg_save_area) == MEM);
05658         reg_save_area = XEXP (reg_save_area, 0);
05659         if (GET_CODE (reg_save_area) == PLUS)
05660     {
05661       gcc_assert (XEXP (reg_save_area, 0)
05662             == virtual_stack_vars_rtx);
05663       gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
05664       offset += INTVAL (XEXP (reg_save_area, 1));
05665     }
05666         else
05667     gcc_assert (reg_save_area == virtual_stack_vars_rtx);
05668       }
05669 
05670     cfun->machine->varargs_save_offset = offset;
05671     save_area = plus_constant (virtual_stack_vars_rtx, offset);
05672   }
05673     }
05674   else
05675     {
05676       first_reg_offset = next_cum.words;
05677       save_area = virtual_incoming_args_rtx;
05678 
05679       if (targetm.calls.must_pass_in_stack (mode, type))
05680   first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
05681     }
05682 
05683   set = get_varargs_alias_set ();
05684   if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
05685       && cfun->va_list_gpr_size)
05686     {
05687       int nregs = GP_ARG_NUM_REG - first_reg_offset;
05688 
05689       if (va_list_gpr_counter_field)
05690   {
05691     /* V4 va_list_gpr_size counts number of registers needed.  */
05692     if (nregs > cfun->va_list_gpr_size)
05693       nregs = cfun->va_list_gpr_size;
05694   }
05695       else
05696   {
05697     /* char * va_list instead counts number of bytes needed.  */
05698     if (nregs > cfun->va_list_gpr_size / reg_size)
05699       nregs = cfun->va_list_gpr_size / reg_size;
05700   }
05701 
05702       mem = gen_rtx_MEM (BLKmode,
05703        plus_constant (save_area,
05704           first_reg_offset * reg_size));
05705       MEM_NOTRAP_P (mem) = 1;
05706       set_mem_alias_set (mem, set);
05707       set_mem_align (mem, BITS_PER_WORD);
05708 
05709       rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
05710           nregs);
05711     }
05712 
05713   /* Save FP registers if needed.  */
05714   if (DEFAULT_ABI == ABI_V4
05715       && TARGET_HARD_FLOAT && TARGET_FPRS
05716       && ! no_rtl
05717       && next_cum.fregno <= FP_ARG_V4_MAX_REG
05718       && cfun->va_list_fpr_size)
05719     {
05720       int fregno = next_cum.fregno, nregs;
05721       rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
05722       rtx lab = gen_label_rtx ();
05723       int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
05724                  * UNITS_PER_FP_WORD);
05725 
05726       emit_jump_insn
05727   (gen_rtx_SET (VOIDmode,
05728           pc_rtx,
05729           gen_rtx_IF_THEN_ELSE (VOIDmode,
05730               gen_rtx_NE (VOIDmode, cr1,
05731               const0_rtx),
05732               gen_rtx_LABEL_REF (VOIDmode, lab),
05733               pc_rtx)));
05734 
05735       for (nregs = 0;
05736      fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
05737      fregno++, off += UNITS_PER_FP_WORD, nregs++)
05738   {
05739     mem = gen_rtx_MEM (DFmode, plus_constant (save_area, off));
05740     MEM_NOTRAP_P (mem) = 1;
05741     set_mem_alias_set (mem, set);
05742     set_mem_align (mem, GET_MODE_ALIGNMENT (DFmode));
05743     emit_move_insn (mem, gen_rtx_REG (DFmode, fregno));
05744   }
05745 
05746       emit_label (lab);
05747     }
05748 }
05749 
05750 /* Create the va_list data type.  */
05751 
05752 static tree
05753 rs6000_build_builtin_va_list (void)
05754 {
05755   tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
05756 
05757   /* For AIX, prefer 'char *' because that's what the system
05758      header files like.  */
05759   if (DEFAULT_ABI != ABI_V4)
05760     return build_pointer_type (char_type_node);
05761 
05762   record = (*lang_hooks.types.make_type) (RECORD_TYPE);
05763   type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
05764 
05765   f_gpr = build_decl (FIELD_DECL, get_identifier ("gpr"),
05766           unsigned_char_type_node);
05767   f_fpr = build_decl (FIELD_DECL, get_identifier ("fpr"),
05768           unsigned_char_type_node);
05769   /* Give the two bytes of padding a name, so that -Wpadded won't warn on
05770      every user file.  */
05771   f_res = build_decl (FIELD_DECL, get_identifier ("reserved"),
05772           short_unsigned_type_node);
05773   f_ovf = build_decl (FIELD_DECL, get_identifier ("overflow_arg_area"),
05774           ptr_type_node);
05775   f_sav = build_decl (FIELD_DECL, get_identifier ("reg_save_area"),
05776           ptr_type_node);
05777 
05778   va_list_gpr_counter_field = f_gpr;
05779   va_list_fpr_counter_field = f_fpr;
05780 
05781   DECL_FIELD_CONTEXT (f_gpr) = record;
05782   DECL_FIELD_CONTEXT (f_fpr) = record;
05783   DECL_FIELD_CONTEXT (f_res) = record;
05784   DECL_FIELD_CONTEXT (f_ovf) = record;
05785   DECL_FIELD_CONTEXT (f_sav) = record;
05786 
05787   TREE_CHAIN (record) = type_decl;
05788   TYPE_NAME (record) = type_decl;
05789   TYPE_FIELDS (record) = f_gpr;
05790   TREE_CHAIN (f_gpr) = f_fpr;
05791   TREE_CHAIN (f_fpr) = f_res;
05792   TREE_CHAIN (f_res) = f_ovf;
05793   TREE_CHAIN (f_ovf) = f_sav;
05794 
05795   layout_type (record);
05796 
05797   /* The correct type is an array type of one element.  */
05798   return build_array_type (record, build_index_type (size_zero_node));
05799 }
05800 
05801 /* Implement va_start.  */
05802 
05803 void
05804 rs6000_va_start (tree valist, rtx nextarg)
05805 {
05806   HOST_WIDE_INT words, n_gpr, n_fpr;
05807   tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
05808   tree gpr, fpr, ovf, sav, t;
05809 
05810   /* Only SVR4 needs something special.  */
05811   if (DEFAULT_ABI != ABI_V4)
05812     {
05813       std_expand_builtin_va_start (valist, nextarg);
05814       return;
05815     }
05816 
05817   f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
05818   f_fpr = TREE_CHAIN (f_gpr);
05819   f_res = TREE_CHAIN (f_fpr);
05820   f_ovf = TREE_CHAIN (f_res);
05821   f_sav = TREE_CHAIN (f_ovf);
05822 
05823   valist = build_va_arg_indirect_ref (valist);
05824   gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
05825   fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
05826   ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
05827   sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
05828 
05829   /* Count number of gp and fp argument registers used.  */
05830   words = current_function_args_info.words;
05831   n_gpr = MIN (current_function_args_info.sysv_gregno - GP_ARG_MIN_REG,
05832          GP_ARG_NUM_REG);
05833   n_fpr = MIN (current_function_args_info.fregno - FP_ARG_MIN_REG,
05834          FP_ARG_NUM_REG);
05835 
05836   if (TARGET_DEBUG_ARG)
05837     fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
05838        HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
05839        words, n_gpr, n_fpr);
05840 
05841   if (cfun->va_list_gpr_size)
05842     {
05843       t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
05844       build_int_cst (NULL_TREE, n_gpr));
05845       TREE_SIDE_EFFECTS (t) = 1;
05846       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
05847     }
05848 
05849   if (cfun->va_list_fpr_size)
05850     {
05851       t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
05852       build_int_cst (NULL_TREE, n_fpr));
05853       TREE_SIDE_EFFECTS (t) = 1;
05854       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
05855     }
05856 
05857   /* Find the overflow area.  */
05858   t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
05859   if (words != 0)
05860     t = build2 (PLUS_EXPR, TREE_TYPE (ovf), t,
05861           build_int_cst (NULL_TREE, words * UNITS_PER_WORD));
05862   t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
05863   TREE_SIDE_EFFECTS (t) = 1;
05864   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
05865 
05866   /* If there were no va_arg invocations, don't set up the register
05867      save area.  */
05868   if (!cfun->va_list_gpr_size
05869       && !cfun->va_list_fpr_size
05870       && n_gpr < GP_ARG_NUM_REG
05871       && n_fpr < FP_ARG_V4_MAX_REG)
05872     return;
05873 
05874   /* Find the register save area.  */
05875   t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
05876   if (cfun->machine->varargs_save_offset)
05877     t = build2 (PLUS_EXPR, TREE_TYPE (sav), t,
05878           build_int_cst (NULL_TREE, cfun->machine->varargs_save_offset));
05879   t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
05880   TREE_SIDE_EFFECTS (t) = 1;
05881   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
05882 }
05883 
05884 /* Implement va_arg.  */
05885 
05886 tree
05887 rs6000_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
05888 {
05889   tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
05890   tree gpr, fpr, ovf, sav, reg, t, u;
05891   int size, rsize, n_reg, sav_ofs, sav_scale;
05892   tree lab_false, lab_over, addr;
05893   int align;
05894   tree ptrtype = build_pointer_type (type);
05895 
05896   if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
05897     {
05898       t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
05899       return build_va_arg_indirect_ref (t);
05900     }
05901 
05902   if (DEFAULT_ABI != ABI_V4)
05903     {
05904       if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
05905   {
05906     tree elem_type = TREE_TYPE (type);
05907     enum machine_mode elem_mode = TYPE_MODE (elem_type);
05908     int elem_size = GET_MODE_SIZE (elem_mode);
05909 
05910     if (elem_size < UNITS_PER_WORD)
05911       {
05912         tree real_part, imag_part;
05913         tree post = NULL_TREE;
05914 
05915         real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
05916               &post);
05917         /* Copy the value into a temporary, lest the formal temporary
05918      be reused out from under us.  */
05919         real_part = get_initialized_tmp_var (real_part, pre_p, &post);
05920         append_to_statement_list (post, pre_p);
05921 
05922         imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
05923               post_p);
05924 
05925         return build2 (COMPLEX_EXPR, type, real_part, imag_part);
05926       }
05927   }
05928 
05929       return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
05930     }
05931 
05932   f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
05933   f_fpr = TREE_CHAIN (f_gpr);
05934   f_res = TREE_CHAIN (f_fpr);
05935   f_ovf = TREE_CHAIN (f_res);
05936   f_sav = TREE_CHAIN (f_ovf);
05937 
05938   valist = build_va_arg_indirect_ref (valist);
05939   gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
05940   fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
05941   ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
05942   sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
05943 
05944   size = int_size_in_bytes (type);
05945   rsize = (size + 3) / 4;
05946   align = 1;
05947 
05948   if (TARGET_HARD_FLOAT && TARGET_FPRS
05949       && (TYPE_MODE (type) == SFmode
05950     || TYPE_MODE (type) == DFmode
05951     || TYPE_MODE (type) == TFmode))
05952     {
05953       /* FP args go in FP registers, if present.  */
05954       reg = fpr;
05955       n_reg = (size + 7) / 8;
05956       sav_ofs = 8*4;
05957       sav_scale = 8;
05958       if (TYPE_MODE (type) != SFmode)
05959   align = 8;
05960     }
05961   else
05962     {
05963       /* Otherwise into GP registers.  */
05964       reg = gpr;
05965       n_reg = rsize;
05966       sav_ofs = 0;
05967       sav_scale = 4;
05968       if (n_reg == 2)
05969   align = 8;
05970     }
05971 
05972   /* Pull the value out of the saved registers....  */
05973 
05974   lab_over = NULL;
05975   addr = create_tmp_var (ptr_type_node, "addr");
05976   DECL_POINTER_ALIAS_SET (addr) = get_varargs_alias_set ();
05977 
05978   /*  AltiVec vectors never go in registers when -mabi=altivec.  */
05979   if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
05980     align = 16;
05981   else
05982     {
05983       lab_false = create_artificial_label ();
05984       lab_over = create_artificial_label ();
05985 
05986       /* Long long and SPE vectors are aligned in the registers.
05987    As are any other 2 gpr item such as complex int due to a
05988    historical mistake.  */
05989       u = reg;
05990       if (n_reg == 2 && reg == gpr)
05991   {
05992     u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), reg,
05993          size_int (n_reg - 1));
05994     u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg, u);
05995   }
05996 
05997       t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
05998       t = build2 (GE_EXPR, boolean_type_node, u, t);
05999       u = build1 (GOTO_EXPR, void_type_node, lab_false);
06000       t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
06001       gimplify_and_add (t, pre_p);
06002 
06003       t = sav;
06004       if (sav_ofs)
06005   t = build2 (PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
06006 
06007       u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg, size_int (n_reg));
06008       u = build1 (CONVERT_EXPR, integer_type_node, u);
06009       u = build2 (MULT_EXPR, integer_type_node, u, size_int (sav_scale));
06010       t = build2 (PLUS_EXPR, ptr_type_node, t, u);
06011 
06012       t = build2 (MODIFY_EXPR, void_type_node, addr, t);
06013       gimplify_and_add (t, pre_p);
06014 
06015       t = build1 (GOTO_EXPR, void_type_node, lab_over);
06016       gimplify_and_add (t, pre_p);
06017 
06018       t = build1 (LABEL_EXPR, void_type_node, lab_false);
06019       append_to_statement_list (t, pre_p);
06020 
06021       if ((n_reg == 2 && reg != gpr) || n_reg > 2)
06022   {
06023     /* Ensure that we don't find any more args in regs.
06024        Alignment has taken care of the n_reg == 2 gpr case.  */
06025     t = build2 (MODIFY_EXPR, TREE_TYPE (reg), reg, size_int (8));
06026     gimplify_and_add (t, pre_p);
06027   }
06028     }
06029 
06030   /* ... otherwise out of the overflow area.  */
06031 
06032   /* Care for on-stack alignment if needed.  */
06033   t = ovf;
06034   if (align != 1)
06035     {
06036       t = build2 (PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
06037       t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
06038       build_int_cst (NULL_TREE, -align));
06039     }
06040   gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
06041 
06042   u = build2 (MODIFY_EXPR, void_type_node, addr, t);
06043   gimplify_and_add (u, pre_p);
06044 
06045   t = build2 (PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
06046   t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
06047   gimplify_and_add (t, pre_p);
06048 
06049   if (lab_over)
06050     {
06051       t = build1 (LABEL_EXPR, void_type_node, lab_over);
06052       append_to_statement_list (t, pre_p);
06053     }
06054 
06055   if (STRICT_ALIGNMENT
06056       && (TYPE_ALIGN (type)
06057     > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
06058     {
06059       /* The value (of type complex double, for example) may not be
06060    aligned in memory in the saved registers, so copy via a
06061    temporary.  (This is the same code as used for SPARC.)  */
06062       tree tmp = create_tmp_var (type, "va_arg_tmp");
06063       tree dest_addr = build_fold_addr_expr (tmp);
06064 
06065       tree copy = build_function_call_expr
06066   (implicit_built_in_decls[BUILT_IN_MEMCPY],
06067    tree_cons (NULL_TREE, dest_addr,
06068         tree_cons (NULL_TREE, addr,
06069              tree_cons (NULL_TREE, size_int (rsize * 4),
06070             NULL_TREE))));
06071 
06072       gimplify_and_add (copy, pre_p);
06073       addr = dest_addr;
06074     }
06075 
06076   addr = fold_convert (ptrtype, addr);
06077   return build_va_arg_indirect_ref (addr);
06078 }
06079 
06080 /* Builtins.  */
06081 
06082 static void
06083 def_builtin (int mask, const char *name, tree type, int code)
06084 {
06085   if (mask & target_flags)
06086     {
06087       if (rs6000_builtin_decls[code])
06088   abort ();
06089 
06090       rs6000_builtin_decls[code] =
06091         lang_hooks.builtin_function (name, type, code, BUILT_IN_MD,
06092              NULL, NULL_TREE);
06093     }
06094 }
06095 
06096 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc).  */
06097 
06098 static const struct builtin_description bdesc_3arg[] =
06099 {
06100   { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
06101   { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
06102   { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
06103   { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
06104   { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
06105   { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
06106   { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
06107   { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
06108   { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
06109   { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
06110   { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
06111   { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
06112   { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
06113   { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
06114   { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
06115   { MASK_ALTIVEC, CODE_FOR_altivec_vsel_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
06116   { MASK_ALTIVEC, CODE_FOR_altivec_vsel_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
06117   { MASK_ALTIVEC, CODE_FOR_altivec_vsel_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
06118   { MASK_ALTIVEC, CODE_FOR_altivec_vsel_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
06119   { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
06120   { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
06121   { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
06122   { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
06123 
06124   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
06125   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
06126   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
06127   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
06128   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
06129   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
06130   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
06131   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
06132   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
06133   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
06134   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
06135   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
06136   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
06137   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
06138   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
06139 };
06140 
06141 /* DST operations: void foo (void *, const int, const char).  */
06142 
06143 static const struct builtin_description bdesc_dst[] =
06144 {
06145   { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
06146   { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
06147   { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
06148   { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
06149 
06150   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
06151   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
06152   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
06153   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
06154 };
06155 
06156 /* Simple binary operations: VECc = foo (VECa, VECb).  */
06157 
06158 static struct builtin_description bdesc_2arg[] =
06159 {
06160   { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
06161   { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
06162   { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
06163   { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
06164   { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
06165   { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
06166   { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
06167   { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
06168   { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
06169   { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
06170   { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
06171   { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
06172   { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
06173   { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
06174   { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
06175   { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
06176   { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
06177   { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
06178   { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
06179   { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
06180   { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
06181   { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
06182   { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequb, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
06183   { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequh, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
06184   { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequw, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
06185   { MASK_ALTIVEC, CODE_FOR_altivec_vcmpeqfp, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
06186   { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgefp, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
06187   { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtub, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
06188   { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsb, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
06189   { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuh, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
06190   { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsh, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
06191   { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuw, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
06192   { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsw, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
06193   { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtfp, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
06194   { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
06195   { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
06196   { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
06197   { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
06198   { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
06199   { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
06200   { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
06201   { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
06202   { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
06203   { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
06204   { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
06205   { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
06206   { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
06207   { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
06208   { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
06209   { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
06210   { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
06211   { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
06212   { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
06213   { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
06214   { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
06215   { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
06216   { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
06217   { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
06218   { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
06219   { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
06220   { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
06221   { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
06222   { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
06223   { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
06224   { MASK_ALTIVEC, CODE_FOR_altivec_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
06225   { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
06226   { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
06227   { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
06228   { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
06229   { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
06230   { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
06231   { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
06232   { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
06233   { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
06234   { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
06235   { MASK_ALTIVEC, CODE_FOR_altivec_vrlb, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
06236   { MASK_ALTIVEC, CODE_FOR_altivec_vrlh, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
06237   { MASK_ALTIVEC, CODE_FOR_altivec_vrlw, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
06238   { MASK_ALTIVEC, CODE_FOR_altivec_vslb, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
06239   { MASK_ALTIVEC, CODE_FOR_altivec_vslh, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
06240   { MASK_ALTIVEC, CODE_FOR_altivec_vslw, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
06241   { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
06242   { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
06243   { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
06244   { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
06245   { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
06246   { MASK_ALTIVEC, CODE_FOR_lshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
06247   { MASK_ALTIVEC, CODE_FOR_lshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
06248   { MASK_ALTIVEC, CODE_FOR_lshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
06249   { MASK_ALTIVEC, CODE_FOR_ashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
06250   { MASK_ALTIVEC, CODE_FOR_ashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
06251   { MASK_ALTIVEC, CODE_FOR_ashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
06252   { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
06253   { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
06254   { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
06255   { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
06256   { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
06257   { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
06258   { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
06259   { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
06260   { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
06261   { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
06262   { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
06263   { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
06264   { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
06265   { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
06266   { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
06267   { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
06268   { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
06269   { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
06270   { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
06271 
06272   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
06273   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
06274   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
06275   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
06276   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
06277   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
06278   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
06279   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
06280   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
06281   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
06282   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
06283   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
06284   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
06285   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
06286   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
06287   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
06288   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
06289   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
06290   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
06291   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
06292   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
06293   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
06294   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
06295   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
06296   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
06297   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
06298   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
06299   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
06300   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
06301   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
06302   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
06303   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
06304   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
06305   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
06306   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
06307   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
06308   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
06309   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
06310   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
06311   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
06312   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
06313   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
06314   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
06315   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
06316   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
06317   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
06318   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
06319   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
06320   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
06321   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
06322   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
06323   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
06324   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
06325   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
06326   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
06327   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
06328   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
06329   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
06330   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
06331   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
06332   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
06333   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
06334   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
06335   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
06336   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
06337   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
06338   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
06339   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
06340   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
06341   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
06342   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
06343   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
06344   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
06345   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
06346   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
06347   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
06348   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
06349   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
06350   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
06351   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
06352   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
06353   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
06354   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
06355   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
06356   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
06357   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
06358   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
06359   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
06360   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
06361   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
06362   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
06363   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
06364   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
06365   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
06366   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
06367   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
06368   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
06369   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
06370   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
06371   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
06372   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
06373   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
06374   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
06375   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
06376   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
06377   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
06378   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro",