2011-03-21 Daniel Jacobowitz <dan@codesourcery.com>
[official-gcc.git] / gcc / config / rs6000 / rs6000.c
blobeca1b44f4ec3a5b5cc18b369be924df6ba1fa13b
1 /* Subroutines used for code generation on IBM RS/6000.
2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
4 Free Software Foundation, Inc.
5 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published
11 by the Free Software Foundation; either version 3, or (at your
12 option) any later version.
14 GCC is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "rtl.h"
28 #include "regs.h"
29 #include "hard-reg-set.h"
30 #include "insn-config.h"
31 #include "conditions.h"
32 #include "insn-attr.h"
33 #include "flags.h"
34 #include "recog.h"
35 #include "obstack.h"
36 #include "tree.h"
37 #include "expr.h"
38 #include "optabs.h"
39 #include "except.h"
40 #include "function.h"
41 #include "output.h"
42 #include "basic-block.h"
43 #include "integrate.h"
44 #include "diagnostic-core.h"
45 #include "toplev.h"
46 #include "ggc.h"
47 #include "hashtab.h"
48 #include "tm_p.h"
49 #include "target.h"
50 #include "target-def.h"
51 #include "langhooks.h"
52 #include "reload.h"
53 #include "cfglayout.h"
54 #include "cfgloop.h"
55 #include "sched-int.h"
56 #include "gimple.h"
57 #include "tree-flow.h"
58 #include "intl.h"
59 #include "params.h"
60 #include "tm-constrs.h"
61 #if TARGET_XCOFF
62 #include "xcoffout.h" /* get declarations of xcoff_*_section_name */
63 #endif
64 #if TARGET_MACHO
65 #include "gstab.h" /* for N_SLINE */
66 #endif
68 #ifndef TARGET_NO_PROTOTYPE
69 #define TARGET_NO_PROTOTYPE 0
70 #endif
72 #define min(A,B) ((A) < (B) ? (A) : (B))
73 #define max(A,B) ((A) > (B) ? (A) : (B))
75 /* Structure used to define the rs6000 stack */
76 typedef struct rs6000_stack {
77 int reload_completed; /* stack info won't change from here on */
78 int first_gp_reg_save; /* first callee saved GP register used */
79 int first_fp_reg_save; /* first callee saved FP register used */
80 int first_altivec_reg_save; /* first callee saved AltiVec register used */
81 int lr_save_p; /* true if the link reg needs to be saved */
82 int cr_save_p; /* true if the CR reg needs to be saved */
83 unsigned int vrsave_mask; /* mask of vec registers to save */
84 int push_p; /* true if we need to allocate stack space */
85 int calls_p; /* true if the function makes any calls */
86 int world_save_p; /* true if we're saving *everything*:
87 r13-r31, cr, f14-f31, vrsave, v20-v31 */
88 enum rs6000_abi abi; /* which ABI to use */
89 int gp_save_offset; /* offset to save GP regs from initial SP */
90 int fp_save_offset; /* offset to save FP regs from initial SP */
91 int altivec_save_offset; /* offset to save AltiVec regs from initial SP */
92 int lr_save_offset; /* offset to save LR from initial SP */
93 int cr_save_offset; /* offset to save CR from initial SP */
94 int vrsave_save_offset; /* offset to save VRSAVE from initial SP */
95 int spe_gp_save_offset; /* offset to save spe 64-bit gprs */
96 int varargs_save_offset; /* offset to save the varargs registers */
97 int ehrd_offset; /* offset to EH return data */
98 int reg_size; /* register size (4 or 8) */
99 HOST_WIDE_INT vars_size; /* variable save area size */
100 int parm_size; /* outgoing parameter size */
101 int save_size; /* save area size */
102 int fixed_size; /* fixed size of stack frame */
103 int gp_size; /* size of saved GP registers */
104 int fp_size; /* size of saved FP registers */
105 int altivec_size; /* size of saved AltiVec registers */
106 int cr_size; /* size to hold CR if not in save_size */
107 int vrsave_size; /* size to hold VRSAVE if not in save_size */
108 int altivec_padding_size; /* size of altivec alignment padding if
109 not in save_size */
110 int spe_gp_size; /* size of 64-bit GPR save size for SPE */
111 int spe_padding_size;
112 HOST_WIDE_INT total_size; /* total bytes allocated for stack */
113 int spe_64bit_regs_used;
114 int savres_strategy;
115 } rs6000_stack_t;
117 /* A C structure for machine-specific, per-function data.
118 This is added to the cfun structure. */
119 typedef struct GTY(()) machine_function
121 /* Some local-dynamic symbol. */
122 const char *some_ld_name;
123 /* Whether the instruction chain has been scanned already. */
124 int insn_chain_scanned_p;
125 /* Flags if __builtin_return_address (n) with n >= 1 was used. */
126 int ra_needs_full_frame;
127 /* Flags if __builtin_return_address (0) was used. */
128 int ra_need_lr;
129 /* Cache lr_save_p after expansion of builtin_eh_return. */
130 int lr_save_state;
131 /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4
132 varargs save area. */
133 HOST_WIDE_INT varargs_save_offset;
134 /* Temporary stack slot to use for SDmode copies. This slot is
135 64-bits wide and is allocated early enough so that the offset
136 does not overflow the 16-bit load/store offset field. */
137 rtx sdmode_stack_slot;
138 } machine_function;
140 /* Target cpu type */
142 struct rs6000_cpu_select rs6000_select[3] =
144 /* switch name, tune arch */
145 { (const char *)0, "--with-cpu=", 1, 1 },
146 { (const char *)0, "-mcpu=", 1, 1 },
147 { (const char *)0, "-mtune=", 1, 0 },
150 /* String variables to hold the various options. */
151 static const char *rs6000_sched_insert_nops_str;
152 static const char *rs6000_sched_costly_dep_str;
153 static const char *rs6000_recip_name;
155 #ifdef USING_ELFOS_H
156 static const char *rs6000_abi_name;
157 static const char *rs6000_sdata_name;
158 #endif
160 /* Support targetm.vectorize.builtin_mask_for_load. */
161 static GTY(()) tree altivec_builtin_mask_for_load;
163 /* Set to nonzero once AIX common-mode calls have been defined. */
164 static GTY(()) int common_mode_defined;
166 /* Label number of label created for -mrelocatable, to call to so we can
167 get the address of the GOT section */
168 static int rs6000_pic_labelno;
170 #ifdef USING_ELFOS_H
171 /* Counter for labels which are to be placed in .fixup. */
172 int fixuplabelno = 0;
173 #endif
175 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
176 int dot_symbols;
178 /* Specify the machine mode that pointers have. After generation of rtl, the
179 compiler makes no further distinction between pointers and any other objects
180 of this machine mode. The type is unsigned since not all things that
181 include rs6000.h also include machmode.h. */
182 unsigned rs6000_pmode;
184 /* Width in bits of a pointer. */
185 unsigned rs6000_pointer_size;
187 #ifdef HAVE_AS_GNU_ATTRIBUTE
188 /* Flag whether floating point values have been passed/returned. */
189 static bool rs6000_passes_float;
190 /* Flag whether vector values have been passed/returned. */
191 static bool rs6000_passes_vector;
192 /* Flag whether small (<= 8 byte) structures have been returned. */
193 static bool rs6000_returns_struct;
194 #endif
196 /* Value is TRUE if register/mode pair is acceptable. */
197 bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
199 /* Maximum number of registers needed for a given register class and mode. */
200 unsigned char rs6000_class_max_nregs[NUM_MACHINE_MODES][LIM_REG_CLASSES];
202 /* How many registers are needed for a given register and mode. */
203 unsigned char rs6000_hard_regno_nregs[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
205 /* Map register number to register class. */
206 enum reg_class rs6000_regno_regclass[FIRST_PSEUDO_REGISTER];
208 /* Reload functions based on the type and the vector unit. */
209 static enum insn_code rs6000_vector_reload[NUM_MACHINE_MODES][2];
211 /* Built in types. */
212 tree rs6000_builtin_types[RS6000_BTI_MAX];
213 tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
215 /* Flag to say the TOC is initialized */
216 int toc_initialized;
217 char toc_label_name[10];
219 /* Cached value of rs6000_variable_issue. This is cached in
220 rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */
221 static short cached_can_issue_more;
223 static GTY(()) section *read_only_data_section;
224 static GTY(()) section *private_data_section;
225 static GTY(()) section *read_only_private_data_section;
226 static GTY(()) section *sdata2_section;
227 static GTY(()) section *toc_section;
229 /* True for any options that were explicitly set. */
230 static struct {
231 bool aix_struct_ret; /* True if -maix-struct-ret was used. */
232 bool alignment; /* True if -malign- was used. */
233 bool spe_abi; /* True if -mabi=spe/no-spe was used. */
234 bool altivec_abi; /* True if -mabi=altivec/no-altivec used. */
235 bool spe; /* True if -mspe= was used. */
236 bool float_gprs; /* True if -mfloat-gprs= was used. */
237 bool long_double; /* True if -mlong-double- was used. */
238 bool ieee; /* True if -mabi=ieee/ibmlongdouble used. */
239 bool vrsave; /* True if -mvrsave was used. */
240 bool cmodel; /* True if -mcmodel was used. */
241 } rs6000_explicit_options;
243 struct builtin_description
245 /* mask is not const because we're going to alter it below. This
246 nonsense will go away when we rewrite the -march infrastructure
247 to give us more target flag bits. */
248 unsigned int mask;
249 const enum insn_code icode;
250 const char *const name;
251 const enum rs6000_builtins code;
254 /* Describe the vector unit used for modes. */
255 enum rs6000_vector rs6000_vector_unit[NUM_MACHINE_MODES];
256 enum rs6000_vector rs6000_vector_mem[NUM_MACHINE_MODES];
258 /* Register classes for various constraints that are based on the target
259 switches. */
260 enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX];
262 /* Describe the alignment of a vector. */
263 int rs6000_vector_align[NUM_MACHINE_MODES];
265 /* Map selected modes to types for builtins. */
266 static GTY(()) tree builtin_mode_to_type[MAX_MACHINE_MODE][2];
268 /* What modes to automatically generate reciprocal divide estimate (fre) and
269 reciprocal sqrt (frsqrte) for. */
270 unsigned char rs6000_recip_bits[MAX_MACHINE_MODE];
272 /* Masks to determine which reciprocal esitmate instructions to generate
273 automatically. */
274 enum rs6000_recip_mask {
275 RECIP_SF_DIV = 0x001, /* Use divide estimate */
276 RECIP_DF_DIV = 0x002,
277 RECIP_V4SF_DIV = 0x004,
278 RECIP_V2DF_DIV = 0x008,
280 RECIP_SF_RSQRT = 0x010, /* Use reciprocal sqrt estimate. */
281 RECIP_DF_RSQRT = 0x020,
282 RECIP_V4SF_RSQRT = 0x040,
283 RECIP_V2DF_RSQRT = 0x080,
285 /* Various combination of flags for -mrecip=xxx. */
286 RECIP_NONE = 0,
287 RECIP_ALL = (RECIP_SF_DIV | RECIP_DF_DIV | RECIP_V4SF_DIV
288 | RECIP_V2DF_DIV | RECIP_SF_RSQRT | RECIP_DF_RSQRT
289 | RECIP_V4SF_RSQRT | RECIP_V2DF_RSQRT),
291 RECIP_HIGH_PRECISION = RECIP_ALL,
293 /* On low precision machines like the power5, don't enable double precision
294 reciprocal square root estimate, since it isn't accurate enough. */
295 RECIP_LOW_PRECISION = (RECIP_ALL & ~(RECIP_DF_RSQRT | RECIP_V2DF_RSQRT))
298 /* -mrecip options. */
299 static struct
301 const char *string; /* option name */
302 unsigned int mask; /* mask bits to set */
303 } recip_options[] = {
304 { "all", RECIP_ALL },
305 { "none", RECIP_NONE },
306 { "div", (RECIP_SF_DIV | RECIP_DF_DIV | RECIP_V4SF_DIV
307 | RECIP_V2DF_DIV) },
308 { "divf", (RECIP_SF_DIV | RECIP_V4SF_DIV) },
309 { "divd", (RECIP_DF_DIV | RECIP_V2DF_DIV) },
310 { "rsqrt", (RECIP_SF_RSQRT | RECIP_DF_RSQRT | RECIP_V4SF_RSQRT
311 | RECIP_V2DF_RSQRT) },
312 { "rsqrtf", (RECIP_SF_RSQRT | RECIP_V4SF_RSQRT) },
313 { "rsqrtd", (RECIP_DF_RSQRT | RECIP_V2DF_RSQRT) },
316 /* 2 argument gen function typedef. */
317 typedef rtx (*gen_2arg_fn_t) (rtx, rtx, rtx);
320 /* Target cpu costs. */
322 struct processor_costs {
323 const int mulsi; /* cost of SImode multiplication. */
324 const int mulsi_const; /* cost of SImode multiplication by constant. */
325 const int mulsi_const9; /* cost of SImode mult by short constant. */
326 const int muldi; /* cost of DImode multiplication. */
327 const int divsi; /* cost of SImode division. */
328 const int divdi; /* cost of DImode division. */
329 const int fp; /* cost of simple SFmode and DFmode insns. */
330 const int dmul; /* cost of DFmode multiplication (and fmadd). */
331 const int sdiv; /* cost of SFmode division (fdivs). */
332 const int ddiv; /* cost of DFmode division (fdiv). */
333 const int cache_line_size; /* cache line size in bytes. */
334 const int l1_cache_size; /* size of l1 cache, in kilobytes. */
335 const int l2_cache_size; /* size of l2 cache, in kilobytes. */
336 const int simultaneous_prefetches; /* number of parallel prefetch
337 operations. */
340 const struct processor_costs *rs6000_cost;
342 /* Processor costs (relative to an add) */
344 /* Instruction size costs on 32bit processors. */
345 static const
346 struct processor_costs size32_cost = {
347 COSTS_N_INSNS (1), /* mulsi */
348 COSTS_N_INSNS (1), /* mulsi_const */
349 COSTS_N_INSNS (1), /* mulsi_const9 */
350 COSTS_N_INSNS (1), /* muldi */
351 COSTS_N_INSNS (1), /* divsi */
352 COSTS_N_INSNS (1), /* divdi */
353 COSTS_N_INSNS (1), /* fp */
354 COSTS_N_INSNS (1), /* dmul */
355 COSTS_N_INSNS (1), /* sdiv */
356 COSTS_N_INSNS (1), /* ddiv */
363 /* Instruction size costs on 64bit processors. */
364 static const
365 struct processor_costs size64_cost = {
366 COSTS_N_INSNS (1), /* mulsi */
367 COSTS_N_INSNS (1), /* mulsi_const */
368 COSTS_N_INSNS (1), /* mulsi_const9 */
369 COSTS_N_INSNS (1), /* muldi */
370 COSTS_N_INSNS (1), /* divsi */
371 COSTS_N_INSNS (1), /* divdi */
372 COSTS_N_INSNS (1), /* fp */
373 COSTS_N_INSNS (1), /* dmul */
374 COSTS_N_INSNS (1), /* sdiv */
375 COSTS_N_INSNS (1), /* ddiv */
376 128,
382 /* Instruction costs on RIOS1 processors. */
383 static const
384 struct processor_costs rios1_cost = {
385 COSTS_N_INSNS (5), /* mulsi */
386 COSTS_N_INSNS (4), /* mulsi_const */
387 COSTS_N_INSNS (3), /* mulsi_const9 */
388 COSTS_N_INSNS (5), /* muldi */
389 COSTS_N_INSNS (19), /* divsi */
390 COSTS_N_INSNS (19), /* divdi */
391 COSTS_N_INSNS (2), /* fp */
392 COSTS_N_INSNS (2), /* dmul */
393 COSTS_N_INSNS (19), /* sdiv */
394 COSTS_N_INSNS (19), /* ddiv */
395 128, /* cache line size */
396 64, /* l1 cache */
397 512, /* l2 cache */
398 0, /* streams */
401 /* Instruction costs on RIOS2 processors. */
402 static const
403 struct processor_costs rios2_cost = {
404 COSTS_N_INSNS (2), /* mulsi */
405 COSTS_N_INSNS (2), /* mulsi_const */
406 COSTS_N_INSNS (2), /* mulsi_const9 */
407 COSTS_N_INSNS (2), /* muldi */
408 COSTS_N_INSNS (13), /* divsi */
409 COSTS_N_INSNS (13), /* divdi */
410 COSTS_N_INSNS (2), /* fp */
411 COSTS_N_INSNS (2), /* dmul */
412 COSTS_N_INSNS (17), /* sdiv */
413 COSTS_N_INSNS (17), /* ddiv */
414 256, /* cache line size */
415 256, /* l1 cache */
416 1024, /* l2 cache */
417 0, /* streams */
420 /* Instruction costs on RS64A processors. */
421 static const
422 struct processor_costs rs64a_cost = {
423 COSTS_N_INSNS (20), /* mulsi */
424 COSTS_N_INSNS (12), /* mulsi_const */
425 COSTS_N_INSNS (8), /* mulsi_const9 */
426 COSTS_N_INSNS (34), /* muldi */
427 COSTS_N_INSNS (65), /* divsi */
428 COSTS_N_INSNS (67), /* divdi */
429 COSTS_N_INSNS (4), /* fp */
430 COSTS_N_INSNS (4), /* dmul */
431 COSTS_N_INSNS (31), /* sdiv */
432 COSTS_N_INSNS (31), /* ddiv */
433 128, /* cache line size */
434 128, /* l1 cache */
435 2048, /* l2 cache */
436 1, /* streams */
439 /* Instruction costs on MPCCORE processors. */
440 static const
441 struct processor_costs mpccore_cost = {
442 COSTS_N_INSNS (2), /* mulsi */
443 COSTS_N_INSNS (2), /* mulsi_const */
444 COSTS_N_INSNS (2), /* mulsi_const9 */
445 COSTS_N_INSNS (2), /* muldi */
446 COSTS_N_INSNS (6), /* divsi */
447 COSTS_N_INSNS (6), /* divdi */
448 COSTS_N_INSNS (4), /* fp */
449 COSTS_N_INSNS (5), /* dmul */
450 COSTS_N_INSNS (10), /* sdiv */
451 COSTS_N_INSNS (17), /* ddiv */
452 32, /* cache line size */
453 4, /* l1 cache */
454 16, /* l2 cache */
455 1, /* streams */
458 /* Instruction costs on PPC403 processors. */
459 static const
460 struct processor_costs ppc403_cost = {
461 COSTS_N_INSNS (4), /* mulsi */
462 COSTS_N_INSNS (4), /* mulsi_const */
463 COSTS_N_INSNS (4), /* mulsi_const9 */
464 COSTS_N_INSNS (4), /* muldi */
465 COSTS_N_INSNS (33), /* divsi */
466 COSTS_N_INSNS (33), /* divdi */
467 COSTS_N_INSNS (11), /* fp */
468 COSTS_N_INSNS (11), /* dmul */
469 COSTS_N_INSNS (11), /* sdiv */
470 COSTS_N_INSNS (11), /* ddiv */
471 32, /* cache line size */
472 4, /* l1 cache */
473 16, /* l2 cache */
474 1, /* streams */
477 /* Instruction costs on PPC405 processors. */
478 static const
479 struct processor_costs ppc405_cost = {
480 COSTS_N_INSNS (5), /* mulsi */
481 COSTS_N_INSNS (4), /* mulsi_const */
482 COSTS_N_INSNS (3), /* mulsi_const9 */
483 COSTS_N_INSNS (5), /* muldi */
484 COSTS_N_INSNS (35), /* divsi */
485 COSTS_N_INSNS (35), /* divdi */
486 COSTS_N_INSNS (11), /* fp */
487 COSTS_N_INSNS (11), /* dmul */
488 COSTS_N_INSNS (11), /* sdiv */
489 COSTS_N_INSNS (11), /* ddiv */
490 32, /* cache line size */
491 16, /* l1 cache */
492 128, /* l2 cache */
493 1, /* streams */
496 /* Instruction costs on PPC440 processors. */
497 static const
498 struct processor_costs ppc440_cost = {
499 COSTS_N_INSNS (3), /* mulsi */
500 COSTS_N_INSNS (2), /* mulsi_const */
501 COSTS_N_INSNS (2), /* mulsi_const9 */
502 COSTS_N_INSNS (3), /* muldi */
503 COSTS_N_INSNS (34), /* divsi */
504 COSTS_N_INSNS (34), /* divdi */
505 COSTS_N_INSNS (5), /* fp */
506 COSTS_N_INSNS (5), /* dmul */
507 COSTS_N_INSNS (19), /* sdiv */
508 COSTS_N_INSNS (33), /* ddiv */
509 32, /* cache line size */
510 32, /* l1 cache */
511 256, /* l2 cache */
512 1, /* streams */
515 /* Instruction costs on PPC476 processors. */
516 static const
517 struct processor_costs ppc476_cost = {
518 COSTS_N_INSNS (4), /* mulsi */
519 COSTS_N_INSNS (4), /* mulsi_const */
520 COSTS_N_INSNS (4), /* mulsi_const9 */
521 COSTS_N_INSNS (4), /* muldi */
522 COSTS_N_INSNS (11), /* divsi */
523 COSTS_N_INSNS (11), /* divdi */
524 COSTS_N_INSNS (6), /* fp */
525 COSTS_N_INSNS (6), /* dmul */
526 COSTS_N_INSNS (19), /* sdiv */
527 COSTS_N_INSNS (33), /* ddiv */
528 32, /* l1 cache line size */
529 32, /* l1 cache */
530 512, /* l2 cache */
531 1, /* streams */
534 /* Instruction costs on PPC601 processors. */
535 static const
536 struct processor_costs ppc601_cost = {
537 COSTS_N_INSNS (5), /* mulsi */
538 COSTS_N_INSNS (5), /* mulsi_const */
539 COSTS_N_INSNS (5), /* mulsi_const9 */
540 COSTS_N_INSNS (5), /* muldi */
541 COSTS_N_INSNS (36), /* divsi */
542 COSTS_N_INSNS (36), /* divdi */
543 COSTS_N_INSNS (4), /* fp */
544 COSTS_N_INSNS (5), /* dmul */
545 COSTS_N_INSNS (17), /* sdiv */
546 COSTS_N_INSNS (31), /* ddiv */
547 32, /* cache line size */
548 32, /* l1 cache */
549 256, /* l2 cache */
550 1, /* streams */
553 /* Instruction costs on PPC603 processors. */
554 static const
555 struct processor_costs ppc603_cost = {
556 COSTS_N_INSNS (5), /* mulsi */
557 COSTS_N_INSNS (3), /* mulsi_const */
558 COSTS_N_INSNS (2), /* mulsi_const9 */
559 COSTS_N_INSNS (5), /* muldi */
560 COSTS_N_INSNS (37), /* divsi */
561 COSTS_N_INSNS (37), /* divdi */
562 COSTS_N_INSNS (3), /* fp */
563 COSTS_N_INSNS (4), /* dmul */
564 COSTS_N_INSNS (18), /* sdiv */
565 COSTS_N_INSNS (33), /* ddiv */
566 32, /* cache line size */
567 8, /* l1 cache */
568 64, /* l2 cache */
569 1, /* streams */
572 /* Instruction costs on PPC604 processors. */
573 static const
574 struct processor_costs ppc604_cost = {
575 COSTS_N_INSNS (4), /* mulsi */
576 COSTS_N_INSNS (4), /* mulsi_const */
577 COSTS_N_INSNS (4), /* mulsi_const9 */
578 COSTS_N_INSNS (4), /* muldi */
579 COSTS_N_INSNS (20), /* divsi */
580 COSTS_N_INSNS (20), /* divdi */
581 COSTS_N_INSNS (3), /* fp */
582 COSTS_N_INSNS (3), /* dmul */
583 COSTS_N_INSNS (18), /* sdiv */
584 COSTS_N_INSNS (32), /* ddiv */
585 32, /* cache line size */
586 16, /* l1 cache */
587 512, /* l2 cache */
588 1, /* streams */
591 /* Instruction costs on PPC604e processors. */
592 static const
593 struct processor_costs ppc604e_cost = {
594 COSTS_N_INSNS (2), /* mulsi */
595 COSTS_N_INSNS (2), /* mulsi_const */
596 COSTS_N_INSNS (2), /* mulsi_const9 */
597 COSTS_N_INSNS (2), /* muldi */
598 COSTS_N_INSNS (20), /* divsi */
599 COSTS_N_INSNS (20), /* divdi */
600 COSTS_N_INSNS (3), /* fp */
601 COSTS_N_INSNS (3), /* dmul */
602 COSTS_N_INSNS (18), /* sdiv */
603 COSTS_N_INSNS (32), /* ddiv */
604 32, /* cache line size */
605 32, /* l1 cache */
606 1024, /* l2 cache */
607 1, /* streams */
610 /* Instruction costs on PPC620 processors. */
611 static const
612 struct processor_costs ppc620_cost = {
613 COSTS_N_INSNS (5), /* mulsi */
614 COSTS_N_INSNS (4), /* mulsi_const */
615 COSTS_N_INSNS (3), /* mulsi_const9 */
616 COSTS_N_INSNS (7), /* muldi */
617 COSTS_N_INSNS (21), /* divsi */
618 COSTS_N_INSNS (37), /* divdi */
619 COSTS_N_INSNS (3), /* fp */
620 COSTS_N_INSNS (3), /* dmul */
621 COSTS_N_INSNS (18), /* sdiv */
622 COSTS_N_INSNS (32), /* ddiv */
623 128, /* cache line size */
624 32, /* l1 cache */
625 1024, /* l2 cache */
626 1, /* streams */
629 /* Instruction costs on PPC630 processors. */
630 static const
631 struct processor_costs ppc630_cost = {
632 COSTS_N_INSNS (5), /* mulsi */
633 COSTS_N_INSNS (4), /* mulsi_const */
634 COSTS_N_INSNS (3), /* mulsi_const9 */
635 COSTS_N_INSNS (7), /* muldi */
636 COSTS_N_INSNS (21), /* divsi */
637 COSTS_N_INSNS (37), /* divdi */
638 COSTS_N_INSNS (3), /* fp */
639 COSTS_N_INSNS (3), /* dmul */
640 COSTS_N_INSNS (17), /* sdiv */
641 COSTS_N_INSNS (21), /* ddiv */
642 128, /* cache line size */
643 64, /* l1 cache */
644 1024, /* l2 cache */
645 1, /* streams */
648 /* Instruction costs on Cell processor. */
649 /* COSTS_N_INSNS (1) ~ one add. */
650 static const
651 struct processor_costs ppccell_cost = {
652 COSTS_N_INSNS (9/2)+2, /* mulsi */
653 COSTS_N_INSNS (6/2), /* mulsi_const */
654 COSTS_N_INSNS (6/2), /* mulsi_const9 */
655 COSTS_N_INSNS (15/2)+2, /* muldi */
656 COSTS_N_INSNS (38/2), /* divsi */
657 COSTS_N_INSNS (70/2), /* divdi */
658 COSTS_N_INSNS (10/2), /* fp */
659 COSTS_N_INSNS (10/2), /* dmul */
660 COSTS_N_INSNS (74/2), /* sdiv */
661 COSTS_N_INSNS (74/2), /* ddiv */
662 128, /* cache line size */
663 32, /* l1 cache */
664 512, /* l2 cache */
665 6, /* streams */
668 /* Instruction costs on PPC750 and PPC7400 processors. */
669 static const
670 struct processor_costs ppc750_cost = {
671 COSTS_N_INSNS (5), /* mulsi */
672 COSTS_N_INSNS (3), /* mulsi_const */
673 COSTS_N_INSNS (2), /* mulsi_const9 */
674 COSTS_N_INSNS (5), /* muldi */
675 COSTS_N_INSNS (17), /* divsi */
676 COSTS_N_INSNS (17), /* divdi */
677 COSTS_N_INSNS (3), /* fp */
678 COSTS_N_INSNS (3), /* dmul */
679 COSTS_N_INSNS (17), /* sdiv */
680 COSTS_N_INSNS (31), /* ddiv */
681 32, /* cache line size */
682 32, /* l1 cache */
683 512, /* l2 cache */
684 1, /* streams */
687 /* Instruction costs on PPC7450 processors. */
688 static const
689 struct processor_costs ppc7450_cost = {
690 COSTS_N_INSNS (4), /* mulsi */
691 COSTS_N_INSNS (3), /* mulsi_const */
692 COSTS_N_INSNS (3), /* mulsi_const9 */
693 COSTS_N_INSNS (4), /* muldi */
694 COSTS_N_INSNS (23), /* divsi */
695 COSTS_N_INSNS (23), /* divdi */
696 COSTS_N_INSNS (5), /* fp */
697 COSTS_N_INSNS (5), /* dmul */
698 COSTS_N_INSNS (21), /* sdiv */
699 COSTS_N_INSNS (35), /* ddiv */
700 32, /* cache line size */
701 32, /* l1 cache */
702 1024, /* l2 cache */
703 1, /* streams */
706 /* Instruction costs on PPC8540 processors. */
707 static const
708 struct processor_costs ppc8540_cost = {
709 COSTS_N_INSNS (4), /* mulsi */
710 COSTS_N_INSNS (4), /* mulsi_const */
711 COSTS_N_INSNS (4), /* mulsi_const9 */
712 COSTS_N_INSNS (4), /* muldi */
713 COSTS_N_INSNS (19), /* divsi */
714 COSTS_N_INSNS (19), /* divdi */
715 COSTS_N_INSNS (4), /* fp */
716 COSTS_N_INSNS (4), /* dmul */
717 COSTS_N_INSNS (29), /* sdiv */
718 COSTS_N_INSNS (29), /* ddiv */
719 32, /* cache line size */
720 32, /* l1 cache */
721 256, /* l2 cache */
722 1, /* prefetch streams /*/
725 /* Instruction costs on E300C2 and E300C3 cores. */
726 static const
727 struct processor_costs ppce300c2c3_cost = {
728 COSTS_N_INSNS (4), /* mulsi */
729 COSTS_N_INSNS (4), /* mulsi_const */
730 COSTS_N_INSNS (4), /* mulsi_const9 */
731 COSTS_N_INSNS (4), /* muldi */
732 COSTS_N_INSNS (19), /* divsi */
733 COSTS_N_INSNS (19), /* divdi */
734 COSTS_N_INSNS (3), /* fp */
735 COSTS_N_INSNS (4), /* dmul */
736 COSTS_N_INSNS (18), /* sdiv */
737 COSTS_N_INSNS (33), /* ddiv */
739 16, /* l1 cache */
740 16, /* l2 cache */
741 1, /* prefetch streams /*/
744 /* Instruction costs on PPCE500MC processors. */
745 static const
746 struct processor_costs ppce500mc_cost = {
747 COSTS_N_INSNS (4), /* mulsi */
748 COSTS_N_INSNS (4), /* mulsi_const */
749 COSTS_N_INSNS (4), /* mulsi_const9 */
750 COSTS_N_INSNS (4), /* muldi */
751 COSTS_N_INSNS (14), /* divsi */
752 COSTS_N_INSNS (14), /* divdi */
753 COSTS_N_INSNS (8), /* fp */
754 COSTS_N_INSNS (10), /* dmul */
755 COSTS_N_INSNS (36), /* sdiv */
756 COSTS_N_INSNS (66), /* ddiv */
757 64, /* cache line size */
758 32, /* l1 cache */
759 128, /* l2 cache */
760 1, /* prefetch streams /*/
763 /* Instruction costs on PPCE500MC64 processors. */
764 static const
765 struct processor_costs ppce500mc64_cost = {
766 COSTS_N_INSNS (4), /* mulsi */
767 COSTS_N_INSNS (4), /* mulsi_const */
768 COSTS_N_INSNS (4), /* mulsi_const9 */
769 COSTS_N_INSNS (4), /* muldi */
770 COSTS_N_INSNS (14), /* divsi */
771 COSTS_N_INSNS (14), /* divdi */
772 COSTS_N_INSNS (4), /* fp */
773 COSTS_N_INSNS (10), /* dmul */
774 COSTS_N_INSNS (36), /* sdiv */
775 COSTS_N_INSNS (66), /* ddiv */
776 64, /* cache line size */
777 32, /* l1 cache */
778 128, /* l2 cache */
779 1, /* prefetch streams /*/
782 /* Instruction costs on AppliedMicro Titan processors. */
783 static const
784 struct processor_costs titan_cost = {
785 COSTS_N_INSNS (5), /* mulsi */
786 COSTS_N_INSNS (5), /* mulsi_const */
787 COSTS_N_INSNS (5), /* mulsi_const9 */
788 COSTS_N_INSNS (5), /* muldi */
789 COSTS_N_INSNS (18), /* divsi */
790 COSTS_N_INSNS (18), /* divdi */
791 COSTS_N_INSNS (10), /* fp */
792 COSTS_N_INSNS (10), /* dmul */
793 COSTS_N_INSNS (46), /* sdiv */
794 COSTS_N_INSNS (72), /* ddiv */
795 32, /* cache line size */
796 32, /* l1 cache */
797 512, /* l2 cache */
798 1, /* prefetch streams /*/
801 /* Instruction costs on POWER4 and POWER5 processors. */
802 static const
803 struct processor_costs power4_cost = {
804 COSTS_N_INSNS (3), /* mulsi */
805 COSTS_N_INSNS (2), /* mulsi_const */
806 COSTS_N_INSNS (2), /* mulsi_const9 */
807 COSTS_N_INSNS (4), /* muldi */
808 COSTS_N_INSNS (18), /* divsi */
809 COSTS_N_INSNS (34), /* divdi */
810 COSTS_N_INSNS (3), /* fp */
811 COSTS_N_INSNS (3), /* dmul */
812 COSTS_N_INSNS (17), /* sdiv */
813 COSTS_N_INSNS (17), /* ddiv */
814 128, /* cache line size */
815 32, /* l1 cache */
816 1024, /* l2 cache */
817 8, /* prefetch streams /*/
820 /* Instruction costs on POWER6 processors. */
821 static const
822 struct processor_costs power6_cost = {
823 COSTS_N_INSNS (8), /* mulsi */
824 COSTS_N_INSNS (8), /* mulsi_const */
825 COSTS_N_INSNS (8), /* mulsi_const9 */
826 COSTS_N_INSNS (8), /* muldi */
827 COSTS_N_INSNS (22), /* divsi */
828 COSTS_N_INSNS (28), /* divdi */
829 COSTS_N_INSNS (3), /* fp */
830 COSTS_N_INSNS (3), /* dmul */
831 COSTS_N_INSNS (13), /* sdiv */
832 COSTS_N_INSNS (16), /* ddiv */
833 128, /* cache line size */
834 64, /* l1 cache */
835 2048, /* l2 cache */
836 16, /* prefetch streams */
839 /* Instruction costs on POWER7 processors. */
840 static const
841 struct processor_costs power7_cost = {
842 COSTS_N_INSNS (2), /* mulsi */
843 COSTS_N_INSNS (2), /* mulsi_const */
844 COSTS_N_INSNS (2), /* mulsi_const9 */
845 COSTS_N_INSNS (2), /* muldi */
846 COSTS_N_INSNS (18), /* divsi */
847 COSTS_N_INSNS (34), /* divdi */
848 COSTS_N_INSNS (3), /* fp */
849 COSTS_N_INSNS (3), /* dmul */
850 COSTS_N_INSNS (13), /* sdiv */
851 COSTS_N_INSNS (16), /* ddiv */
852 128, /* cache line size */
853 32, /* l1 cache */
854 256, /* l2 cache */
855 12, /* prefetch streams */
858 /* Instruction costs on POWER A2 processors. */
859 static const
860 struct processor_costs ppca2_cost = {
861 COSTS_N_INSNS (16), /* mulsi */
862 COSTS_N_INSNS (16), /* mulsi_const */
863 COSTS_N_INSNS (16), /* mulsi_const9 */
864 COSTS_N_INSNS (16), /* muldi */
865 COSTS_N_INSNS (22), /* divsi */
866 COSTS_N_INSNS (28), /* divdi */
867 COSTS_N_INSNS (3), /* fp */
868 COSTS_N_INSNS (3), /* dmul */
869 COSTS_N_INSNS (59), /* sdiv */
870 COSTS_N_INSNS (72), /* ddiv */
872 16, /* l1 cache */
873 2048, /* l2 cache */
874 16, /* prefetch streams */
878 /* Table that classifies rs6000 builtin functions (pure, const, etc.). */
879 #undef RS6000_BUILTIN
880 #undef RS6000_BUILTIN_EQUATE
881 #define RS6000_BUILTIN(NAME, TYPE) TYPE,
882 #define RS6000_BUILTIN_EQUATE(NAME, VALUE)
884 static const enum rs6000_btc builtin_classify[(int)RS6000_BUILTIN_COUNT] =
886 #include "rs6000-builtin.def"
889 #undef RS6000_BUILTIN
890 #undef RS6000_BUILTIN_EQUATE
892 /* Support for -mveclibabi=<xxx> to control which vector library to use. */
893 static tree (*rs6000_veclib_handler) (tree, tree, tree);
896 static bool rs6000_function_ok_for_sibcall (tree, tree);
897 static const char *rs6000_invalid_within_doloop (const_rtx);
898 static bool rs6000_legitimate_address_p (enum machine_mode, rtx, bool);
899 static bool rs6000_debug_legitimate_address_p (enum machine_mode, rtx, bool);
900 static rtx rs6000_generate_compare (rtx, enum machine_mode);
901 static void rs6000_emit_stack_tie (void);
902 static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
903 static bool spe_func_has_64bit_regs_p (void);
904 static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int,
905 int, HOST_WIDE_INT);
906 static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
907 static unsigned rs6000_hash_constant (rtx);
908 static unsigned toc_hash_function (const void *);
909 static int toc_hash_eq (const void *, const void *);
910 static bool reg_offset_addressing_ok_p (enum machine_mode);
911 static bool virtual_stack_registers_memory_p (rtx);
912 static bool constant_pool_expr_p (rtx);
913 static bool legitimate_small_data_p (enum machine_mode, rtx);
914 static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
915 static struct machine_function * rs6000_init_machine_status (void);
916 static bool rs6000_assemble_integer (rtx, unsigned int, int);
917 static bool no_global_regs_above (int, bool);
918 #ifdef HAVE_GAS_HIDDEN
919 static void rs6000_assemble_visibility (tree, int);
920 #endif
921 static int rs6000_ra_ever_killed (void);
922 static bool rs6000_attribute_takes_identifier_p (const_tree);
923 static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
924 static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
925 static bool rs6000_ms_bitfield_layout_p (const_tree);
926 static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *);
927 static void rs6000_eliminate_indexed_memrefs (rtx operands[2]);
928 static const char *rs6000_mangle_type (const_tree);
929 static void rs6000_set_default_type_attributes (tree);
930 static rtx rs6000_savres_routine_sym (rs6000_stack_t *, bool, bool, bool);
931 static rtx rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool);
932 static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int,
933 enum machine_mode, bool, bool, bool);
934 static bool rs6000_reg_live_or_pic_offset_p (int);
935 static tree rs6000_builtin_vectorized_libmass (tree, tree, tree);
936 static tree rs6000_builtin_vectorized_function (tree, tree, tree);
937 static void rs6000_restore_saved_cr (rtx, int);
938 static bool rs6000_output_addr_const_extra (FILE *, rtx);
939 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
940 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
941 static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
942 tree);
943 static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
944 static bool rs6000_return_in_memory (const_tree, const_tree);
945 static rtx rs6000_function_value (const_tree, const_tree, bool);
946 static void rs6000_file_start (void);
947 #if TARGET_ELF
948 static int rs6000_elf_reloc_rw_mask (void);
949 static void rs6000_elf_asm_out_constructor (rtx, int) ATTRIBUTE_UNUSED;
950 static void rs6000_elf_asm_out_destructor (rtx, int) ATTRIBUTE_UNUSED;
951 static void rs6000_elf_file_end (void) ATTRIBUTE_UNUSED;
952 static void rs6000_elf_asm_init_sections (void);
953 static section *rs6000_elf_select_rtx_section (enum machine_mode, rtx,
954 unsigned HOST_WIDE_INT);
955 static void rs6000_elf_encode_section_info (tree, rtx, int)
956 ATTRIBUTE_UNUSED;
957 #endif
958 static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx);
959 static void rs6000_alloc_sdmode_stack_slot (void);
960 static void rs6000_instantiate_decls (void);
961 #if TARGET_XCOFF
962 static void rs6000_xcoff_asm_output_anchor (rtx);
963 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
964 static void rs6000_xcoff_asm_init_sections (void);
965 static int rs6000_xcoff_reloc_rw_mask (void);
966 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree);
967 static section *rs6000_xcoff_select_section (tree, int,
968 unsigned HOST_WIDE_INT);
969 static void rs6000_xcoff_unique_section (tree, int);
970 static section *rs6000_xcoff_select_rtx_section
971 (enum machine_mode, rtx, unsigned HOST_WIDE_INT);
972 static const char * rs6000_xcoff_strip_name_encoding (const char *);
973 static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
974 static void rs6000_xcoff_file_start (void);
975 static void rs6000_xcoff_file_end (void);
976 #endif
977 static int rs6000_variable_issue (FILE *, int, rtx, int);
978 static int rs6000_register_move_cost (enum machine_mode,
979 reg_class_t, reg_class_t);
980 static int rs6000_memory_move_cost (enum machine_mode, reg_class_t, bool);
981 static bool rs6000_rtx_costs (rtx, int, int, int *, bool);
982 static bool rs6000_debug_rtx_costs (rtx, int, int, int *, bool);
983 static int rs6000_debug_address_cost (rtx, bool);
984 static int rs6000_adjust_cost (rtx, rtx, rtx, int);
985 static int rs6000_debug_adjust_cost (rtx, rtx, rtx, int);
986 static void rs6000_sched_init (FILE *, int, int);
987 static bool is_microcoded_insn (rtx);
988 static bool is_nonpipeline_insn (rtx);
989 static bool is_cracked_insn (rtx);
990 static bool is_branch_slot_insn (rtx);
991 static bool is_load_insn (rtx);
992 static rtx get_store_dest (rtx pat);
993 static bool is_store_insn (rtx);
994 static bool set_to_load_agen (rtx,rtx);
995 static bool adjacent_mem_locations (rtx,rtx);
996 static int rs6000_adjust_priority (rtx, int);
997 static int rs6000_issue_rate (void);
998 static bool rs6000_is_costly_dependence (dep_t, int, int);
999 static rtx get_next_active_insn (rtx, rtx);
1000 static bool insn_terminates_group_p (rtx , enum group_termination);
1001 static bool insn_must_be_first_in_group (rtx);
1002 static bool insn_must_be_last_in_group (rtx);
1003 static bool is_costly_group (rtx *, rtx);
1004 static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
1005 static int redefine_groups (FILE *, int, rtx, rtx);
1006 static int pad_groups (FILE *, int, rtx, rtx);
1007 static void rs6000_sched_finish (FILE *, int);
1008 static int rs6000_sched_reorder (FILE *, int, rtx *, int *, int);
1009 static int rs6000_sched_reorder2 (FILE *, int, rtx *, int *, int);
1010 static int rs6000_use_sched_lookahead (void);
1011 static int rs6000_use_sched_lookahead_guard (rtx);
1012 static void * rs6000_alloc_sched_context (void);
1013 static void rs6000_init_sched_context (void *, bool);
1014 static void rs6000_set_sched_context (void *);
1015 static void rs6000_free_sched_context (void *);
1016 static tree rs6000_builtin_reciprocal (unsigned int, bool, bool);
1017 static tree rs6000_builtin_mask_for_load (void);
1018 static tree rs6000_builtin_mul_widen_even (tree);
1019 static tree rs6000_builtin_mul_widen_odd (tree);
1020 static tree rs6000_builtin_conversion (unsigned int, tree, tree);
1021 static tree rs6000_builtin_vec_perm (tree, tree *);
1022 static bool rs6000_builtin_support_vector_misalignment (enum
1023 machine_mode,
1024 const_tree,
1025 int, bool);
1026 static int rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt,
1027 tree, int);
1028 static enum machine_mode rs6000_preferred_simd_mode (enum machine_mode);
1030 static void def_builtin (int, const char *, tree, int);
1031 static bool rs6000_vector_alignment_reachable (const_tree, bool);
1032 static void rs6000_init_builtins (void);
1033 static tree rs6000_builtin_decl (unsigned, bool);
1035 static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
1036 static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
1037 static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
1038 static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
1039 static void altivec_init_builtins (void);
1040 static unsigned builtin_hash_function (const void *);
1041 static int builtin_hash_eq (const void *, const void *);
1042 static tree builtin_function_type (enum machine_mode, enum machine_mode,
1043 enum machine_mode, enum machine_mode,
1044 enum rs6000_builtins, const char *name);
1045 static void rs6000_common_init_builtins (void);
1046 static void rs6000_init_libfuncs (void);
1048 static void paired_init_builtins (void);
1049 static rtx paired_expand_builtin (tree, rtx, bool *);
1050 static rtx paired_expand_lv_builtin (enum insn_code, tree, rtx);
1051 static rtx paired_expand_stv_builtin (enum insn_code, tree);
1052 static rtx paired_expand_predicate_builtin (enum insn_code, tree, rtx);
1054 static void enable_mask_for_builtins (struct builtin_description *, int,
1055 enum rs6000_builtins,
1056 enum rs6000_builtins);
1057 static void spe_init_builtins (void);
1058 static rtx spe_expand_builtin (tree, rtx, bool *);
1059 static rtx spe_expand_stv_builtin (enum insn_code, tree);
1060 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
1061 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
1062 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
1063 static rs6000_stack_t *rs6000_stack_info (void);
1064 static void debug_stack_info (rs6000_stack_t *);
1066 static rtx altivec_expand_builtin (tree, rtx, bool *);
1067 static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
1068 static rtx altivec_expand_st_builtin (tree, rtx, bool *);
1069 static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
1070 static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
1071 static rtx altivec_expand_predicate_builtin (enum insn_code, tree, rtx);
1072 static rtx altivec_expand_stv_builtin (enum insn_code, tree);
1073 static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
1074 static rtx altivec_expand_vec_set_builtin (tree);
1075 static rtx altivec_expand_vec_ext_builtin (tree, rtx);
1076 static int get_element_number (tree, tree);
1077 static void rs6000_option_override (void);
1078 static void rs6000_option_init_struct (struct gcc_options *);
1079 static void rs6000_option_default_params (void);
1080 static bool rs6000_handle_option (size_t, const char *, int);
1081 static int rs6000_loop_align_max_skip (rtx);
1082 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
1083 static int first_altivec_reg_to_save (void);
1084 static unsigned int compute_vrsave_mask (void);
1085 static void compute_save_world_info (rs6000_stack_t *info_ptr);
1086 static void is_altivec_return_reg (rtx, void *);
1087 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
1088 int easy_vector_constant (rtx, enum machine_mode);
1089 static rtx rs6000_dwarf_register_span (rtx);
1090 static void rs6000_init_dwarf_reg_sizes_extra (tree);
1091 static rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode);
1092 static rtx rs6000_debug_legitimize_address (rtx, rtx, enum machine_mode);
1093 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
1094 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
1095 static rtx rs6000_delegitimize_address (rtx);
1096 static rtx rs6000_tls_get_addr (void);
1097 static rtx rs6000_got_sym (void);
1098 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
1099 static const char *rs6000_get_some_local_dynamic_name (void);
1100 static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
1101 static rtx rs6000_complex_function_value (enum machine_mode);
1102 static rtx rs6000_spe_function_arg (const CUMULATIVE_ARGS *,
1103 enum machine_mode, const_tree);
1104 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
1105 HOST_WIDE_INT, int);
1106 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
1107 const_tree,
1108 HOST_WIDE_INT);
1109 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
1110 HOST_WIDE_INT,
1111 rtx[], int *);
1112 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
1113 const_tree, HOST_WIDE_INT,
1114 rtx[], int *);
1115 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, bool, bool);
1116 static rtx rs6000_mixed_function_arg (enum machine_mode, const_tree, int);
1117 static void rs6000_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
1118 const_tree, bool);
1119 static rtx rs6000_function_arg (CUMULATIVE_ARGS *, enum machine_mode,
1120 const_tree, bool);
1121 static unsigned int rs6000_function_arg_boundary (enum machine_mode,
1122 const_tree);
1123 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
1124 static void setup_incoming_varargs (CUMULATIVE_ARGS *,
1125 enum machine_mode, tree,
1126 int *, int);
1127 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
1128 const_tree, bool);
1129 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
1130 tree, bool);
1131 static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree);
1132 #if TARGET_MACHO
1133 static void macho_branch_islands (void);
1134 static int no_previous_def (tree function_name);
1135 static tree get_prev_label (tree function_name);
1136 static void rs6000_darwin_file_start (void);
1137 #endif
1139 static tree rs6000_build_builtin_va_list (void);
1140 static void rs6000_va_start (tree, rtx);
1141 static tree rs6000_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
1142 static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree);
1143 static bool rs6000_scalar_mode_supported_p (enum machine_mode);
1144 static bool rs6000_vector_mode_supported_p (enum machine_mode);
1145 static rtx rs6000_emit_vector_compare_inner (enum rtx_code, rtx, rtx);
1146 static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
1147 enum machine_mode);
1148 static tree rs6000_stack_protect_fail (void);
1150 static rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, int, int,
1151 int, int *);
1153 static rtx rs6000_debug_legitimize_reload_address (rtx, enum machine_mode, int,
1154 int, int, int *);
1156 rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode, int, int,
1157 int, int *)
1158 = rs6000_legitimize_reload_address;
1160 static bool rs6000_mode_dependent_address_p (const_rtx);
1161 static bool rs6000_mode_dependent_address (const_rtx);
1162 static bool rs6000_debug_mode_dependent_address (const_rtx);
1163 static bool (*rs6000_mode_dependent_address_ptr) (const_rtx)
1164 = rs6000_mode_dependent_address;
1166 static enum reg_class rs6000_secondary_reload_class (enum reg_class,
1167 enum machine_mode, rtx);
1168 static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class,
1169 enum machine_mode,
1170 rtx);
1171 enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class,
1172 enum machine_mode, rtx)
1173 = rs6000_secondary_reload_class;
1175 static enum reg_class rs6000_preferred_reload_class (rtx, enum reg_class);
1176 static enum reg_class rs6000_debug_preferred_reload_class (rtx,
1177 enum reg_class);
1178 enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, enum reg_class)
1179 = rs6000_preferred_reload_class;
1181 static bool rs6000_secondary_memory_needed (enum reg_class, enum reg_class,
1182 enum machine_mode);
1184 static bool rs6000_debug_secondary_memory_needed (enum reg_class,
1185 enum reg_class,
1186 enum machine_mode);
1188 bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class,
1189 enum machine_mode)
1190 = rs6000_secondary_memory_needed;
1192 static bool rs6000_cannot_change_mode_class (enum machine_mode,
1193 enum machine_mode,
1194 enum reg_class);
1195 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode,
1196 enum machine_mode,
1197 enum reg_class);
1199 bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode,
1200 enum machine_mode,
1201 enum reg_class)
1202 = rs6000_cannot_change_mode_class;
1204 static reg_class_t rs6000_secondary_reload (bool, rtx, reg_class_t,
1205 enum machine_mode,
1206 struct secondary_reload_info *);
1208 static const reg_class_t *rs6000_ira_cover_classes (void);
1210 const int INSN_NOT_AVAILABLE = -1;
1211 static enum machine_mode rs6000_eh_return_filter_mode (void);
1212 static bool rs6000_can_eliminate (const int, const int);
1213 static void rs6000_conditional_register_usage (void);
1214 static void rs6000_trampoline_init (rtx, tree, rtx);
1216 /* Hash table stuff for keeping track of TOC entries. */
1218 struct GTY(()) toc_hash_struct
1220 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1221 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1222 rtx key;
1223 enum machine_mode key_mode;
1224 int labelno;
1227 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
1229 /* Hash table to keep track of the argument types for builtin functions. */
1231 struct GTY(()) builtin_hash_struct
1233 tree type;
1234 enum machine_mode mode[4]; /* return value + 3 arguments. */
1235 unsigned char uns_p[4]; /* and whether the types are unsigned. */
1238 static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table;
1240 static bool rs6000_valid_attribute_p (tree, tree, tree, int);
1241 static void rs6000_function_specific_save (struct cl_target_option *);
1242 static void rs6000_function_specific_restore (struct cl_target_option *);
1243 static void rs6000_function_specific_print (FILE *, int,
1244 struct cl_target_option *);
1245 static bool rs6000_can_inline_p (tree, tree);
1246 static void rs6000_set_current_function (tree);
1249 /* Default register names. */
1250 char rs6000_reg_names[][8] =
1252 "0", "1", "2", "3", "4", "5", "6", "7",
1253 "8", "9", "10", "11", "12", "13", "14", "15",
1254 "16", "17", "18", "19", "20", "21", "22", "23",
1255 "24", "25", "26", "27", "28", "29", "30", "31",
1256 "0", "1", "2", "3", "4", "5", "6", "7",
1257 "8", "9", "10", "11", "12", "13", "14", "15",
1258 "16", "17", "18", "19", "20", "21", "22", "23",
1259 "24", "25", "26", "27", "28", "29", "30", "31",
1260 "mq", "lr", "ctr","ap",
1261 "0", "1", "2", "3", "4", "5", "6", "7",
1262 "ca",
1263 /* AltiVec registers. */
1264 "0", "1", "2", "3", "4", "5", "6", "7",
1265 "8", "9", "10", "11", "12", "13", "14", "15",
1266 "16", "17", "18", "19", "20", "21", "22", "23",
1267 "24", "25", "26", "27", "28", "29", "30", "31",
1268 "vrsave", "vscr",
1269 /* SPE registers. */
1270 "spe_acc", "spefscr",
1271 /* Soft frame pointer. */
1272 "sfp"
1275 #ifdef TARGET_REGNAMES
1276 static const char alt_reg_names[][8] =
1278 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1279 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1280 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1281 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1282 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1283 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1284 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1285 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1286 "mq", "lr", "ctr", "ap",
1287 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1288 "ca",
1289 /* AltiVec registers. */
1290 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1291 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1292 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1293 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1294 "vrsave", "vscr",
1295 /* SPE registers. */
1296 "spe_acc", "spefscr",
1297 /* Soft frame pointer. */
1298 "sfp"
1300 #endif
1302 /* Table of valid machine attributes. */
1304 static const struct attribute_spec rs6000_attribute_table[] =
1306 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
1307 affects_type_identity } */
1308 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute,
1309 false },
1310 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute,
1311 false },
1312 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute,
1313 false },
1314 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute,
1315 false },
1316 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute,
1317 false },
1318 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1319 SUBTARGET_ATTRIBUTE_TABLE,
1320 #endif
1321 { NULL, 0, 0, false, false, false, NULL, false }
1324 /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */
1325 static const struct default_options rs6000_option_optimization_table[] =
1327 { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
1328 { OPT_LEVELS_NONE, 0, NULL, 0 }
1331 #ifndef MASK_STRICT_ALIGN
1332 #define MASK_STRICT_ALIGN 0
1333 #endif
1334 #ifndef TARGET_PROFILE_KERNEL
1335 #define TARGET_PROFILE_KERNEL 0
1336 #endif
1338 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1339 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1341 /* Initialize the GCC target structure. */
1342 #undef TARGET_ATTRIBUTE_TABLE
1343 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1344 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1345 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1346 #undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P
1347 #define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P rs6000_attribute_takes_identifier_p
1349 #undef TARGET_ASM_ALIGNED_DI_OP
1350 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1352 /* Default unaligned ops are only provided for ELF. Find the ops needed
1353 for non-ELF systems. */
1354 #ifndef OBJECT_FORMAT_ELF
1355 #if TARGET_XCOFF
1356 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1357 64-bit targets. */
1358 #undef TARGET_ASM_UNALIGNED_HI_OP
1359 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1360 #undef TARGET_ASM_UNALIGNED_SI_OP
1361 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1362 #undef TARGET_ASM_UNALIGNED_DI_OP
1363 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1364 #else
1365 /* For Darwin. */
1366 #undef TARGET_ASM_UNALIGNED_HI_OP
1367 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1368 #undef TARGET_ASM_UNALIGNED_SI_OP
1369 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1370 #undef TARGET_ASM_UNALIGNED_DI_OP
1371 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1372 #undef TARGET_ASM_ALIGNED_DI_OP
1373 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1374 #endif
1375 #endif
1377 /* This hook deals with fixups for relocatable code and DI-mode objects
1378 in 64-bit code. */
1379 #undef TARGET_ASM_INTEGER
1380 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1382 #ifdef HAVE_GAS_HIDDEN
1383 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1384 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1385 #endif
1387 #undef TARGET_HAVE_TLS
1388 #define TARGET_HAVE_TLS HAVE_AS_TLS
1390 #undef TARGET_CANNOT_FORCE_CONST_MEM
1391 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1393 #undef TARGET_DELEGITIMIZE_ADDRESS
1394 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1396 #undef TARGET_ASM_FUNCTION_PROLOGUE
1397 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1398 #undef TARGET_ASM_FUNCTION_EPILOGUE
1399 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1401 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
1402 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA rs6000_output_addr_const_extra
1404 #undef TARGET_LEGITIMIZE_ADDRESS
1405 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1407 #undef TARGET_SCHED_VARIABLE_ISSUE
1408 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1410 #undef TARGET_SCHED_ISSUE_RATE
1411 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1412 #undef TARGET_SCHED_ADJUST_COST
1413 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1414 #undef TARGET_SCHED_ADJUST_PRIORITY
1415 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1416 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1417 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1418 #undef TARGET_SCHED_INIT
1419 #define TARGET_SCHED_INIT rs6000_sched_init
1420 #undef TARGET_SCHED_FINISH
1421 #define TARGET_SCHED_FINISH rs6000_sched_finish
1422 #undef TARGET_SCHED_REORDER
1423 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1424 #undef TARGET_SCHED_REORDER2
1425 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1427 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1428 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1430 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1431 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1433 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1434 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1435 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1436 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1437 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1438 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1439 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1440 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1442 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1443 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1444 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1445 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1446 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1447 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1448 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1449 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1450 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1451 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1452 #undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
1453 #define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT \
1454 rs6000_builtin_support_vector_misalignment
1455 #undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE
1456 #define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1457 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
1458 #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
1459 rs6000_builtin_vectorization_cost
1460 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
1461 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE \
1462 rs6000_preferred_simd_mode
1464 #undef TARGET_INIT_BUILTINS
1465 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1466 #undef TARGET_BUILTIN_DECL
1467 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1469 #undef TARGET_EXPAND_BUILTIN
1470 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1472 #undef TARGET_MANGLE_TYPE
1473 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1475 #undef TARGET_INIT_LIBFUNCS
1476 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1478 #if TARGET_MACHO
1479 #undef TARGET_BINDS_LOCAL_P
1480 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1481 #endif
1483 #undef TARGET_MS_BITFIELD_LAYOUT_P
1484 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1486 #undef TARGET_ASM_OUTPUT_MI_THUNK
1487 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1489 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1490 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1492 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1493 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1495 #undef TARGET_INVALID_WITHIN_DOLOOP
1496 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1498 #undef TARGET_REGISTER_MOVE_COST
1499 #define TARGET_REGISTER_MOVE_COST rs6000_register_move_cost
1500 #undef TARGET_MEMORY_MOVE_COST
1501 #define TARGET_MEMORY_MOVE_COST rs6000_memory_move_cost
1502 #undef TARGET_RTX_COSTS
1503 #define TARGET_RTX_COSTS rs6000_rtx_costs
1504 #undef TARGET_ADDRESS_COST
1505 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1507 #undef TARGET_DWARF_REGISTER_SPAN
1508 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1510 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1511 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1513 /* On rs6000, function arguments are promoted, as are function return
1514 values. */
1515 #undef TARGET_PROMOTE_FUNCTION_MODE
1516 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1518 #undef TARGET_RETURN_IN_MEMORY
1519 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1521 #undef TARGET_SETUP_INCOMING_VARARGS
1522 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1524 /* Always strict argument naming on rs6000. */
1525 #undef TARGET_STRICT_ARGUMENT_NAMING
1526 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1527 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1528 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1529 #undef TARGET_SPLIT_COMPLEX_ARG
1530 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1531 #undef TARGET_MUST_PASS_IN_STACK
1532 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1533 #undef TARGET_PASS_BY_REFERENCE
1534 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1535 #undef TARGET_ARG_PARTIAL_BYTES
1536 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1537 #undef TARGET_FUNCTION_ARG_ADVANCE
1538 #define TARGET_FUNCTION_ARG_ADVANCE rs6000_function_arg_advance
1539 #undef TARGET_FUNCTION_ARG
1540 #define TARGET_FUNCTION_ARG rs6000_function_arg
1541 #undef TARGET_FUNCTION_ARG_BOUNDARY
1542 #define TARGET_FUNCTION_ARG_BOUNDARY rs6000_function_arg_boundary
1544 #undef TARGET_BUILD_BUILTIN_VA_LIST
1545 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1547 #undef TARGET_EXPAND_BUILTIN_VA_START
1548 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1550 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1551 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1553 #undef TARGET_EH_RETURN_FILTER_MODE
1554 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1556 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1557 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1559 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1560 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1562 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1563 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1565 #undef TARGET_HANDLE_OPTION
1566 #define TARGET_HANDLE_OPTION rs6000_handle_option
1568 #undef TARGET_ASM_LOOP_ALIGN_MAX_SKIP
1569 #define TARGET_ASM_LOOP_ALIGN_MAX_SKIP rs6000_loop_align_max_skip
1571 #undef TARGET_OPTION_OVERRIDE
1572 #define TARGET_OPTION_OVERRIDE rs6000_option_override
1574 #undef TARGET_OPTION_INIT_STRUCT
1575 #define TARGET_OPTION_INIT_STRUCT rs6000_option_init_struct
1577 #undef TARGET_OPTION_DEFAULT_PARAMS
1578 #define TARGET_OPTION_DEFAULT_PARAMS rs6000_option_default_params
1580 #undef TARGET_OPTION_OPTIMIZATION_TABLE
1581 #define TARGET_OPTION_OPTIMIZATION_TABLE rs6000_option_optimization_table
1583 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1584 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1585 rs6000_builtin_vectorized_function
1587 #undef TARGET_DEFAULT_TARGET_FLAGS
1588 #define TARGET_DEFAULT_TARGET_FLAGS \
1589 (TARGET_DEFAULT)
1591 #undef TARGET_STACK_PROTECT_FAIL
1592 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1594 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1595 The PowerPC architecture requires only weak consistency among
1596 processors--that is, memory accesses between processors need not be
1597 sequentially consistent and memory accesses among processors can occur
1598 in any order. The ability to order memory accesses weakly provides
1599 opportunities for more efficient use of the system bus. Unless a
1600 dependency exists, the 604e allows read operations to precede store
1601 operations. */
1602 #undef TARGET_RELAXED_ORDERING
1603 #define TARGET_RELAXED_ORDERING true
1605 #ifdef HAVE_AS_TLS
1606 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1607 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1608 #endif
1610 /* Use a 32-bit anchor range. This leads to sequences like:
1612 addis tmp,anchor,high
1613 add dest,tmp,low
1615 where tmp itself acts as an anchor, and can be shared between
1616 accesses to the same 64k page. */
1617 #undef TARGET_MIN_ANCHOR_OFFSET
1618 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1619 #undef TARGET_MAX_ANCHOR_OFFSET
1620 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1621 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1622 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1624 #undef TARGET_BUILTIN_RECIPROCAL
1625 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1627 #undef TARGET_EXPAND_TO_RTL_HOOK
1628 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1630 #undef TARGET_INSTANTIATE_DECLS
1631 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1633 #undef TARGET_SECONDARY_RELOAD
1634 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1636 #undef TARGET_IRA_COVER_CLASSES
1637 #define TARGET_IRA_COVER_CLASSES rs6000_ira_cover_classes
1639 #undef TARGET_LEGITIMATE_ADDRESS_P
1640 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1642 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
1643 #define TARGET_MODE_DEPENDENT_ADDRESS_P rs6000_mode_dependent_address_p
1645 #undef TARGET_CAN_ELIMINATE
1646 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1648 #undef TARGET_CONDITIONAL_REGISTER_USAGE
1649 #define TARGET_CONDITIONAL_REGISTER_USAGE rs6000_conditional_register_usage
1651 #undef TARGET_TRAMPOLINE_INIT
1652 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1654 #undef TARGET_FUNCTION_VALUE
1655 #define TARGET_FUNCTION_VALUE rs6000_function_value
1657 #undef TARGET_OPTION_VALID_ATTRIBUTE_P
1658 #define TARGET_OPTION_VALID_ATTRIBUTE_P rs6000_valid_attribute_p
1660 #undef TARGET_OPTION_SAVE
1661 #define TARGET_OPTION_SAVE rs6000_function_specific_save
1663 #undef TARGET_OPTION_RESTORE
1664 #define TARGET_OPTION_RESTORE rs6000_function_specific_restore
1666 #undef TARGET_OPTION_PRINT
1667 #define TARGET_OPTION_PRINT rs6000_function_specific_print
1669 #undef TARGET_CAN_INLINE_P
1670 #define TARGET_CAN_INLINE_P rs6000_can_inline_p
1672 #undef TARGET_SET_CURRENT_FUNCTION
1673 #define TARGET_SET_CURRENT_FUNCTION rs6000_set_current_function
1675 struct gcc_target targetm = TARGET_INITIALIZER;
1678 /* Simplifications for entries below. */
1680 enum {
1681 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
1682 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
1685 /* Some OSs don't support saving the high part of 64-bit registers on context
1686 switch. Other OSs don't support saving Altivec registers. On those OSs, we
1687 don't touch the MASK_POWERPC64 or MASK_ALTIVEC settings; if the user wants
1688 either, the user must explicitly specify them and we won't interfere with
1689 the user's specification. */
1691 enum {
1692 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
1693 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
1694 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
1695 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
1696 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
1697 | MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE
1698 | MASK_RECIP_PRECISION)
1701 /* Masks for instructions set at various powerpc ISAs. */
1702 enum {
1703 ISA_2_1_MASKS = MASK_MFCRF,
1704 ISA_2_2_MASKS = (ISA_2_1_MASKS | MASK_POPCNTB),
1705 ISA_2_4_MASKS = (ISA_2_2_MASKS | MASK_FPRND),
1707 /* For ISA 2.05, do not add MFPGPR, since it isn't in ISA 2.06, and don't add
1708 ALTIVEC, since in general it isn't a win on power6. In ISA 2.04, fsel,
1709 fre, fsqrt, etc. were no longer documented as optional. Group masks by
1710 server and embedded. */
1711 ISA_2_5_MASKS_EMBEDDED = (ISA_2_2_MASKS | MASK_CMPB | MASK_RECIP_PRECISION
1712 | MASK_PPC_GFXOPT | MASK_PPC_GPOPT),
1713 ISA_2_5_MASKS_SERVER = (ISA_2_5_MASKS_EMBEDDED | MASK_DFP),
1715 /* For ISA 2.06, don't add ISEL, since in general it isn't a win, but
1716 altivec is a win so enable it. */
1717 ISA_2_6_MASKS_EMBEDDED = (ISA_2_5_MASKS_EMBEDDED | MASK_POPCNTD),
1718 ISA_2_6_MASKS_SERVER = (ISA_2_5_MASKS_SERVER | MASK_POPCNTD | MASK_ALTIVEC
1719 | MASK_VSX)
1722 /* This table occasionally claims that a processor does not support a
1723 particular feature even though it does, but the feature is slower than the
1724 alternative. Thus, it shouldn't be relied on as a complete description of
1725 the processor's support.
1727 Please keep this list in order, and don't forget to update the documentation
1728 in invoke.texi when adding a new processor or flag. */
1730 struct rs6000_ptt
1732 const char *const name; /* Canonical processor name. */
1733 const enum processor_type processor; /* Processor type enum value. */
1734 const int target_enable; /* Target flags to enable. */
1737 static struct rs6000_ptt const processor_target_table[] =
1739 {"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1740 {"403", PROCESSOR_PPC403,
1741 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
1742 {"405", PROCESSOR_PPC405,
1743 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1744 {"405fp", PROCESSOR_PPC405,
1745 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1746 {"440", PROCESSOR_PPC440,
1747 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1748 {"440fp", PROCESSOR_PPC440,
1749 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1750 {"464", PROCESSOR_PPC440,
1751 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1752 {"464fp", PROCESSOR_PPC440,
1753 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1754 {"476", PROCESSOR_PPC476,
1755 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_PPC_GFXOPT | MASK_MFCRF
1756 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
1757 {"476fp", PROCESSOR_PPC476,
1758 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB
1759 | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
1760 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
1761 {"601", PROCESSOR_PPC601,
1762 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
1763 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1764 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1765 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1766 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1767 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1768 {"620", PROCESSOR_PPC620,
1769 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1770 {"630", PROCESSOR_PPC630,
1771 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1772 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1773 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
1774 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
1775 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1776 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1777 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1778 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1779 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
1780 | MASK_ISEL},
1781 /* 8548 has a dummy entry for now. */
1782 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
1783 | MASK_ISEL},
1784 {"a2", PROCESSOR_PPCA2,
1785 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_POPCNTB
1786 | MASK_CMPB | MASK_NO_UPDATE },
1787 {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1788 {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK},
1789 {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT
1790 | MASK_ISEL},
1791 {"e500mc64", PROCESSOR_PPCE500MC64, POWERPC_BASE_MASK | MASK_POWERPC64
1792 | MASK_PPC_GFXOPT | MASK_ISEL},
1793 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1794 {"970", PROCESSOR_POWER4,
1795 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1796 {"cell", PROCESSOR_CELL,
1797 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1798 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
1799 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1800 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1801 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
1802 {"G5", PROCESSOR_POWER4,
1803 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1804 {"titan", PROCESSOR_TITAN,
1805 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1806 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1807 {"power2", PROCESSOR_POWER,
1808 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
1809 {"power3", PROCESSOR_PPC630,
1810 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1811 {"power4", PROCESSOR_POWER4,
1812 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1813 | MASK_MFCRF},
1814 {"power5", PROCESSOR_POWER5,
1815 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1816 | MASK_MFCRF | MASK_POPCNTB},
1817 {"power5+", PROCESSOR_POWER5,
1818 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1819 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
1820 {"power6", PROCESSOR_POWER6,
1821 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1822 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
1823 | MASK_RECIP_PRECISION},
1824 {"power6x", PROCESSOR_POWER6,
1825 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1826 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
1827 | MASK_MFPGPR | MASK_RECIP_PRECISION},
1828 {"power7", PROCESSOR_POWER7, /* Don't add MASK_ISEL by default */
1829 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
1830 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD
1831 | MASK_VSX | MASK_RECIP_PRECISION},
1832 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
1833 {"powerpc64", PROCESSOR_POWERPC64,
1834 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1835 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1836 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1837 {"rios2", PROCESSOR_RIOS2,
1838 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
1839 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1840 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1841 {"rs64", PROCESSOR_RS64A,
1842 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
1845 /* Look up a processor name for -mcpu=xxx and -mtune=xxx. Return -1 if the
1846 name is invalid. */
1848 static int
1849 rs6000_cpu_name_lookup (const char *name)
1851 size_t i;
1853 if (name != NULL)
1855 for (i = 0; i < ARRAY_SIZE (processor_target_table); i++)
1856 if (! strcmp (name, processor_target_table[i].name))
1857 return (int)i;
1860 return -1;
1864 /* Return number of consecutive hard regs needed starting at reg REGNO
1865 to hold something of mode MODE.
1866 This is ordinarily the length in words of a value of mode MODE
1867 but can be less for certain modes in special long registers.
1869 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1870 scalar instructions. The upper 32 bits are only available to the
1871 SIMD instructions.
1873 POWER and PowerPC GPRs hold 32 bits worth;
1874 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1876 static int
1877 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1879 unsigned HOST_WIDE_INT reg_size;
1881 if (FP_REGNO_P (regno))
1882 reg_size = (VECTOR_MEM_VSX_P (mode)
1883 ? UNITS_PER_VSX_WORD
1884 : UNITS_PER_FP_WORD);
1886 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1887 reg_size = UNITS_PER_SPE_WORD;
1889 else if (ALTIVEC_REGNO_P (regno))
1890 reg_size = UNITS_PER_ALTIVEC_WORD;
1892 /* The value returned for SCmode in the E500 double case is 2 for
1893 ABI compatibility; storing an SCmode value in a single register
1894 would require function_arg and rs6000_spe_function_arg to handle
1895 SCmode so as to pass the value correctly in a pair of
1896 registers. */
1897 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1898 && !DECIMAL_FLOAT_MODE_P (mode))
1899 reg_size = UNITS_PER_FP_WORD;
1901 else
1902 reg_size = UNITS_PER_WORD;
1904 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1907 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1908 MODE. */
1909 static int
1910 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1912 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1914 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1915 implementations. Don't allow an item to be split between a FP register
1916 and an Altivec register. */
1917 if (VECTOR_MEM_VSX_P (mode))
1919 if (FP_REGNO_P (regno))
1920 return FP_REGNO_P (last_regno);
1922 if (ALTIVEC_REGNO_P (regno))
1923 return ALTIVEC_REGNO_P (last_regno);
1926 /* The GPRs can hold any mode, but values bigger than one register
1927 cannot go past R31. */
1928 if (INT_REGNO_P (regno))
1929 return INT_REGNO_P (last_regno);
1931 /* The float registers (except for VSX vector modes) can only hold floating
1932 modes and DImode. This excludes the 32-bit decimal float mode for
1933 now. */
1934 if (FP_REGNO_P (regno))
1936 if (SCALAR_FLOAT_MODE_P (mode)
1937 && (mode != TDmode || (regno % 2) == 0)
1938 && FP_REGNO_P (last_regno))
1939 return 1;
1941 if (GET_MODE_CLASS (mode) == MODE_INT
1942 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1943 return 1;
1945 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1946 && PAIRED_VECTOR_MODE (mode))
1947 return 1;
1949 return 0;
1952 /* The CR register can only hold CC modes. */
1953 if (CR_REGNO_P (regno))
1954 return GET_MODE_CLASS (mode) == MODE_CC;
1956 if (CA_REGNO_P (regno))
1957 return mode == BImode;
1959 /* AltiVec only in AldyVec registers. */
1960 if (ALTIVEC_REGNO_P (regno))
1961 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1963 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1964 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1965 return 1;
1967 /* We cannot put TImode anywhere except general register and it must be able
1968 to fit within the register set. In the future, allow TImode in the
1969 Altivec or VSX registers. */
1971 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1974 /* Print interesting facts about registers. */
1975 static void
1976 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1978 int r, m;
1980 for (r = first_regno; r <= last_regno; ++r)
1982 const char *comma = "";
1983 int len;
1985 if (first_regno == last_regno)
1986 fprintf (stderr, "%s:\t", reg_name);
1987 else
1988 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1990 len = 8;
1991 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1992 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1994 if (len > 70)
1996 fprintf (stderr, ",\n\t");
1997 len = 8;
1998 comma = "";
2001 if (rs6000_hard_regno_nregs[m][r] > 1)
2002 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
2003 rs6000_hard_regno_nregs[m][r]);
2004 else
2005 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
2007 comma = ", ";
2010 if (call_used_regs[r])
2012 if (len > 70)
2014 fprintf (stderr, ",\n\t");
2015 len = 8;
2016 comma = "";
2019 len += fprintf (stderr, "%s%s", comma, "call-used");
2020 comma = ", ";
2023 if (fixed_regs[r])
2025 if (len > 70)
2027 fprintf (stderr, ",\n\t");
2028 len = 8;
2029 comma = "";
2032 len += fprintf (stderr, "%s%s", comma, "fixed");
2033 comma = ", ";
2036 if (len > 70)
2038 fprintf (stderr, ",\n\t");
2039 comma = "";
2042 fprintf (stderr, "%sregno = %d\n", comma, r);
2046 #define DEBUG_FMT_D "%-32s= %d\n"
2047 #define DEBUG_FMT_S "%-32s= %s\n"
2049 /* Print various interesting information with -mdebug=reg. */
2050 static void
2051 rs6000_debug_reg_global (void)
2053 static const char *const tf[2] = { "false", "true" };
2054 const char *nl = (const char *)0;
2055 int m;
2056 char costly_num[20];
2057 char nop_num[20];
2058 const char *costly_str;
2059 const char *nop_str;
2060 const char *trace_str;
2061 const char *abi_str;
2062 const char *cmodel_str;
2064 /* Map enum rs6000_vector to string. */
2065 static const char *rs6000_debug_vector_unit[] = {
2066 "none",
2067 "altivec",
2068 "vsx",
2069 "paired",
2070 "spe",
2071 "other"
2074 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
2075 LAST_VIRTUAL_REGISTER);
2076 rs6000_debug_reg_print (0, 31, "gr");
2077 rs6000_debug_reg_print (32, 63, "fp");
2078 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
2079 LAST_ALTIVEC_REGNO,
2080 "vs");
2081 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
2082 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
2083 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
2084 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
2085 rs6000_debug_reg_print (CA_REGNO, CA_REGNO, "ca");
2086 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
2087 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
2088 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
2089 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
2091 fprintf (stderr,
2092 "\n"
2093 "d reg_class = %s\n"
2094 "f reg_class = %s\n"
2095 "v reg_class = %s\n"
2096 "wa reg_class = %s\n"
2097 "wd reg_class = %s\n"
2098 "wf reg_class = %s\n"
2099 "ws reg_class = %s\n\n",
2100 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
2101 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
2102 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
2103 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
2104 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
2105 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
2106 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
2108 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2109 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
2111 nl = "\n";
2112 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
2113 GET_MODE_NAME (m),
2114 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
2115 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
2118 if (nl)
2119 fputs (nl, stderr);
2121 if (rs6000_recip_control)
2123 fprintf (stderr, "\nReciprocal mask = 0x%x\n", rs6000_recip_control);
2125 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2126 if (rs6000_recip_bits[m])
2128 fprintf (stderr,
2129 "Reciprocal estimate mode: %-5s divide: %s rsqrt: %s\n",
2130 GET_MODE_NAME (m),
2131 (RS6000_RECIP_AUTO_RE_P (m)
2132 ? "auto"
2133 : (RS6000_RECIP_HAVE_RE_P (m) ? "have" : "none")),
2134 (RS6000_RECIP_AUTO_RSQRTE_P (m)
2135 ? "auto"
2136 : (RS6000_RECIP_HAVE_RSQRTE_P (m) ? "have" : "none")));
2139 fputs ("\n", stderr);
2142 if (rs6000_cpu_index >= 0)
2143 fprintf (stderr, DEBUG_FMT_S, "cpu",
2144 processor_target_table[rs6000_cpu_index].name);
2146 if (rs6000_tune_index >= 0)
2147 fprintf (stderr, DEBUG_FMT_S, "tune",
2148 processor_target_table[rs6000_tune_index].name);
2150 switch (rs6000_sched_costly_dep)
2152 case max_dep_latency:
2153 costly_str = "max_dep_latency";
2154 break;
2156 case no_dep_costly:
2157 costly_str = "no_dep_costly";
2158 break;
2160 case all_deps_costly:
2161 costly_str = "all_deps_costly";
2162 break;
2164 case true_store_to_load_dep_costly:
2165 costly_str = "true_store_to_load_dep_costly";
2166 break;
2168 case store_to_load_dep_costly:
2169 costly_str = "store_to_load_dep_costly";
2170 break;
2172 default:
2173 costly_str = costly_num;
2174 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
2175 break;
2178 fprintf (stderr, DEBUG_FMT_S, "sched_costly_dep", costly_str);
2180 switch (rs6000_sched_insert_nops)
2182 case sched_finish_regroup_exact:
2183 nop_str = "sched_finish_regroup_exact";
2184 break;
2186 case sched_finish_pad_groups:
2187 nop_str = "sched_finish_pad_groups";
2188 break;
2190 case sched_finish_none:
2191 nop_str = "sched_finish_none";
2192 break;
2194 default:
2195 nop_str = nop_num;
2196 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
2197 break;
2200 fprintf (stderr, DEBUG_FMT_S, "sched_insert_nops", nop_str);
2202 switch (rs6000_sdata)
2204 default:
2205 case SDATA_NONE:
2206 break;
2208 case SDATA_DATA:
2209 fprintf (stderr, DEBUG_FMT_S, "sdata", "data");
2210 break;
2212 case SDATA_SYSV:
2213 fprintf (stderr, DEBUG_FMT_S, "sdata", "sysv");
2214 break;
2216 case SDATA_EABI:
2217 fprintf (stderr, DEBUG_FMT_S, "sdata", "eabi");
2218 break;
2222 switch (rs6000_traceback)
2224 case traceback_default: trace_str = "default"; break;
2225 case traceback_none: trace_str = "none"; break;
2226 case traceback_part: trace_str = "part"; break;
2227 case traceback_full: trace_str = "full"; break;
2228 default: trace_str = "unknown"; break;
2231 fprintf (stderr, DEBUG_FMT_S, "traceback", trace_str);
2233 switch (rs6000_current_cmodel)
2235 case CMODEL_SMALL: cmodel_str = "small"; break;
2236 case CMODEL_MEDIUM: cmodel_str = "medium"; break;
2237 case CMODEL_LARGE: cmodel_str = "large"; break;
2238 default: cmodel_str = "unknown"; break;
2241 fprintf (stderr, DEBUG_FMT_S, "cmodel", cmodel_str);
2243 switch (rs6000_current_abi)
2245 case ABI_NONE: abi_str = "none"; break;
2246 case ABI_AIX: abi_str = "aix"; break;
2247 case ABI_V4: abi_str = "V4"; break;
2248 case ABI_DARWIN: abi_str = "darwin"; break;
2249 default: abi_str = "unknown"; break;
2252 fprintf (stderr, DEBUG_FMT_S, "abi", abi_str);
2254 if (rs6000_altivec_abi)
2255 fprintf (stderr, DEBUG_FMT_S, "altivec_abi", "true");
2257 if (rs6000_spe_abi)
2258 fprintf (stderr, DEBUG_FMT_S, "spe_abi", "true");
2260 if (rs6000_darwin64_abi)
2261 fprintf (stderr, DEBUG_FMT_S, "darwin64_abi", "true");
2263 if (rs6000_float_gprs)
2264 fprintf (stderr, DEBUG_FMT_S, "float_gprs", "true");
2266 fprintf (stderr, DEBUG_FMT_S, "always_hint", tf[!!rs6000_always_hint]);
2267 fprintf (stderr, DEBUG_FMT_S, "align_branch",
2268 tf[!!rs6000_align_branch_targets]);
2269 fprintf (stderr, DEBUG_FMT_D, "tls_size", rs6000_tls_size);
2270 fprintf (stderr, DEBUG_FMT_D, "long_double_size",
2271 rs6000_long_double_type_size);
2272 fprintf (stderr, DEBUG_FMT_D, "sched_restricted_insns_priority",
2273 (int)rs6000_sched_restricted_insns_priority);
2276 /* Initialize the various global tables that are based on register size. */
2277 static void
2278 rs6000_init_hard_regno_mode_ok (bool global_init_p)
2280 int r, m, c;
2281 int align64;
2282 int align32;
2284 /* Precalculate REGNO_REG_CLASS. */
2285 rs6000_regno_regclass[0] = GENERAL_REGS;
2286 for (r = 1; r < 32; ++r)
2287 rs6000_regno_regclass[r] = BASE_REGS;
2289 for (r = 32; r < 64; ++r)
2290 rs6000_regno_regclass[r] = FLOAT_REGS;
2292 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
2293 rs6000_regno_regclass[r] = NO_REGS;
2295 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
2296 rs6000_regno_regclass[r] = ALTIVEC_REGS;
2298 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
2299 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
2300 rs6000_regno_regclass[r] = CR_REGS;
2302 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
2303 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
2304 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
2305 rs6000_regno_regclass[CA_REGNO] = CA_REGS;
2306 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
2307 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
2308 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
2309 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
2310 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
2311 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
2313 /* Precalculate vector information, this must be set up before the
2314 rs6000_hard_regno_nregs_internal below. */
2315 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2317 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
2318 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
2319 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
2322 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
2323 rs6000_constraints[c] = NO_REGS;
2325 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
2326 believes it can use native alignment or still uses 128-bit alignment. */
2327 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
2329 align64 = 64;
2330 align32 = 32;
2332 else
2334 align64 = 128;
2335 align32 = 128;
2338 /* V2DF mode, VSX only. */
2339 if (TARGET_VSX)
2341 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
2342 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
2343 rs6000_vector_align[V2DFmode] = align64;
2346 /* V4SF mode, either VSX or Altivec. */
2347 if (TARGET_VSX)
2349 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
2350 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
2351 rs6000_vector_align[V4SFmode] = align32;
2353 else if (TARGET_ALTIVEC)
2355 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
2356 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
2357 rs6000_vector_align[V4SFmode] = align32;
2360 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
2361 and stores. */
2362 if (TARGET_ALTIVEC)
2364 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
2365 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
2366 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
2367 rs6000_vector_align[V4SImode] = align32;
2368 rs6000_vector_align[V8HImode] = align32;
2369 rs6000_vector_align[V16QImode] = align32;
2371 if (TARGET_VSX)
2373 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
2374 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
2375 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
2377 else
2379 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
2380 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
2381 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
2385 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
2386 Altivec doesn't have 64-bit support. */
2387 if (TARGET_VSX)
2389 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
2390 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
2391 rs6000_vector_align[V2DImode] = align64;
2394 /* DFmode, see if we want to use the VSX unit. */
2395 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
2397 rs6000_vector_unit[DFmode] = VECTOR_VSX;
2398 rs6000_vector_mem[DFmode]
2399 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
2400 rs6000_vector_align[DFmode] = align64;
2403 /* TODO add SPE and paired floating point vector support. */
2405 /* Register class constaints for the constraints that depend on compile
2406 switches. */
2407 if (TARGET_HARD_FLOAT && TARGET_FPRS)
2408 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
2410 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
2411 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
2413 if (TARGET_VSX)
2415 /* At present, we just use VSX_REGS, but we have different constraints
2416 based on the use, in case we want to fine tune the default register
2417 class used. wa = any VSX register, wf = register class to use for
2418 V4SF, wd = register class to use for V2DF, and ws = register classs to
2419 use for DF scalars. */
2420 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
2421 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
2422 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
2423 rs6000_constraints[RS6000_CONSTRAINT_ws] = (TARGET_VSX_SCALAR_MEMORY
2424 ? VSX_REGS
2425 : FLOAT_REGS);
2428 if (TARGET_ALTIVEC)
2429 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
2431 /* Set up the reload helper functions. */
2432 if (TARGET_VSX || TARGET_ALTIVEC)
2434 if (TARGET_64BIT)
2436 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
2437 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
2438 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
2439 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
2440 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
2441 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
2442 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
2443 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
2444 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
2445 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
2446 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
2447 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
2449 else
2451 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
2452 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
2453 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
2454 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
2455 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
2456 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
2457 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
2458 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
2459 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
2460 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
2461 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
2462 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
2466 /* Precalculate HARD_REGNO_NREGS. */
2467 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2468 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2469 rs6000_hard_regno_nregs[m][r]
2470 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
2472 /* Precalculate HARD_REGNO_MODE_OK. */
2473 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2474 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2475 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
2476 rs6000_hard_regno_mode_ok_p[m][r] = true;
2478 /* Precalculate CLASS_MAX_NREGS sizes. */
2479 for (c = 0; c < LIM_REG_CLASSES; ++c)
2481 int reg_size;
2483 if (TARGET_VSX && VSX_REG_CLASS_P (c))
2484 reg_size = UNITS_PER_VSX_WORD;
2486 else if (c == ALTIVEC_REGS)
2487 reg_size = UNITS_PER_ALTIVEC_WORD;
2489 else if (c == FLOAT_REGS)
2490 reg_size = UNITS_PER_FP_WORD;
2492 else
2493 reg_size = UNITS_PER_WORD;
2495 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2496 rs6000_class_max_nregs[m][c]
2497 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
2500 if (TARGET_E500_DOUBLE)
2501 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
2503 /* Calculate which modes to automatically generate code to use a the
2504 reciprocal divide and square root instructions. In the future, possibly
2505 automatically generate the instructions even if the user did not specify
2506 -mrecip. The older machines double precision reciprocal sqrt estimate is
2507 not accurate enough. */
2508 memset (rs6000_recip_bits, 0, sizeof (rs6000_recip_bits));
2509 if (TARGET_FRES)
2510 rs6000_recip_bits[SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2511 if (TARGET_FRE)
2512 rs6000_recip_bits[DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2513 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2514 rs6000_recip_bits[V4SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2515 if (VECTOR_UNIT_VSX_P (V2DFmode))
2516 rs6000_recip_bits[V2DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2518 if (TARGET_FRSQRTES)
2519 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2520 if (TARGET_FRSQRTE)
2521 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2522 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2523 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2524 if (VECTOR_UNIT_VSX_P (V2DFmode))
2525 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2527 if (rs6000_recip_control)
2529 if (!flag_finite_math_only)
2530 warning (0, "-mrecip requires -ffinite-math or -ffast-math");
2531 if (flag_trapping_math)
2532 warning (0, "-mrecip requires -fno-trapping-math or -ffast-math");
2533 if (!flag_reciprocal_math)
2534 warning (0, "-mrecip requires -freciprocal-math or -ffast-math");
2535 if (flag_finite_math_only && !flag_trapping_math && flag_reciprocal_math)
2537 if (RS6000_RECIP_HAVE_RE_P (SFmode)
2538 && (rs6000_recip_control & RECIP_SF_DIV) != 0)
2539 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2541 if (RS6000_RECIP_HAVE_RE_P (DFmode)
2542 && (rs6000_recip_control & RECIP_DF_DIV) != 0)
2543 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2545 if (RS6000_RECIP_HAVE_RE_P (V4SFmode)
2546 && (rs6000_recip_control & RECIP_V4SF_DIV) != 0)
2547 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2549 if (RS6000_RECIP_HAVE_RE_P (V2DFmode)
2550 && (rs6000_recip_control & RECIP_V2DF_DIV) != 0)
2551 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2553 if (RS6000_RECIP_HAVE_RSQRTE_P (SFmode)
2554 && (rs6000_recip_control & RECIP_SF_RSQRT) != 0)
2555 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2557 if (RS6000_RECIP_HAVE_RSQRTE_P (DFmode)
2558 && (rs6000_recip_control & RECIP_DF_RSQRT) != 0)
2559 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2561 if (RS6000_RECIP_HAVE_RSQRTE_P (V4SFmode)
2562 && (rs6000_recip_control & RECIP_V4SF_RSQRT) != 0)
2563 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2565 if (RS6000_RECIP_HAVE_RSQRTE_P (V2DFmode)
2566 && (rs6000_recip_control & RECIP_V2DF_RSQRT) != 0)
2567 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2571 if (global_init_p || TARGET_DEBUG_TARGET)
2573 if (TARGET_DEBUG_REG)
2574 rs6000_debug_reg_global ();
2576 if (TARGET_DEBUG_COST || TARGET_DEBUG_REG)
2577 fprintf (stderr,
2578 "SImode variable mult cost = %d\n"
2579 "SImode constant mult cost = %d\n"
2580 "SImode short constant mult cost = %d\n"
2581 "DImode multipliciation cost = %d\n"
2582 "SImode division cost = %d\n"
2583 "DImode division cost = %d\n"
2584 "Simple fp operation cost = %d\n"
2585 "DFmode multiplication cost = %d\n"
2586 "SFmode division cost = %d\n"
2587 "DFmode division cost = %d\n"
2588 "cache line size = %d\n"
2589 "l1 cache size = %d\n"
2590 "l2 cache size = %d\n"
2591 "simultaneous prefetches = %d\n"
2592 "\n",
2593 rs6000_cost->mulsi,
2594 rs6000_cost->mulsi_const,
2595 rs6000_cost->mulsi_const9,
2596 rs6000_cost->muldi,
2597 rs6000_cost->divsi,
2598 rs6000_cost->divdi,
2599 rs6000_cost->fp,
2600 rs6000_cost->dmul,
2601 rs6000_cost->sdiv,
2602 rs6000_cost->ddiv,
2603 rs6000_cost->cache_line_size,
2604 rs6000_cost->l1_cache_size,
2605 rs6000_cost->l2_cache_size,
2606 rs6000_cost->simultaneous_prefetches);
2610 #if TARGET_MACHO
2611 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2613 static void
2614 darwin_rs6000_override_options (void)
2616 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2617 off. */
2618 rs6000_altivec_abi = 1;
2619 TARGET_ALTIVEC_VRSAVE = 1;
2621 if (DEFAULT_ABI == ABI_DARWIN
2622 && TARGET_64BIT)
2623 darwin_one_byte_bool = 1;
2625 if (TARGET_64BIT && ! TARGET_POWERPC64)
2627 target_flags |= MASK_POWERPC64;
2628 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2630 if (flag_mkernel)
2632 rs6000_default_long_calls = 1;
2633 target_flags |= MASK_SOFT_FLOAT;
2636 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2637 Altivec. */
2638 if (!flag_mkernel && !flag_apple_kext
2639 && TARGET_64BIT
2640 && ! (target_flags_explicit & MASK_ALTIVEC))
2641 target_flags |= MASK_ALTIVEC;
2643 /* Unless the user (not the configurer) has explicitly overridden
2644 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2645 G4 unless targetting the kernel. */
2646 if (!flag_mkernel
2647 && !flag_apple_kext
2648 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2649 && ! (target_flags_explicit & MASK_ALTIVEC)
2650 && ! rs6000_select[1].string)
2652 target_flags |= MASK_ALTIVEC;
2655 #endif
2657 /* If not otherwise specified by a target, make 'long double' equivalent to
2658 'double'. */
2660 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2661 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2662 #endif
2664 /* Override command line options. Mostly we process the processor type and
2665 sometimes adjust other TARGET_ options. */
2667 static bool
2668 rs6000_option_override_internal (bool global_init_p)
2670 bool ret = true;
2671 const char *default_cpu = OPTION_TARGET_CPU_DEFAULT;
2672 int set_masks;
2673 int cpu_index;
2674 int tune_index;
2675 struct cl_target_option *main_target_opt
2676 = ((global_init_p || target_option_default_node == NULL)
2677 ? NULL : TREE_TARGET_OPTION (target_option_default_node));
2679 /* Numerous experiment shows that IRA based loop pressure
2680 calculation works better for RTL loop invariant motion on targets
2681 with enough (>= 32) registers. It is an expensive optimization.
2682 So it is on only for peak performance. */
2683 if (optimize >= 3 && global_init_p)
2684 flag_ira_loop_pressure = 1;
2686 /* Set the pointer size. */
2687 if (TARGET_64BIT)
2689 rs6000_pmode = (int)DImode;
2690 rs6000_pointer_size = 64;
2692 else
2694 rs6000_pmode = (int)SImode;
2695 rs6000_pointer_size = 32;
2698 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2699 #ifdef OS_MISSING_POWERPC64
2700 if (OS_MISSING_POWERPC64)
2701 set_masks &= ~MASK_POWERPC64;
2702 #endif
2703 #ifdef OS_MISSING_ALTIVEC
2704 if (OS_MISSING_ALTIVEC)
2705 set_masks &= ~MASK_ALTIVEC;
2706 #endif
2708 /* Don't override by the processor default if given explicitly. */
2709 set_masks &= ~target_flags_explicit;
2711 /* Identify the processor type. */
2712 if (!default_cpu)
2714 if (TARGET_POWERPC64)
2715 default_cpu = "powerpc64";
2716 else if (TARGET_POWERPC)
2717 default_cpu = "powerpc";
2720 /* Process the -mcpu=<xxx> and -mtune=<xxx> argument. If the user changed
2721 the cpu in a target attribute or pragma, but did not specify a tuning
2722 option, use the cpu for the tuning option rather than the option specified
2723 with -mtune on the command line. */
2724 if (rs6000_cpu_index > 0)
2725 cpu_index = rs6000_cpu_index;
2726 else if (main_target_opt != NULL && main_target_opt->x_rs6000_cpu_index > 0)
2727 rs6000_cpu_index = cpu_index = main_target_opt->x_rs6000_cpu_index;
2728 else
2729 rs6000_cpu_index = cpu_index = rs6000_cpu_name_lookup (default_cpu);
2731 if (rs6000_tune_index > 0)
2732 tune_index = rs6000_tune_index;
2733 else
2734 rs6000_tune_index = tune_index = cpu_index;
2736 if (cpu_index >= 0)
2738 target_flags &= ~set_masks;
2739 target_flags |= (processor_target_table[cpu_index].target_enable
2740 & set_masks);
2743 rs6000_cpu = ((tune_index >= 0)
2744 ? processor_target_table[tune_index].processor
2745 : (TARGET_POWERPC64
2746 ? PROCESSOR_DEFAULT64
2747 : PROCESSOR_DEFAULT));
2749 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2750 || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64)
2752 if (TARGET_ALTIVEC)
2753 error ("AltiVec not supported in this target");
2754 if (TARGET_SPE)
2755 error ("SPE not supported in this target");
2758 /* Disable Cell microcode if we are optimizing for the Cell
2759 and not optimizing for size. */
2760 if (rs6000_gen_cell_microcode == -1)
2761 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2762 && !optimize_size);
2764 /* If we are optimizing big endian systems for space and it's OK to
2765 use instructions that would be microcoded on the Cell, use the
2766 load/store multiple and string instructions. */
2767 if (BYTES_BIG_ENDIAN && optimize_size && rs6000_gen_cell_microcode)
2768 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2770 /* Don't allow -mmultiple or -mstring on little endian systems
2771 unless the cpu is a 750, because the hardware doesn't support the
2772 instructions used in little endian mode, and causes an alignment
2773 trap. The 750 does not cause an alignment trap (except when the
2774 target is unaligned). */
2776 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2778 if (TARGET_MULTIPLE)
2780 target_flags &= ~MASK_MULTIPLE;
2781 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2782 warning (0, "-mmultiple is not supported on little endian systems");
2785 if (TARGET_STRING)
2787 target_flags &= ~MASK_STRING;
2788 if ((target_flags_explicit & MASK_STRING) != 0)
2789 warning (0, "-mstring is not supported on little endian systems");
2793 /* Add some warnings for VSX. */
2794 if (TARGET_VSX)
2796 const char *msg = NULL;
2797 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2798 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2800 if (target_flags_explicit & MASK_VSX)
2801 msg = N_("-mvsx requires hardware floating point");
2802 else
2803 target_flags &= ~ MASK_VSX;
2805 else if (TARGET_PAIRED_FLOAT)
2806 msg = N_("-mvsx and -mpaired are incompatible");
2807 /* The hardware will allow VSX and little endian, but until we make sure
2808 things like vector select, etc. work don't allow VSX on little endian
2809 systems at this point. */
2810 else if (!BYTES_BIG_ENDIAN)
2811 msg = N_("-mvsx used with little endian code");
2812 else if (TARGET_AVOID_XFORM > 0)
2813 msg = N_("-mvsx needs indexed addressing");
2814 else if (!TARGET_ALTIVEC && (target_flags_explicit & MASK_ALTIVEC))
2816 if (target_flags_explicit & MASK_VSX)
2817 msg = N_("-mvsx and -mno-altivec are incompatible");
2818 else
2819 msg = N_("-mno-altivec disables vsx");
2822 if (msg)
2824 warning (0, msg);
2825 target_flags &= ~ MASK_VSX;
2826 target_flags_explicit |= MASK_VSX;
2830 /* For the newer switches (vsx, dfp, etc.) set some of the older options,
2831 unless the user explicitly used the -mno-<option> to disable the code. */
2832 if (TARGET_VSX)
2833 target_flags |= (ISA_2_6_MASKS_SERVER & ~target_flags_explicit);
2834 else if (TARGET_POPCNTD)
2835 target_flags |= (ISA_2_6_MASKS_EMBEDDED & ~target_flags_explicit);
2836 else if (TARGET_DFP)
2837 target_flags |= (ISA_2_5_MASKS_SERVER & ~target_flags_explicit);
2838 else if (TARGET_CMPB)
2839 target_flags |= (ISA_2_5_MASKS_EMBEDDED & ~target_flags_explicit);
2840 else if (TARGET_FPRND)
2841 target_flags |= (ISA_2_4_MASKS & ~target_flags_explicit);
2842 else if (TARGET_POPCNTB)
2843 target_flags |= (ISA_2_2_MASKS & ~target_flags_explicit);
2844 else if (TARGET_ALTIVEC)
2845 target_flags |= (MASK_PPC_GFXOPT & ~target_flags_explicit);
2847 /* E500mc does "better" if we inline more aggressively. Respect the
2848 user's opinion, though. */
2849 if (rs6000_block_move_inline_limit == 0
2850 && (rs6000_cpu == PROCESSOR_PPCE500MC
2851 || rs6000_cpu == PROCESSOR_PPCE500MC64))
2852 rs6000_block_move_inline_limit = 128;
2854 /* store_one_arg depends on expand_block_move to handle at least the
2855 size of reg_parm_stack_space. */
2856 if (rs6000_block_move_inline_limit < (TARGET_POWERPC64 ? 64 : 32))
2857 rs6000_block_move_inline_limit = (TARGET_POWERPC64 ? 64 : 32);
2859 if (global_init_p)
2861 /* If the appropriate debug option is enabled, replace the target hooks
2862 with debug versions that call the real version and then prints
2863 debugging information. */
2864 if (TARGET_DEBUG_COST)
2866 targetm.rtx_costs = rs6000_debug_rtx_costs;
2867 targetm.address_cost = rs6000_debug_address_cost;
2868 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2871 if (TARGET_DEBUG_ADDR)
2873 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2874 targetm.legitimize_address = rs6000_debug_legitimize_address;
2875 rs6000_secondary_reload_class_ptr
2876 = rs6000_debug_secondary_reload_class;
2877 rs6000_secondary_memory_needed_ptr
2878 = rs6000_debug_secondary_memory_needed;
2879 rs6000_cannot_change_mode_class_ptr
2880 = rs6000_debug_cannot_change_mode_class;
2881 rs6000_preferred_reload_class_ptr
2882 = rs6000_debug_preferred_reload_class;
2883 rs6000_legitimize_reload_address_ptr
2884 = rs6000_debug_legitimize_reload_address;
2885 rs6000_mode_dependent_address_ptr
2886 = rs6000_debug_mode_dependent_address;
2889 if (rs6000_veclibabi_name)
2891 if (strcmp (rs6000_veclibabi_name, "mass") == 0)
2892 rs6000_veclib_handler = rs6000_builtin_vectorized_libmass;
2893 else
2895 error ("unknown vectorization library ABI type (%s) for "
2896 "-mveclibabi= switch", rs6000_veclibabi_name);
2897 ret = false;
2902 if (!rs6000_explicit_options.long_double)
2904 if (main_target_opt != NULL
2905 && (main_target_opt->x_rs6000_long_double_type_size
2906 != RS6000_DEFAULT_LONG_DOUBLE_SIZE))
2907 error ("target attribute or pragma changes long double size");
2908 else
2909 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2912 #ifndef POWERPC_LINUX
2913 if (!rs6000_explicit_options.ieee)
2914 rs6000_ieeequad = 1;
2915 #endif
2917 /* Disable VSX and Altivec silently if the user switched cpus to power7 in a
2918 target attribute or pragma which automatically enables both options,
2919 unless the altivec ABI was set. This is set by default for 64-bit, but
2920 not for 32-bit. */
2921 if (main_target_opt != NULL && !main_target_opt->x_rs6000_altivec_abi)
2922 target_flags &= ~((MASK_VSX | MASK_ALTIVEC) & ~target_flags_explicit);
2924 /* Enable Altivec ABI for AIX -maltivec. */
2925 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2927 if (main_target_opt != NULL && !main_target_opt->x_rs6000_altivec_abi)
2928 error ("target attribute or pragma changes AltiVec ABI");
2929 else
2930 rs6000_altivec_abi = 1;
2933 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2934 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2935 be explicitly overridden in either case. */
2936 if (TARGET_ELF)
2938 if (!rs6000_explicit_options.altivec_abi
2939 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2941 if (main_target_opt != NULL &&
2942 !main_target_opt->x_rs6000_altivec_abi)
2943 error ("target attribute or pragma changes AltiVec ABI");
2944 else
2945 rs6000_altivec_abi = 1;
2948 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2949 if (!rs6000_explicit_options.vrsave)
2950 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2953 /* Set the Darwin64 ABI as default for 64-bit Darwin.
2954 So far, the only darwin64 targets are also MACH-O. */
2955 if (TARGET_MACHO
2956 && DEFAULT_ABI == ABI_DARWIN
2957 && TARGET_64BIT)
2959 if (main_target_opt != NULL && !main_target_opt->x_rs6000_darwin64_abi)
2960 error ("target attribute or pragma changes darwin64 ABI");
2961 else
2963 rs6000_darwin64_abi = 1;
2964 /* Default to natural alignment, for better performance. */
2965 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2969 /* Place FP constants in the constant pool instead of TOC
2970 if section anchors enabled. */
2971 if (flag_section_anchors)
2972 TARGET_NO_FP_IN_TOC = 1;
2974 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2975 SUBTARGET_OVERRIDE_OPTIONS;
2976 #endif
2977 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2978 SUBSUBTARGET_OVERRIDE_OPTIONS;
2979 #endif
2980 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2981 SUB3TARGET_OVERRIDE_OPTIONS;
2982 #endif
2984 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC
2985 || rs6000_cpu == PROCESSOR_PPCE500MC64)
2987 /* The e500 and e500mc do not have string instructions, and we set
2988 MASK_STRING above when optimizing for size. */
2989 if ((target_flags & MASK_STRING) != 0)
2990 target_flags = target_flags & ~MASK_STRING;
2992 else if (rs6000_select[1].string != NULL)
2994 /* For the powerpc-eabispe configuration, we set all these by
2995 default, so let's unset them if we manually set another
2996 CPU that is not the E500. */
2997 if (main_target_opt != NULL
2998 && ((main_target_opt->x_rs6000_spe_abi != rs6000_spe_abi)
2999 || (main_target_opt->x_rs6000_spe != rs6000_spe)
3000 || (main_target_opt->x_rs6000_float_gprs != rs6000_float_gprs)))
3001 error ("target attribute or pragma changes SPE ABI");
3002 else
3004 if (!rs6000_explicit_options.spe_abi)
3005 rs6000_spe_abi = 0;
3006 if (!rs6000_explicit_options.spe)
3007 rs6000_spe = 0;
3008 if (!rs6000_explicit_options.float_gprs)
3009 rs6000_float_gprs = 0;
3011 if (!(target_flags_explicit & MASK_ISEL))
3012 target_flags &= ~MASK_ISEL;
3015 /* Detect invalid option combinations with E500. */
3016 CHECK_E500_OPTIONS;
3018 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
3019 && rs6000_cpu != PROCESSOR_POWER5
3020 && rs6000_cpu != PROCESSOR_POWER6
3021 && rs6000_cpu != PROCESSOR_POWER7
3022 && rs6000_cpu != PROCESSOR_PPCA2
3023 && rs6000_cpu != PROCESSOR_CELL);
3024 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
3025 || rs6000_cpu == PROCESSOR_POWER5
3026 || rs6000_cpu == PROCESSOR_POWER7);
3027 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
3028 || rs6000_cpu == PROCESSOR_POWER5
3029 || rs6000_cpu == PROCESSOR_POWER6
3030 || rs6000_cpu == PROCESSOR_POWER7
3031 || rs6000_cpu == PROCESSOR_PPCE500MC
3032 || rs6000_cpu == PROCESSOR_PPCE500MC64);
3034 /* Allow debug switches to override the above settings. These are set to -1
3035 in rs6000.opt to indicate the user hasn't directly set the switch. */
3036 if (TARGET_ALWAYS_HINT >= 0)
3037 rs6000_always_hint = TARGET_ALWAYS_HINT;
3039 if (TARGET_SCHED_GROUPS >= 0)
3040 rs6000_sched_groups = TARGET_SCHED_GROUPS;
3042 if (TARGET_ALIGN_BRANCH_TARGETS >= 0)
3043 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
3045 rs6000_sched_restricted_insns_priority
3046 = (rs6000_sched_groups ? 1 : 0);
3048 /* Handle -msched-costly-dep option. */
3049 rs6000_sched_costly_dep
3050 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
3052 if (rs6000_sched_costly_dep_str)
3054 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
3055 rs6000_sched_costly_dep = no_dep_costly;
3056 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
3057 rs6000_sched_costly_dep = all_deps_costly;
3058 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
3059 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
3060 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
3061 rs6000_sched_costly_dep = store_to_load_dep_costly;
3062 else
3063 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
3064 atoi (rs6000_sched_costly_dep_str));
3067 /* Handle -minsert-sched-nops option. */
3068 rs6000_sched_insert_nops
3069 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
3071 if (rs6000_sched_insert_nops_str)
3073 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
3074 rs6000_sched_insert_nops = sched_finish_none;
3075 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
3076 rs6000_sched_insert_nops = sched_finish_pad_groups;
3077 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
3078 rs6000_sched_insert_nops = sched_finish_regroup_exact;
3079 else
3080 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
3081 atoi (rs6000_sched_insert_nops_str));
3084 if (global_init_p)
3086 #ifdef TARGET_REGNAMES
3087 /* If the user desires alternate register names, copy in the
3088 alternate names now. */
3089 if (TARGET_REGNAMES)
3090 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
3091 #endif
3093 /* Set aix_struct_return last, after the ABI is determined.
3094 If -maix-struct-return or -msvr4-struct-return was explicitly
3095 used, don't override with the ABI default. */
3096 if (!rs6000_explicit_options.aix_struct_ret)
3097 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
3099 #if 0
3100 /* IBM XL compiler defaults to unsigned bitfields. */
3101 if (TARGET_XL_COMPAT)
3102 flag_signed_bitfields = 0;
3103 #endif
3105 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
3106 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
3108 if (TARGET_TOC)
3109 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
3111 /* We can only guarantee the availability of DI pseudo-ops when
3112 assembling for 64-bit targets. */
3113 if (!TARGET_64BIT)
3115 targetm.asm_out.aligned_op.di = NULL;
3116 targetm.asm_out.unaligned_op.di = NULL;
3120 /* Set branch target alignment, if not optimizing for size. */
3121 if (!optimize_size)
3123 /* Cell wants to be aligned 8byte for dual issue. Titan wants to be
3124 aligned 8byte to avoid misprediction by the branch predictor. */
3125 if (rs6000_cpu == PROCESSOR_TITAN
3126 || rs6000_cpu == PROCESSOR_CELL)
3128 if (align_functions <= 0)
3129 align_functions = 8;
3130 if (align_jumps <= 0)
3131 align_jumps = 8;
3132 if (align_loops <= 0)
3133 align_loops = 8;
3135 if (rs6000_align_branch_targets)
3137 if (align_functions <= 0)
3138 align_functions = 16;
3139 if (align_jumps <= 0)
3140 align_jumps = 16;
3141 if (align_loops <= 0)
3143 can_override_loop_align = 1;
3144 align_loops = 16;
3147 if (align_jumps_max_skip <= 0)
3148 align_jumps_max_skip = 15;
3149 if (align_loops_max_skip <= 0)
3150 align_loops_max_skip = 15;
3153 /* Arrange to save and restore machine status around nested functions. */
3154 init_machine_status = rs6000_init_machine_status;
3156 /* We should always be splitting complex arguments, but we can't break
3157 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
3158 if (DEFAULT_ABI != ABI_AIX)
3159 targetm.calls.split_complex_arg = NULL;
3162 /* Initialize rs6000_cost with the appropriate target costs. */
3163 if (optimize_size)
3164 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
3165 else
3166 switch (rs6000_cpu)
3168 case PROCESSOR_RIOS1:
3169 rs6000_cost = &rios1_cost;
3170 break;
3172 case PROCESSOR_RIOS2:
3173 rs6000_cost = &rios2_cost;
3174 break;
3176 case PROCESSOR_RS64A:
3177 rs6000_cost = &rs64a_cost;
3178 break;
3180 case PROCESSOR_MPCCORE:
3181 rs6000_cost = &mpccore_cost;
3182 break;
3184 case PROCESSOR_PPC403:
3185 rs6000_cost = &ppc403_cost;
3186 break;
3188 case PROCESSOR_PPC405:
3189 rs6000_cost = &ppc405_cost;
3190 break;
3192 case PROCESSOR_PPC440:
3193 rs6000_cost = &ppc440_cost;
3194 break;
3196 case PROCESSOR_PPC476:
3197 rs6000_cost = &ppc476_cost;
3198 break;
3200 case PROCESSOR_PPC601:
3201 rs6000_cost = &ppc601_cost;
3202 break;
3204 case PROCESSOR_PPC603:
3205 rs6000_cost = &ppc603_cost;
3206 break;
3208 case PROCESSOR_PPC604:
3209 rs6000_cost = &ppc604_cost;
3210 break;
3212 case PROCESSOR_PPC604e:
3213 rs6000_cost = &ppc604e_cost;
3214 break;
3216 case PROCESSOR_PPC620:
3217 rs6000_cost = &ppc620_cost;
3218 break;
3220 case PROCESSOR_PPC630:
3221 rs6000_cost = &ppc630_cost;
3222 break;
3224 case PROCESSOR_CELL:
3225 rs6000_cost = &ppccell_cost;
3226 break;
3228 case PROCESSOR_PPC750:
3229 case PROCESSOR_PPC7400:
3230 rs6000_cost = &ppc750_cost;
3231 break;
3233 case PROCESSOR_PPC7450:
3234 rs6000_cost = &ppc7450_cost;
3235 break;
3237 case PROCESSOR_PPC8540:
3238 rs6000_cost = &ppc8540_cost;
3239 break;
3241 case PROCESSOR_PPCE300C2:
3242 case PROCESSOR_PPCE300C3:
3243 rs6000_cost = &ppce300c2c3_cost;
3244 break;
3246 case PROCESSOR_PPCE500MC:
3247 rs6000_cost = &ppce500mc_cost;
3248 break;
3250 case PROCESSOR_PPCE500MC64:
3251 rs6000_cost = &ppce500mc64_cost;
3252 break;
3254 case PROCESSOR_TITAN:
3255 rs6000_cost = &titan_cost;
3256 break;
3258 case PROCESSOR_POWER4:
3259 case PROCESSOR_POWER5:
3260 rs6000_cost = &power4_cost;
3261 break;
3263 case PROCESSOR_POWER6:
3264 rs6000_cost = &power6_cost;
3265 break;
3267 case PROCESSOR_POWER7:
3268 rs6000_cost = &power7_cost;
3269 break;
3271 case PROCESSOR_PPCA2:
3272 rs6000_cost = &ppca2_cost;
3273 break;
3275 default:
3276 gcc_unreachable ();
3279 if (global_init_p)
3281 maybe_set_param_value (PARAM_SIMULTANEOUS_PREFETCHES,
3282 rs6000_cost->simultaneous_prefetches,
3283 global_options.x_param_values,
3284 global_options_set.x_param_values);
3285 maybe_set_param_value (PARAM_L1_CACHE_SIZE, rs6000_cost->l1_cache_size,
3286 global_options.x_param_values,
3287 global_options_set.x_param_values);
3288 maybe_set_param_value (PARAM_L1_CACHE_LINE_SIZE,
3289 rs6000_cost->cache_line_size,
3290 global_options.x_param_values,
3291 global_options_set.x_param_values);
3292 maybe_set_param_value (PARAM_L2_CACHE_SIZE, rs6000_cost->l2_cache_size,
3293 global_options.x_param_values,
3294 global_options_set.x_param_values);
3296 /* If using typedef char *va_list, signal that
3297 __builtin_va_start (&ap, 0) can be optimized to
3298 ap = __builtin_next_arg (0). */
3299 if (DEFAULT_ABI != ABI_V4)
3300 targetm.expand_builtin_va_start = NULL;
3303 /* Set up single/double float flags.
3304 If TARGET_HARD_FLOAT is set, but neither single or double is set,
3305 then set both flags. */
3306 if (TARGET_HARD_FLOAT && TARGET_FPRS
3307 && rs6000_single_float == 0 && rs6000_double_float == 0)
3308 rs6000_single_float = rs6000_double_float = 1;
3310 /* Reset single and double FP flags if target is E500. */
3311 if (TARGET_E500)
3313 rs6000_single_float = rs6000_double_float = 0;
3314 if (TARGET_E500_SINGLE)
3315 rs6000_single_float = 1;
3316 if (TARGET_E500_DOUBLE)
3317 rs6000_single_float = rs6000_double_float = 1;
3320 if (main_target_opt)
3322 if (main_target_opt->x_rs6000_single_float != rs6000_single_float)
3323 error ("target attribute or pragma changes single precision floating "
3324 "point");
3325 if (main_target_opt->x_rs6000_double_float != rs6000_double_float)
3326 error ("target attribute or pragma changes double precision floating "
3327 "point");
3330 /* If not explicitly specified via option, decide whether to generate indexed
3331 load/store instructions. */
3332 if (TARGET_AVOID_XFORM == -1)
3333 /* Avoid indexed addressing when targeting Power6 in order to avoid the
3334 DERAT mispredict penalty. However the LVE and STVE altivec instructions
3335 need indexed accesses and the type used is the scalar type of the element
3336 being loaded or stored. */
3337 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB
3338 && !TARGET_ALTIVEC);
3340 /* Set the -mrecip options. */
3341 if (rs6000_recip_name)
3343 char *p = ASTRDUP (rs6000_recip_name);
3344 char *q;
3345 unsigned int mask, i;
3346 bool invert;
3348 while ((q = strtok (p, ",")) != NULL)
3350 p = NULL;
3351 if (*q == '!')
3353 invert = true;
3354 q++;
3356 else
3357 invert = false;
3359 if (!strcmp (q, "default"))
3360 mask = ((TARGET_RECIP_PRECISION)
3361 ? RECIP_HIGH_PRECISION : RECIP_LOW_PRECISION);
3362 else
3364 for (i = 0; i < ARRAY_SIZE (recip_options); i++)
3365 if (!strcmp (q, recip_options[i].string))
3367 mask = recip_options[i].mask;
3368 break;
3371 if (i == ARRAY_SIZE (recip_options))
3373 error ("unknown option for -mrecip=%s", q);
3374 invert = false;
3375 mask = 0;
3376 ret = false;
3380 if (invert)
3381 rs6000_recip_control &= ~mask;
3382 else
3383 rs6000_recip_control |= mask;
3387 rs6000_init_hard_regno_mode_ok (global_init_p);
3389 /* Save the initial options in case the user does function specific options */
3390 if (global_init_p)
3391 target_option_default_node = target_option_current_node
3392 = build_target_option_node ();
3394 return ret;
3397 /* Implement TARGET_OPTION_OVERRIDE. On the RS/6000 this is used to
3398 define the target cpu type. */
3400 static void
3401 rs6000_option_override (void)
3403 (void) rs6000_option_override_internal (true);
3407 /* Implement targetm.vectorize.builtin_mask_for_load. */
3408 static tree
3409 rs6000_builtin_mask_for_load (void)
3411 if (TARGET_ALTIVEC || TARGET_VSX)
3412 return altivec_builtin_mask_for_load;
3413 else
3414 return 0;
3417 /* Implement LOOP_ALIGN. */
3419 rs6000_loop_align (rtx label)
3421 basic_block bb;
3422 int ninsns;
3424 /* Don't override loop alignment if -falign-loops was specified. */
3425 if (!can_override_loop_align)
3426 return align_loops_log;
3428 bb = BLOCK_FOR_INSN (label);
3429 ninsns = num_loop_insns(bb->loop_father);
3431 /* Align small loops to 32 bytes to fit in an icache sector, otherwise return default. */
3432 if (ninsns > 4 && ninsns <= 8
3433 && (rs6000_cpu == PROCESSOR_POWER4
3434 || rs6000_cpu == PROCESSOR_POWER5
3435 || rs6000_cpu == PROCESSOR_POWER6
3436 || rs6000_cpu == PROCESSOR_POWER7))
3437 return 5;
3438 else
3439 return align_loops_log;
3442 /* Implement TARGET_LOOP_ALIGN_MAX_SKIP. */
3443 static int
3444 rs6000_loop_align_max_skip (rtx label)
3446 return (1 << rs6000_loop_align (label)) - 1;
3449 /* Implement targetm.vectorize.builtin_conversion.
3450 Returns a decl of a function that implements conversion of an integer vector
3451 into a floating-point vector, or vice-versa. DEST_TYPE is the
3452 destination type and SRC_TYPE the source type of the conversion.
3453 Return NULL_TREE if it is not available. */
3454 static tree
3455 rs6000_builtin_conversion (unsigned int tcode, tree dest_type, tree src_type)
3457 enum tree_code code = (enum tree_code) tcode;
3459 switch (code)
3461 case FIX_TRUNC_EXPR:
3462 switch (TYPE_MODE (dest_type))
3464 case V2DImode:
3465 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3466 return NULL_TREE;
3468 return TYPE_UNSIGNED (dest_type)
3469 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
3470 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
3472 case V4SImode:
3473 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3474 return NULL_TREE;
3476 return TYPE_UNSIGNED (dest_type)
3477 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
3478 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
3480 default:
3481 return NULL_TREE;
3484 case FLOAT_EXPR:
3485 switch (TYPE_MODE (src_type))
3487 case V2DImode:
3488 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3489 return NULL_TREE;
3491 return TYPE_UNSIGNED (src_type)
3492 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
3493 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
3495 case V4SImode:
3496 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3497 return NULL_TREE;
3499 return TYPE_UNSIGNED (src_type)
3500 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
3501 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
3503 default:
3504 return NULL_TREE;
3507 default:
3508 return NULL_TREE;
3512 /* Implement targetm.vectorize.builtin_mul_widen_even. */
3513 static tree
3514 rs6000_builtin_mul_widen_even (tree type)
3516 if (!TARGET_ALTIVEC)
3517 return NULL_TREE;
3519 switch (TYPE_MODE (type))
3521 case V8HImode:
3522 return TYPE_UNSIGNED (type)
3523 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
3524 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
3526 case V16QImode:
3527 return TYPE_UNSIGNED (type)
3528 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
3529 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
3530 default:
3531 return NULL_TREE;
3535 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
3536 static tree
3537 rs6000_builtin_mul_widen_odd (tree type)
3539 if (!TARGET_ALTIVEC)
3540 return NULL_TREE;
3542 switch (TYPE_MODE (type))
3544 case V8HImode:
3545 return TYPE_UNSIGNED (type)
3546 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
3547 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
3549 case V16QImode:
3550 return TYPE_UNSIGNED (type)
3551 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
3552 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
3553 default:
3554 return NULL_TREE;
3559 /* Return true iff, data reference of TYPE can reach vector alignment (16)
3560 after applying N number of iterations. This routine does not determine
3561 how may iterations are required to reach desired alignment. */
3563 static bool
3564 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
3566 if (is_packed)
3567 return false;
3569 if (TARGET_32BIT)
3571 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
3572 return true;
3574 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
3575 return true;
3577 return false;
3579 else
3581 if (TARGET_MACHO)
3582 return false;
3584 /* Assuming that all other types are naturally aligned. CHECKME! */
3585 return true;
3589 /* Return true if the vector misalignment factor is supported by the
3590 target. */
3591 bool
3592 rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
3593 const_tree type,
3594 int misalignment,
3595 bool is_packed)
3597 if (TARGET_VSX)
3599 /* Return if movmisalign pattern is not supported for this mode. */
3600 if (optab_handler (movmisalign_optab, mode) == CODE_FOR_nothing)
3601 return false;
3603 if (misalignment == -1)
3605 /* Misalignment factor is unknown at compile time but we know
3606 it's word aligned. */
3607 if (rs6000_vector_alignment_reachable (type, is_packed))
3609 int element_size = TREE_INT_CST_LOW (TYPE_SIZE (type));
3611 if (element_size == 64 || element_size == 32)
3612 return true;
3615 return false;
3618 /* VSX supports word-aligned vector. */
3619 if (misalignment % 4 == 0)
3620 return true;
3622 return false;
3625 /* Implement targetm.vectorize.builtin_vec_perm. */
3626 tree
3627 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
3629 tree inner_type = TREE_TYPE (type);
3630 bool uns_p = TYPE_UNSIGNED (inner_type);
3631 tree d;
3633 *mask_element_type = unsigned_char_type_node;
3635 switch (TYPE_MODE (type))
3637 case V16QImode:
3638 d = (uns_p
3639 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
3640 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
3641 break;
3643 case V8HImode:
3644 d = (uns_p
3645 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
3646 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
3647 break;
3649 case V4SImode:
3650 d = (uns_p
3651 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
3652 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
3653 break;
3655 case V4SFmode:
3656 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
3657 break;
3659 case V2DFmode:
3660 if (!TARGET_ALLOW_DF_PERMUTE)
3661 return NULL_TREE;
3663 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
3664 break;
3666 case V2DImode:
3667 if (!TARGET_ALLOW_DF_PERMUTE)
3668 return NULL_TREE;
3670 d = (uns_p
3671 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
3672 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
3673 break;
3675 default:
3676 return NULL_TREE;
3679 gcc_assert (d);
3680 return d;
3684 /* Implement targetm.vectorize.builtin_vectorization_cost. */
3685 static int
3686 rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
3687 tree vectype, int misalign)
3689 unsigned elements;
3691 switch (type_of_cost)
3693 case scalar_stmt:
3694 case scalar_load:
3695 case scalar_store:
3696 case vector_stmt:
3697 case vector_load:
3698 case vector_store:
3699 case vec_to_scalar:
3700 case scalar_to_vec:
3701 case cond_branch_not_taken:
3702 case vec_perm:
3703 return 1;
3705 case cond_branch_taken:
3706 return 3;
3708 case unaligned_load:
3709 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3711 elements = TYPE_VECTOR_SUBPARTS (vectype);
3712 if (elements == 2)
3713 /* Double word aligned. */
3714 return 2;
3716 if (elements == 4)
3718 switch (misalign)
3720 case 8:
3721 /* Double word aligned. */
3722 return 2;
3724 case -1:
3725 /* Unknown misalignment. */
3726 case 4:
3727 case 12:
3728 /* Word aligned. */
3729 return 22;
3731 default:
3732 gcc_unreachable ();
3737 if (TARGET_ALTIVEC)
3738 /* Misaligned loads are not supported. */
3739 gcc_unreachable ();
3741 return 2;
3743 case unaligned_store:
3744 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3746 elements = TYPE_VECTOR_SUBPARTS (vectype);
3747 if (elements == 2)
3748 /* Double word aligned. */
3749 return 2;
3751 if (elements == 4)
3753 switch (misalign)
3755 case 8:
3756 /* Double word aligned. */
3757 return 2;
3759 case -1:
3760 /* Unknown misalignment. */
3761 case 4:
3762 case 12:
3763 /* Word aligned. */
3764 return 23;
3766 default:
3767 gcc_unreachable ();
3772 if (TARGET_ALTIVEC)
3773 /* Misaligned stores are not supported. */
3774 gcc_unreachable ();
3776 return 2;
3778 default:
3779 gcc_unreachable ();
3783 /* Implement targetm.vectorize.preferred_simd_mode. */
3785 static enum machine_mode
3786 rs6000_preferred_simd_mode (enum machine_mode mode)
3788 if (TARGET_VSX)
3789 switch (mode)
3791 case DFmode:
3792 return V2DFmode;
3793 default:;
3795 if (TARGET_ALTIVEC || TARGET_VSX)
3796 switch (mode)
3798 case SFmode:
3799 return V4SFmode;
3800 case DImode:
3801 return V2DImode;
3802 case SImode:
3803 return V4SImode;
3804 case HImode:
3805 return V8HImode;
3806 case QImode:
3807 return V16QImode;
3808 default:;
3810 if (TARGET_SPE)
3811 switch (mode)
3813 case SFmode:
3814 return V2SFmode;
3815 case SImode:
3816 return V2SImode;
3817 default:;
3819 if (TARGET_PAIRED_FLOAT
3820 && mode == SFmode)
3821 return V2SFmode;
3822 return word_mode;
3825 /* Handle generic options of the form -mfoo=yes/no.
3826 NAME is the option name.
3827 VALUE is the option value.
3828 FLAG is the pointer to the flag where to store a 1 or 0, depending on
3829 whether the option value is 'yes' or 'no' respectively. */
3830 static void
3831 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
3833 if (value == 0)
3834 return;
3835 else if (!strcmp (value, "yes"))
3836 *flag = 1;
3837 else if (!strcmp (value, "no"))
3838 *flag = 0;
3839 else
3840 error ("unknown -m%s= option specified: '%s'", name, value);
3843 /* Implement TARGET_OPTION_INIT_STRUCT. */
3845 static void
3846 rs6000_option_init_struct (struct gcc_options *opts)
3848 if (DEFAULT_ABI == ABI_DARWIN)
3849 /* The Darwin libraries never set errno, so we might as well
3850 avoid calling them when that's the only reason we would. */
3851 opts->x_flag_errno_math = 0;
3853 /* Enable section anchors by default. */
3854 if (!TARGET_MACHO)
3855 opts->x_flag_section_anchors = 1;
3858 /* Implement TARGET_OPTION_DEFAULT_PARAMS. */
3860 static void
3861 rs6000_option_default_params (void)
3863 /* Double growth factor to counter reduced min jump length. */
3864 set_default_param_value (PARAM_MAX_GROW_COPY_BB_INSNS, 16);
3867 static enum fpu_type_t
3868 rs6000_parse_fpu_option (const char *option)
3870 if (!strcmp("none", option)) return FPU_NONE;
3871 if (!strcmp("sp_lite", option)) return FPU_SF_LITE;
3872 if (!strcmp("dp_lite", option)) return FPU_DF_LITE;
3873 if (!strcmp("sp_full", option)) return FPU_SF_FULL;
3874 if (!strcmp("dp_full", option)) return FPU_DF_FULL;
3875 error("unknown value %s for -mfpu", option);
3876 return FPU_NONE;
3880 /* Handler for the Mathematical Acceleration Subsystem (mass) interface to a
3881 library with vectorized intrinsics. */
3883 static tree
3884 rs6000_builtin_vectorized_libmass (tree fndecl, tree type_out, tree type_in)
3886 char name[32];
3887 const char *suffix = NULL;
3888 tree fntype, new_fndecl, bdecl = NULL_TREE;
3889 int n_args = 1;
3890 const char *bname;
3891 enum machine_mode el_mode, in_mode;
3892 int n, in_n;
3894 /* Libmass is suitable for unsafe math only as it does not correctly support
3895 parts of IEEE with the required precision such as denormals. Only support
3896 it if we have VSX to use the simd d2 or f4 functions.
3897 XXX: Add variable length support. */
3898 if (!flag_unsafe_math_optimizations || !TARGET_VSX)
3899 return NULL_TREE;
3901 el_mode = TYPE_MODE (TREE_TYPE (type_out));
3902 n = TYPE_VECTOR_SUBPARTS (type_out);
3903 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3904 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3905 if (el_mode != in_mode
3906 || n != in_n)
3907 return NULL_TREE;
3909 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3911 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3912 switch (fn)
3914 case BUILT_IN_ATAN2:
3915 case BUILT_IN_HYPOT:
3916 case BUILT_IN_POW:
3917 n_args = 2;
3918 /* fall through */
3920 case BUILT_IN_ACOS:
3921 case BUILT_IN_ACOSH:
3922 case BUILT_IN_ASIN:
3923 case BUILT_IN_ASINH:
3924 case BUILT_IN_ATAN:
3925 case BUILT_IN_ATANH:
3926 case BUILT_IN_CBRT:
3927 case BUILT_IN_COS:
3928 case BUILT_IN_COSH:
3929 case BUILT_IN_ERF:
3930 case BUILT_IN_ERFC:
3931 case BUILT_IN_EXP2:
3932 case BUILT_IN_EXP:
3933 case BUILT_IN_EXPM1:
3934 case BUILT_IN_LGAMMA:
3935 case BUILT_IN_LOG10:
3936 case BUILT_IN_LOG1P:
3937 case BUILT_IN_LOG2:
3938 case BUILT_IN_LOG:
3939 case BUILT_IN_SIN:
3940 case BUILT_IN_SINH:
3941 case BUILT_IN_SQRT:
3942 case BUILT_IN_TAN:
3943 case BUILT_IN_TANH:
3944 bdecl = implicit_built_in_decls[fn];
3945 suffix = "d2"; /* pow -> powd2 */
3946 if (el_mode != DFmode
3947 || n != 2)
3948 return NULL_TREE;
3949 break;
3951 case BUILT_IN_ATAN2F:
3952 case BUILT_IN_HYPOTF:
3953 case BUILT_IN_POWF:
3954 n_args = 2;
3955 /* fall through */
3957 case BUILT_IN_ACOSF:
3958 case BUILT_IN_ACOSHF:
3959 case BUILT_IN_ASINF:
3960 case BUILT_IN_ASINHF:
3961 case BUILT_IN_ATANF:
3962 case BUILT_IN_ATANHF:
3963 case BUILT_IN_CBRTF:
3964 case BUILT_IN_COSF:
3965 case BUILT_IN_COSHF:
3966 case BUILT_IN_ERFF:
3967 case BUILT_IN_ERFCF:
3968 case BUILT_IN_EXP2F:
3969 case BUILT_IN_EXPF:
3970 case BUILT_IN_EXPM1F:
3971 case BUILT_IN_LGAMMAF:
3972 case BUILT_IN_LOG10F:
3973 case BUILT_IN_LOG1PF:
3974 case BUILT_IN_LOG2F:
3975 case BUILT_IN_LOGF:
3976 case BUILT_IN_SINF:
3977 case BUILT_IN_SINHF:
3978 case BUILT_IN_SQRTF:
3979 case BUILT_IN_TANF:
3980 case BUILT_IN_TANHF:
3981 bdecl = implicit_built_in_decls[fn];
3982 suffix = "4"; /* powf -> powf4 */
3983 if (el_mode != SFmode
3984 || n != 4)
3985 return NULL_TREE;
3986 break;
3988 default:
3989 return NULL_TREE;
3992 else
3993 return NULL_TREE;
3995 gcc_assert (suffix != NULL);
3996 bname = IDENTIFIER_POINTER (DECL_NAME (bdecl));
3997 strcpy (name, bname + sizeof ("__builtin_") - 1);
3998 strcat (name, suffix);
4000 if (n_args == 1)
4001 fntype = build_function_type_list (type_out, type_in, NULL);
4002 else if (n_args == 2)
4003 fntype = build_function_type_list (type_out, type_in, type_in, NULL);
4004 else
4005 gcc_unreachable ();
4007 /* Build a function declaration for the vectorized function. */
4008 new_fndecl = build_decl (BUILTINS_LOCATION,
4009 FUNCTION_DECL, get_identifier (name), fntype);
4010 TREE_PUBLIC (new_fndecl) = 1;
4011 DECL_EXTERNAL (new_fndecl) = 1;
4012 DECL_IS_NOVOPS (new_fndecl) = 1;
4013 TREE_READONLY (new_fndecl) = 1;
4015 return new_fndecl;
4018 /* Returns a function decl for a vectorized version of the builtin function
4019 with builtin function code FN and the result vector type TYPE, or NULL_TREE
4020 if it is not available. */
4022 static tree
4023 rs6000_builtin_vectorized_function (tree fndecl, tree type_out,
4024 tree type_in)
4026 enum machine_mode in_mode, out_mode;
4027 int in_n, out_n;
4029 if (TREE_CODE (type_out) != VECTOR_TYPE
4030 || TREE_CODE (type_in) != VECTOR_TYPE
4031 || !TARGET_VECTORIZE_BUILTINS)
4032 return NULL_TREE;
4034 out_mode = TYPE_MODE (TREE_TYPE (type_out));
4035 out_n = TYPE_VECTOR_SUBPARTS (type_out);
4036 in_mode = TYPE_MODE (TREE_TYPE (type_in));
4037 in_n = TYPE_VECTOR_SUBPARTS (type_in);
4039 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
4041 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
4042 switch (fn)
4044 case BUILT_IN_COPYSIGN:
4045 if (VECTOR_UNIT_VSX_P (V2DFmode)
4046 && out_mode == DFmode && out_n == 2
4047 && in_mode == DFmode && in_n == 2)
4048 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
4049 break;
4050 case BUILT_IN_COPYSIGNF:
4051 if (out_mode != SFmode || out_n != 4
4052 || in_mode != SFmode || in_n != 4)
4053 break;
4054 if (VECTOR_UNIT_VSX_P (V4SFmode))
4055 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
4056 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4057 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
4058 break;
4059 case BUILT_IN_SQRT:
4060 if (VECTOR_UNIT_VSX_P (V2DFmode)
4061 && out_mode == DFmode && out_n == 2
4062 && in_mode == DFmode && in_n == 2)
4063 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
4064 break;
4065 case BUILT_IN_SQRTF:
4066 if (VECTOR_UNIT_VSX_P (V4SFmode)
4067 && out_mode == SFmode && out_n == 4
4068 && in_mode == SFmode && in_n == 4)
4069 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
4070 break;
4071 case BUILT_IN_CEIL:
4072 if (VECTOR_UNIT_VSX_P (V2DFmode)
4073 && out_mode == DFmode && out_n == 2
4074 && in_mode == DFmode && in_n == 2)
4075 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
4076 break;
4077 case BUILT_IN_CEILF:
4078 if (out_mode != SFmode || out_n != 4
4079 || in_mode != SFmode || in_n != 4)
4080 break;
4081 if (VECTOR_UNIT_VSX_P (V4SFmode))
4082 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
4083 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4084 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
4085 break;
4086 case BUILT_IN_FLOOR:
4087 if (VECTOR_UNIT_VSX_P (V2DFmode)
4088 && out_mode == DFmode && out_n == 2
4089 && in_mode == DFmode && in_n == 2)
4090 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
4091 break;
4092 case BUILT_IN_FLOORF:
4093 if (out_mode != SFmode || out_n != 4
4094 || in_mode != SFmode || in_n != 4)
4095 break;
4096 if (VECTOR_UNIT_VSX_P (V4SFmode))
4097 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
4098 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4099 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
4100 break;
4101 case BUILT_IN_FMA:
4102 if (VECTOR_UNIT_VSX_P (V2DFmode)
4103 && out_mode == DFmode && out_n == 2
4104 && in_mode == DFmode && in_n == 2)
4105 return rs6000_builtin_decls[VSX_BUILTIN_XVMADDDP];
4106 break;
4107 case BUILT_IN_FMAF:
4108 if (VECTOR_UNIT_VSX_P (V4SFmode)
4109 && out_mode == SFmode && out_n == 4
4110 && in_mode == SFmode && in_n == 4)
4111 return rs6000_builtin_decls[VSX_BUILTIN_XVMADDSP];
4112 else if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)
4113 && out_mode == SFmode && out_n == 4
4114 && in_mode == SFmode && in_n == 4)
4115 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VMADDFP];
4116 break;
4117 case BUILT_IN_TRUNC:
4118 if (VECTOR_UNIT_VSX_P (V2DFmode)
4119 && out_mode == DFmode && out_n == 2
4120 && in_mode == DFmode && in_n == 2)
4121 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
4122 break;
4123 case BUILT_IN_TRUNCF:
4124 if (out_mode != SFmode || out_n != 4
4125 || in_mode != SFmode || in_n != 4)
4126 break;
4127 if (VECTOR_UNIT_VSX_P (V4SFmode))
4128 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
4129 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4130 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
4131 break;
4132 case BUILT_IN_NEARBYINT:
4133 if (VECTOR_UNIT_VSX_P (V2DFmode)
4134 && flag_unsafe_math_optimizations
4135 && out_mode == DFmode && out_n == 2
4136 && in_mode == DFmode && in_n == 2)
4137 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
4138 break;
4139 case BUILT_IN_NEARBYINTF:
4140 if (VECTOR_UNIT_VSX_P (V4SFmode)
4141 && flag_unsafe_math_optimizations
4142 && out_mode == SFmode && out_n == 4
4143 && in_mode == SFmode && in_n == 4)
4144 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
4145 break;
4146 case BUILT_IN_RINT:
4147 if (VECTOR_UNIT_VSX_P (V2DFmode)
4148 && !flag_trapping_math
4149 && out_mode == DFmode && out_n == 2
4150 && in_mode == DFmode && in_n == 2)
4151 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
4152 break;
4153 case BUILT_IN_RINTF:
4154 if (VECTOR_UNIT_VSX_P (V4SFmode)
4155 && !flag_trapping_math
4156 && out_mode == SFmode && out_n == 4
4157 && in_mode == SFmode && in_n == 4)
4158 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
4159 break;
4160 default:
4161 break;
4165 else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
4167 enum rs6000_builtins fn
4168 = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl);
4169 switch (fn)
4171 case RS6000_BUILTIN_RSQRTF:
4172 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
4173 && out_mode == SFmode && out_n == 4
4174 && in_mode == SFmode && in_n == 4)
4175 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRSQRTFP];
4176 break;
4177 case RS6000_BUILTIN_RSQRT:
4178 if (VECTOR_UNIT_VSX_P (V2DFmode)
4179 && out_mode == DFmode && out_n == 2
4180 && in_mode == DFmode && in_n == 2)
4181 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
4182 break;
4183 case RS6000_BUILTIN_RECIPF:
4184 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
4185 && out_mode == SFmode && out_n == 4
4186 && in_mode == SFmode && in_n == 4)
4187 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRECIPFP];
4188 break;
4189 case RS6000_BUILTIN_RECIP:
4190 if (VECTOR_UNIT_VSX_P (V2DFmode)
4191 && out_mode == DFmode && out_n == 2
4192 && in_mode == DFmode && in_n == 2)
4193 return rs6000_builtin_decls[VSX_BUILTIN_RECIP_V2DF];
4194 break;
4195 default:
4196 break;
4200 /* Generate calls to libmass if appropriate. */
4201 if (rs6000_veclib_handler)
4202 return rs6000_veclib_handler (fndecl, type_out, type_in);
4204 return NULL_TREE;
4208 /* Implement TARGET_HANDLE_OPTION. */
4210 static bool
4211 rs6000_handle_option (size_t code, const char *arg, int value)
4213 enum fpu_type_t fpu_type = FPU_NONE;
4214 int isel;
4215 char *p, *q;
4217 switch (code)
4219 case OPT_mno_power:
4220 target_flags &= ~(MASK_POWER | MASK_POWER2
4221 | MASK_MULTIPLE | MASK_STRING);
4222 target_flags_explicit |= (MASK_POWER | MASK_POWER2
4223 | MASK_MULTIPLE | MASK_STRING);
4224 break;
4225 case OPT_mno_powerpc:
4226 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
4227 | MASK_PPC_GFXOPT | MASK_POWERPC64);
4228 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
4229 | MASK_PPC_GFXOPT | MASK_POWERPC64);
4230 break;
4231 case OPT_mfull_toc:
4232 target_flags &= ~MASK_MINIMAL_TOC;
4233 TARGET_NO_FP_IN_TOC = 0;
4234 TARGET_NO_SUM_IN_TOC = 0;
4235 target_flags_explicit |= MASK_MINIMAL_TOC;
4236 #ifdef TARGET_USES_SYSV4_OPT
4237 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
4238 just the same as -mminimal-toc. */
4239 target_flags |= MASK_MINIMAL_TOC;
4240 target_flags_explicit |= MASK_MINIMAL_TOC;
4241 #endif
4242 break;
4244 #ifdef TARGET_USES_SYSV4_OPT
4245 case OPT_mtoc:
4246 /* Make -mtoc behave like -mminimal-toc. */
4247 target_flags |= MASK_MINIMAL_TOC;
4248 target_flags_explicit |= MASK_MINIMAL_TOC;
4249 break;
4250 #endif
4252 #if defined (HAVE_LD_LARGE_TOC) && defined (TARGET_USES_LINUX64_OPT)
4253 case OPT_mcmodel_:
4254 if (strcmp (arg, "small") == 0)
4255 rs6000_current_cmodel = CMODEL_SMALL;
4256 else if (strcmp (arg, "medium") == 0)
4257 rs6000_current_cmodel = CMODEL_MEDIUM;
4258 else if (strcmp (arg, "large") == 0)
4259 rs6000_current_cmodel = CMODEL_LARGE;
4260 else
4262 error ("invalid option for -mcmodel: '%s'", arg);
4263 return false;
4265 rs6000_explicit_options.cmodel = true;
4266 #endif
4268 #ifdef TARGET_USES_AIX64_OPT
4269 case OPT_maix64:
4270 #else
4271 case OPT_m64:
4272 #endif
4273 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
4274 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
4275 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
4276 break;
4278 #ifdef TARGET_USES_AIX64_OPT
4279 case OPT_maix32:
4280 #else
4281 case OPT_m32:
4282 #endif
4283 target_flags &= ~MASK_POWERPC64;
4284 target_flags_explicit |= MASK_POWERPC64;
4285 break;
4287 case OPT_minsert_sched_nops_:
4288 rs6000_sched_insert_nops_str = arg;
4289 break;
4291 case OPT_mminimal_toc:
4292 if (value == 1)
4294 TARGET_NO_FP_IN_TOC = 0;
4295 TARGET_NO_SUM_IN_TOC = 0;
4297 break;
4299 case OPT_mpower:
4300 if (value == 1)
4302 target_flags |= (MASK_MULTIPLE | MASK_STRING);
4303 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
4305 break;
4307 case OPT_mpower2:
4308 if (value == 1)
4310 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
4311 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
4313 break;
4315 case OPT_mpowerpc_gpopt:
4316 case OPT_mpowerpc_gfxopt:
4317 if (value == 1)
4319 target_flags |= MASK_POWERPC;
4320 target_flags_explicit |= MASK_POWERPC;
4322 break;
4324 case OPT_maix_struct_return:
4325 case OPT_msvr4_struct_return:
4326 rs6000_explicit_options.aix_struct_ret = true;
4327 break;
4329 case OPT_mvrsave:
4330 rs6000_explicit_options.vrsave = true;
4331 TARGET_ALTIVEC_VRSAVE = value;
4332 break;
4334 case OPT_mvrsave_:
4335 rs6000_explicit_options.vrsave = true;
4336 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
4337 break;
4339 case OPT_misel_:
4340 target_flags_explicit |= MASK_ISEL;
4341 isel = 0;
4342 rs6000_parse_yes_no_option ("isel", arg, &isel);
4343 if (isel)
4344 target_flags |= MASK_ISEL;
4345 else
4346 target_flags &= ~MASK_ISEL;
4347 break;
4349 case OPT_mspe:
4350 rs6000_explicit_options.spe = true;
4351 rs6000_spe = value;
4352 break;
4354 case OPT_mspe_:
4355 rs6000_explicit_options.spe = true;
4356 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
4357 break;
4359 case OPT_mdebug_:
4360 p = ASTRDUP (arg);
4361 rs6000_debug = 0;
4363 while ((q = strtok (p, ",")) != NULL)
4365 unsigned mask = 0;
4366 bool invert;
4368 p = NULL;
4369 if (*q == '!')
4371 invert = true;
4372 q++;
4374 else
4375 invert = false;
4377 if (! strcmp (q, "all"))
4378 mask = MASK_DEBUG_ALL;
4379 else if (! strcmp (q, "stack"))
4380 mask = MASK_DEBUG_STACK;
4381 else if (! strcmp (q, "arg"))
4382 mask = MASK_DEBUG_ARG;
4383 else if (! strcmp (q, "reg"))
4384 mask = MASK_DEBUG_REG;
4385 else if (! strcmp (q, "addr"))
4386 mask = MASK_DEBUG_ADDR;
4387 else if (! strcmp (q, "cost"))
4388 mask = MASK_DEBUG_COST;
4389 else if (! strcmp (q, "target"))
4390 mask = MASK_DEBUG_TARGET;
4391 else
4392 error ("unknown -mdebug-%s switch", q);
4394 if (invert)
4395 rs6000_debug &= ~mask;
4396 else
4397 rs6000_debug |= mask;
4399 break;
4401 #ifdef TARGET_USES_SYSV4_OPT
4402 case OPT_mcall_:
4403 rs6000_abi_name = arg;
4404 break;
4406 case OPT_msdata_:
4407 rs6000_sdata_name = arg;
4408 break;
4410 case OPT_mtls_size_:
4411 if (strcmp (arg, "16") == 0)
4412 rs6000_tls_size = 16;
4413 else if (strcmp (arg, "32") == 0)
4414 rs6000_tls_size = 32;
4415 else if (strcmp (arg, "64") == 0)
4416 rs6000_tls_size = 64;
4417 else
4418 error ("bad value %qs for -mtls-size switch", arg);
4419 break;
4421 case OPT_mrelocatable:
4422 if (value == 1)
4424 target_flags |= MASK_MINIMAL_TOC;
4425 target_flags_explicit |= MASK_MINIMAL_TOC;
4426 TARGET_NO_FP_IN_TOC = 1;
4428 break;
4430 case OPT_mrelocatable_lib:
4431 if (value == 1)
4433 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
4434 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
4435 TARGET_NO_FP_IN_TOC = 1;
4437 else
4439 target_flags &= ~MASK_RELOCATABLE;
4440 target_flags_explicit |= MASK_RELOCATABLE;
4442 break;
4443 #endif
4445 case OPT_mabi_:
4446 if (!strcmp (arg, "altivec"))
4448 rs6000_explicit_options.altivec_abi = true;
4449 rs6000_altivec_abi = 1;
4451 /* Enabling the AltiVec ABI turns off the SPE ABI. */
4452 rs6000_spe_abi = 0;
4454 else if (! strcmp (arg, "no-altivec"))
4456 rs6000_explicit_options.altivec_abi = true;
4457 rs6000_altivec_abi = 0;
4459 else if (! strcmp (arg, "spe"))
4461 rs6000_explicit_options.spe_abi = true;
4462 rs6000_spe_abi = 1;
4463 rs6000_altivec_abi = 0;
4464 if (!TARGET_SPE_ABI)
4465 error ("not configured for ABI: '%s'", arg);
4467 else if (! strcmp (arg, "no-spe"))
4469 rs6000_explicit_options.spe_abi = true;
4470 rs6000_spe_abi = 0;
4473 /* These are here for testing during development only, do not
4474 document in the manual please. */
4475 else if (! strcmp (arg, "d64"))
4477 rs6000_darwin64_abi = 1;
4478 warning (0, "using darwin64 ABI");
4480 else if (! strcmp (arg, "d32"))
4482 rs6000_darwin64_abi = 0;
4483 warning (0, "using old darwin ABI");
4486 else if (! strcmp (arg, "ibmlongdouble"))
4488 rs6000_explicit_options.ieee = true;
4489 rs6000_ieeequad = 0;
4490 warning (0, "using IBM extended precision long double");
4492 else if (! strcmp (arg, "ieeelongdouble"))
4494 rs6000_explicit_options.ieee = true;
4495 rs6000_ieeequad = 1;
4496 warning (0, "using IEEE extended precision long double");
4499 else
4501 error ("unknown ABI specified: '%s'", arg);
4502 return false;
4504 break;
4506 case OPT_mcpu_:
4507 rs6000_select[1].string = arg;
4508 rs6000_cpu_index = rs6000_cpu_name_lookup (arg);
4509 if (rs6000_cpu_index < 0)
4510 error ("bad value (%s) for -mcpu", arg);
4511 break;
4513 case OPT_mtune_:
4514 rs6000_select[2].string = arg;
4515 rs6000_tune_index = rs6000_cpu_name_lookup (arg);
4516 if (rs6000_tune_index < 0)
4517 error ("bad value (%s) for -mtune", arg);
4518 break;
4520 case OPT_mtraceback_:
4521 if (! strncmp (arg, "full", 4))
4522 rs6000_traceback = traceback_full;
4523 else if (! strncmp (arg, "part", 4))
4524 rs6000_traceback = traceback_part;
4525 else if (! strncmp (arg, "no", 2))
4526 rs6000_traceback = traceback_none;
4527 else
4528 error ("unknown -mtraceback arg %qs; expecting %<full%>, "
4529 "%<partial%> or %<none%>", arg);
4530 break;
4532 case OPT_mfloat_gprs_:
4533 rs6000_explicit_options.float_gprs = true;
4534 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
4535 rs6000_float_gprs = 1;
4536 else if (! strcmp (arg, "double"))
4537 rs6000_float_gprs = 2;
4538 else if (! strcmp (arg, "no"))
4539 rs6000_float_gprs = 0;
4540 else
4542 error ("invalid option for -mfloat-gprs: '%s'", arg);
4543 return false;
4545 break;
4547 case OPT_mlong_double_:
4548 rs6000_explicit_options.long_double = true;
4549 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4550 if (value != 64 && value != 128)
4552 error ("unknown switch -mlong-double-%s", arg);
4553 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4554 return false;
4556 else
4557 rs6000_long_double_type_size = value;
4558 break;
4560 case OPT_msched_costly_dep_:
4561 rs6000_sched_costly_dep_str = arg;
4562 break;
4564 case OPT_malign_:
4565 rs6000_explicit_options.alignment = true;
4566 if (! strcmp (arg, "power"))
4568 /* On 64-bit Darwin, power alignment is ABI-incompatible with
4569 some C library functions, so warn about it. The flag may be
4570 useful for performance studies from time to time though, so
4571 don't disable it entirely. */
4572 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
4573 warning (0, "-malign-power is not supported for 64-bit Darwin;"
4574 " it is incompatible with the installed C and C++ libraries");
4575 rs6000_alignment_flags = MASK_ALIGN_POWER;
4577 else if (! strcmp (arg, "natural"))
4578 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
4579 else
4581 error ("unknown -malign-XXXXX option specified: '%s'", arg);
4582 return false;
4584 break;
4586 case OPT_msingle_float:
4587 if (!TARGET_SINGLE_FPU)
4588 warning (0, "-msingle-float option equivalent to -mhard-float");
4589 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
4590 rs6000_double_float = 0;
4591 target_flags &= ~MASK_SOFT_FLOAT;
4592 target_flags_explicit |= MASK_SOFT_FLOAT;
4593 break;
4595 case OPT_mdouble_float:
4596 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
4597 rs6000_single_float = 1;
4598 target_flags &= ~MASK_SOFT_FLOAT;
4599 target_flags_explicit |= MASK_SOFT_FLOAT;
4600 break;
4602 case OPT_msimple_fpu:
4603 if (!TARGET_SINGLE_FPU)
4604 warning (0, "-msimple-fpu option ignored");
4605 break;
4607 case OPT_mhard_float:
4608 /* -mhard_float implies -msingle-float and -mdouble-float. */
4609 rs6000_single_float = rs6000_double_float = 1;
4610 break;
4612 case OPT_msoft_float:
4613 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
4614 rs6000_single_float = rs6000_double_float = 0;
4615 break;
4617 case OPT_mfpu_:
4618 fpu_type = rs6000_parse_fpu_option(arg);
4619 if (fpu_type != FPU_NONE)
4620 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
4622 target_flags &= ~MASK_SOFT_FLOAT;
4623 target_flags_explicit |= MASK_SOFT_FLOAT;
4624 rs6000_xilinx_fpu = 1;
4625 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
4626 rs6000_single_float = 1;
4627 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
4628 rs6000_single_float = rs6000_double_float = 1;
4629 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
4630 rs6000_simple_fpu = 1;
4632 else
4634 /* -mfpu=none is equivalent to -msoft-float */
4635 target_flags |= MASK_SOFT_FLOAT;
4636 target_flags_explicit |= MASK_SOFT_FLOAT;
4637 rs6000_single_float = rs6000_double_float = 0;
4640 case OPT_mrecip:
4641 rs6000_recip_name = (value) ? "default" : "none";
4642 break;
4644 case OPT_mrecip_:
4645 rs6000_recip_name = arg;
4646 break;
4648 return true;
4651 /* Do anything needed at the start of the asm file. */
4653 static void
4654 rs6000_file_start (void)
4656 size_t i;
4657 char buffer[80];
4658 const char *start = buffer;
4659 struct rs6000_cpu_select *ptr;
4660 const char *default_cpu = TARGET_CPU_DEFAULT;
4661 FILE *file = asm_out_file;
4663 default_file_start ();
4665 #ifdef TARGET_BI_ARCH
4666 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
4667 default_cpu = 0;
4668 #endif
4670 if (flag_verbose_asm)
4672 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
4673 rs6000_select[0].string = default_cpu;
4675 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
4677 ptr = &rs6000_select[i];
4678 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
4680 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
4681 start = "";
4685 if (PPC405_ERRATUM77)
4687 fprintf (file, "%s PPC405CR_ERRATUM77", start);
4688 start = "";
4691 #ifdef USING_ELFOS_H
4692 switch (rs6000_sdata)
4694 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
4695 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
4696 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
4697 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
4700 if (rs6000_sdata && g_switch_value)
4702 fprintf (file, "%s -G %d", start,
4703 g_switch_value);
4704 start = "";
4706 #endif
4708 if (*start == '\0')
4709 putc ('\n', file);
4712 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
4714 switch_to_section (toc_section);
4715 switch_to_section (text_section);
4720 /* Return nonzero if this function is known to have a null epilogue. */
4723 direct_return (void)
4725 if (reload_completed)
4727 rs6000_stack_t *info = rs6000_stack_info ();
4729 if (info->first_gp_reg_save == 32
4730 && info->first_fp_reg_save == 64
4731 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
4732 && ! info->lr_save_p
4733 && ! info->cr_save_p
4734 && info->vrsave_mask == 0
4735 && ! info->push_p)
4736 return 1;
4739 return 0;
4742 /* Return the number of instructions it takes to form a constant in an
4743 integer register. */
4746 num_insns_constant_wide (HOST_WIDE_INT value)
4748 /* signed constant loadable with {cal|addi} */
4749 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
4750 return 1;
4752 /* constant loadable with {cau|addis} */
4753 else if ((value & 0xffff) == 0
4754 && (value >> 31 == -1 || value >> 31 == 0))
4755 return 1;
4757 #if HOST_BITS_PER_WIDE_INT == 64
4758 else if (TARGET_POWERPC64)
4760 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
4761 HOST_WIDE_INT high = value >> 31;
4763 if (high == 0 || high == -1)
4764 return 2;
4766 high >>= 1;
4768 if (low == 0)
4769 return num_insns_constant_wide (high) + 1;
4770 else if (high == 0)
4771 return num_insns_constant_wide (low) + 1;
4772 else
4773 return (num_insns_constant_wide (high)
4774 + num_insns_constant_wide (low) + 1);
4776 #endif
4778 else
4779 return 2;
4783 num_insns_constant (rtx op, enum machine_mode mode)
4785 HOST_WIDE_INT low, high;
4787 switch (GET_CODE (op))
4789 case CONST_INT:
4790 #if HOST_BITS_PER_WIDE_INT == 64
4791 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
4792 && mask64_operand (op, mode))
4793 return 2;
4794 else
4795 #endif
4796 return num_insns_constant_wide (INTVAL (op));
4798 case CONST_DOUBLE:
4799 if (mode == SFmode || mode == SDmode)
4801 long l;
4802 REAL_VALUE_TYPE rv;
4804 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4805 if (DECIMAL_FLOAT_MODE_P (mode))
4806 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
4807 else
4808 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
4809 return num_insns_constant_wide ((HOST_WIDE_INT) l);
4812 if (mode == VOIDmode || mode == DImode)
4814 high = CONST_DOUBLE_HIGH (op);
4815 low = CONST_DOUBLE_LOW (op);
4817 else
4819 long l[2];
4820 REAL_VALUE_TYPE rv;
4822 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4823 if (DECIMAL_FLOAT_MODE_P (mode))
4824 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
4825 else
4826 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
4827 high = l[WORDS_BIG_ENDIAN == 0];
4828 low = l[WORDS_BIG_ENDIAN != 0];
4831 if (TARGET_32BIT)
4832 return (num_insns_constant_wide (low)
4833 + num_insns_constant_wide (high));
4834 else
4836 if ((high == 0 && low >= 0)
4837 || (high == -1 && low < 0))
4838 return num_insns_constant_wide (low);
4840 else if (mask64_operand (op, mode))
4841 return 2;
4843 else if (low == 0)
4844 return num_insns_constant_wide (high) + 1;
4846 else
4847 return (num_insns_constant_wide (high)
4848 + num_insns_constant_wide (low) + 1);
4851 default:
4852 gcc_unreachable ();
4856 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
4857 If the mode of OP is MODE_VECTOR_INT, this simply returns the
4858 corresponding element of the vector, but for V4SFmode and V2SFmode,
4859 the corresponding "float" is interpreted as an SImode integer. */
4861 HOST_WIDE_INT
4862 const_vector_elt_as_int (rtx op, unsigned int elt)
4864 rtx tmp;
4866 /* We can't handle V2DImode and V2DFmode vector constants here yet. */
4867 gcc_assert (GET_MODE (op) != V2DImode
4868 && GET_MODE (op) != V2DFmode);
4870 tmp = CONST_VECTOR_ELT (op, elt);
4871 if (GET_MODE (op) == V4SFmode
4872 || GET_MODE (op) == V2SFmode)
4873 tmp = gen_lowpart (SImode, tmp);
4874 return INTVAL (tmp);
4877 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
4878 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
4879 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
4880 all items are set to the same value and contain COPIES replicas of the
4881 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
4882 operand and the others are set to the value of the operand's msb. */
4884 static bool
4885 vspltis_constant (rtx op, unsigned step, unsigned copies)
4887 enum machine_mode mode = GET_MODE (op);
4888 enum machine_mode inner = GET_MODE_INNER (mode);
4890 unsigned i;
4891 unsigned nunits;
4892 unsigned bitsize;
4893 unsigned mask;
4895 HOST_WIDE_INT val;
4896 HOST_WIDE_INT splat_val;
4897 HOST_WIDE_INT msb_val;
4899 if (mode == V2DImode || mode == V2DFmode)
4900 return false;
4902 nunits = GET_MODE_NUNITS (mode);
4903 bitsize = GET_MODE_BITSIZE (inner);
4904 mask = GET_MODE_MASK (inner);
4906 val = const_vector_elt_as_int (op, nunits - 1);
4907 splat_val = val;
4908 msb_val = val > 0 ? 0 : -1;
4910 /* Construct the value to be splatted, if possible. If not, return 0. */
4911 for (i = 2; i <= copies; i *= 2)
4913 HOST_WIDE_INT small_val;
4914 bitsize /= 2;
4915 small_val = splat_val >> bitsize;
4916 mask >>= bitsize;
4917 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
4918 return false;
4919 splat_val = small_val;
4922 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
4923 if (EASY_VECTOR_15 (splat_val))
4926 /* Also check if we can splat, and then add the result to itself. Do so if
4927 the value is positive, of if the splat instruction is using OP's mode;
4928 for splat_val < 0, the splat and the add should use the same mode. */
4929 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
4930 && (splat_val >= 0 || (step == 1 && copies == 1)))
4933 /* Also check if are loading up the most significant bit which can be done by
4934 loading up -1 and shifting the value left by -1. */
4935 else if (EASY_VECTOR_MSB (splat_val, inner))
4938 else
4939 return false;
4941 /* Check if VAL is present in every STEP-th element, and the
4942 other elements are filled with its most significant bit. */
4943 for (i = 0; i < nunits - 1; ++i)
4945 HOST_WIDE_INT desired_val;
4946 if (((i + 1) & (step - 1)) == 0)
4947 desired_val = val;
4948 else
4949 desired_val = msb_val;
4951 if (desired_val != const_vector_elt_as_int (op, i))
4952 return false;
4955 return true;
4959 /* Return true if OP is of the given MODE and can be synthesized
4960 with a vspltisb, vspltish or vspltisw. */
4962 bool
4963 easy_altivec_constant (rtx op, enum machine_mode mode)
4965 unsigned step, copies;
4967 if (mode == VOIDmode)
4968 mode = GET_MODE (op);
4969 else if (mode != GET_MODE (op))
4970 return false;
4972 /* V2DI/V2DF was added with VSX. Only allow 0 and all 1's as easy
4973 constants. */
4974 if (mode == V2DFmode)
4975 return zero_constant (op, mode);
4977 if (mode == V2DImode)
4979 /* In case the compiler is built 32-bit, CONST_DOUBLE constants are not
4980 easy. */
4981 if (GET_CODE (CONST_VECTOR_ELT (op, 0)) != CONST_INT
4982 || GET_CODE (CONST_VECTOR_ELT (op, 1)) != CONST_INT)
4983 return false;
4985 if (zero_constant (op, mode))
4986 return true;
4988 if (INTVAL (CONST_VECTOR_ELT (op, 0)) == -1
4989 && INTVAL (CONST_VECTOR_ELT (op, 1)) == -1)
4990 return true;
4992 return false;
4995 /* Start with a vspltisw. */
4996 step = GET_MODE_NUNITS (mode) / 4;
4997 copies = 1;
4999 if (vspltis_constant (op, step, copies))
5000 return true;
5002 /* Then try with a vspltish. */
5003 if (step == 1)
5004 copies <<= 1;
5005 else
5006 step >>= 1;
5008 if (vspltis_constant (op, step, copies))
5009 return true;
5011 /* And finally a vspltisb. */
5012 if (step == 1)
5013 copies <<= 1;
5014 else
5015 step >>= 1;
5017 if (vspltis_constant (op, step, copies))
5018 return true;
5020 return false;
5023 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
5024 result is OP. Abort if it is not possible. */
5027 gen_easy_altivec_constant (rtx op)
5029 enum machine_mode mode = GET_MODE (op);
5030 int nunits = GET_MODE_NUNITS (mode);
5031 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
5032 unsigned step = nunits / 4;
5033 unsigned copies = 1;
5035 /* Start with a vspltisw. */
5036 if (vspltis_constant (op, step, copies))
5037 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
5039 /* Then try with a vspltish. */
5040 if (step == 1)
5041 copies <<= 1;
5042 else
5043 step >>= 1;
5045 if (vspltis_constant (op, step, copies))
5046 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
5048 /* And finally a vspltisb. */
5049 if (step == 1)
5050 copies <<= 1;
5051 else
5052 step >>= 1;
5054 if (vspltis_constant (op, step, copies))
5055 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
5057 gcc_unreachable ();
5060 const char *
5061 output_vec_const_move (rtx *operands)
5063 int cst, cst2;
5064 enum machine_mode mode;
5065 rtx dest, vec;
5067 dest = operands[0];
5068 vec = operands[1];
5069 mode = GET_MODE (dest);
5071 if (TARGET_VSX)
5073 if (zero_constant (vec, mode))
5074 return "xxlxor %x0,%x0,%x0";
5076 if (mode == V2DImode
5077 && INTVAL (CONST_VECTOR_ELT (vec, 0)) == -1
5078 && INTVAL (CONST_VECTOR_ELT (vec, 1)) == -1)
5079 return "vspltisw %0,-1";
5082 if (TARGET_ALTIVEC)
5084 rtx splat_vec;
5085 if (zero_constant (vec, mode))
5086 return "vxor %0,%0,%0";
5088 splat_vec = gen_easy_altivec_constant (vec);
5089 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
5090 operands[1] = XEXP (splat_vec, 0);
5091 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
5092 return "#";
5094 switch (GET_MODE (splat_vec))
5096 case V4SImode:
5097 return "vspltisw %0,%1";
5099 case V8HImode:
5100 return "vspltish %0,%1";
5102 case V16QImode:
5103 return "vspltisb %0,%1";
5105 default:
5106 gcc_unreachable ();
5110 gcc_assert (TARGET_SPE);
5112 /* Vector constant 0 is handled as a splitter of V2SI, and in the
5113 pattern of V1DI, V4HI, and V2SF.
5115 FIXME: We should probably return # and add post reload
5116 splitters for these, but this way is so easy ;-). */
5117 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
5118 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
5119 operands[1] = CONST_VECTOR_ELT (vec, 0);
5120 operands[2] = CONST_VECTOR_ELT (vec, 1);
5121 if (cst == cst2)
5122 return "li %0,%1\n\tevmergelo %0,%0,%0";
5123 else
5124 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
5127 /* Initialize TARGET of vector PAIRED to VALS. */
5129 void
5130 paired_expand_vector_init (rtx target, rtx vals)
5132 enum machine_mode mode = GET_MODE (target);
5133 int n_elts = GET_MODE_NUNITS (mode);
5134 int n_var = 0;
5135 rtx x, new_rtx, tmp, constant_op, op1, op2;
5136 int i;
5138 for (i = 0; i < n_elts; ++i)
5140 x = XVECEXP (vals, 0, i);
5141 if (!CONSTANT_P (x))
5142 ++n_var;
5144 if (n_var == 0)
5146 /* Load from constant pool. */
5147 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
5148 return;
5151 if (n_var == 2)
5153 /* The vector is initialized only with non-constants. */
5154 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
5155 XVECEXP (vals, 0, 1));
5157 emit_move_insn (target, new_rtx);
5158 return;
5161 /* One field is non-constant and the other one is a constant. Load the
5162 constant from the constant pool and use ps_merge instruction to
5163 construct the whole vector. */
5164 op1 = XVECEXP (vals, 0, 0);
5165 op2 = XVECEXP (vals, 0, 1);
5167 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
5169 tmp = gen_reg_rtx (GET_MODE (constant_op));
5170 emit_move_insn (tmp, constant_op);
5172 if (CONSTANT_P (op1))
5173 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
5174 else
5175 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
5177 emit_move_insn (target, new_rtx);
5180 void
5181 paired_expand_vector_move (rtx operands[])
5183 rtx op0 = operands[0], op1 = operands[1];
5185 emit_move_insn (op0, op1);
5188 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
5189 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
5190 operands for the relation operation COND. This is a recursive
5191 function. */
5193 static void
5194 paired_emit_vector_compare (enum rtx_code rcode,
5195 rtx dest, rtx op0, rtx op1,
5196 rtx cc_op0, rtx cc_op1)
5198 rtx tmp = gen_reg_rtx (V2SFmode);
5199 rtx tmp1, max, min;
5201 gcc_assert (TARGET_PAIRED_FLOAT);
5202 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
5204 switch (rcode)
5206 case LT:
5207 case LTU:
5208 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
5209 return;
5210 case GE:
5211 case GEU:
5212 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
5213 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
5214 return;
5215 case LE:
5216 case LEU:
5217 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
5218 return;
5219 case GT:
5220 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
5221 return;
5222 case EQ:
5223 tmp1 = gen_reg_rtx (V2SFmode);
5224 max = gen_reg_rtx (V2SFmode);
5225 min = gen_reg_rtx (V2SFmode);
5226 gen_reg_rtx (V2SFmode);
5228 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
5229 emit_insn (gen_selv2sf4
5230 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
5231 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
5232 emit_insn (gen_selv2sf4
5233 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
5234 emit_insn (gen_subv2sf3 (tmp1, min, max));
5235 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
5236 return;
5237 case NE:
5238 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
5239 return;
5240 case UNLE:
5241 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
5242 return;
5243 case UNLT:
5244 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
5245 return;
5246 case UNGE:
5247 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
5248 return;
5249 case UNGT:
5250 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
5251 return;
5252 default:
5253 gcc_unreachable ();
5256 return;
5259 /* Emit vector conditional expression.
5260 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
5261 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
5264 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
5265 rtx cond, rtx cc_op0, rtx cc_op1)
5267 enum rtx_code rcode = GET_CODE (cond);
5269 if (!TARGET_PAIRED_FLOAT)
5270 return 0;
5272 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
5274 return 1;
5277 /* Initialize vector TARGET to VALS. */
5279 void
5280 rs6000_expand_vector_init (rtx target, rtx vals)
5282 enum machine_mode mode = GET_MODE (target);
5283 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5284 int n_elts = GET_MODE_NUNITS (mode);
5285 int n_var = 0, one_var = -1;
5286 bool all_same = true, all_const_zero = true;
5287 rtx x, mem;
5288 int i;
5290 for (i = 0; i < n_elts; ++i)
5292 x = XVECEXP (vals, 0, i);
5293 if (!CONSTANT_P (x))
5294 ++n_var, one_var = i;
5295 else if (x != CONST0_RTX (inner_mode))
5296 all_const_zero = false;
5298 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
5299 all_same = false;
5302 if (n_var == 0)
5304 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
5305 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
5306 if ((int_vector_p || TARGET_VSX) && all_const_zero)
5308 /* Zero register. */
5309 emit_insn (gen_rtx_SET (VOIDmode, target,
5310 gen_rtx_XOR (mode, target, target)));
5311 return;
5313 else if (int_vector_p && easy_vector_constant (const_vec, mode))
5315 /* Splat immediate. */
5316 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
5317 return;
5319 else
5321 /* Load from constant pool. */
5322 emit_move_insn (target, const_vec);
5323 return;
5327 /* Double word values on VSX can use xxpermdi or lxvdsx. */
5328 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5330 if (all_same)
5332 rtx element = XVECEXP (vals, 0, 0);
5333 if (mode == V2DFmode)
5334 emit_insn (gen_vsx_splat_v2df (target, element));
5335 else
5336 emit_insn (gen_vsx_splat_v2di (target, element));
5338 else
5340 if (mode == V2DFmode)
5342 rtx op0 = copy_to_mode_reg (DFmode, XVECEXP (vals, 0, 0));
5343 rtx op1 = copy_to_mode_reg (DFmode, XVECEXP (vals, 0, 1));
5344 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
5346 else
5348 rtx op0 = copy_to_mode_reg (DImode, XVECEXP (vals, 0, 0));
5349 rtx op1 = copy_to_mode_reg (DImode, XVECEXP (vals, 0, 1));
5350 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
5353 return;
5356 /* With single precision floating point on VSX, know that internally single
5357 precision is actually represented as a double, and either make 2 V2DF
5358 vectors, and convert these vectors to single precision, or do one
5359 conversion, and splat the result to the other elements. */
5360 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
5362 if (all_same)
5364 rtx freg = gen_reg_rtx (V4SFmode);
5365 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
5367 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
5368 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
5370 else
5372 rtx dbl_even = gen_reg_rtx (V2DFmode);
5373 rtx dbl_odd = gen_reg_rtx (V2DFmode);
5374 rtx flt_even = gen_reg_rtx (V4SFmode);
5375 rtx flt_odd = gen_reg_rtx (V4SFmode);
5377 emit_insn (gen_vsx_concat_v2sf (dbl_even,
5378 copy_to_reg (XVECEXP (vals, 0, 0)),
5379 copy_to_reg (XVECEXP (vals, 0, 1))));
5380 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
5381 copy_to_reg (XVECEXP (vals, 0, 2)),
5382 copy_to_reg (XVECEXP (vals, 0, 3))));
5383 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
5384 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
5385 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
5387 return;
5390 /* Store value to stack temp. Load vector element. Splat. However, splat
5391 of 64-bit items is not supported on Altivec. */
5392 if (all_same && GET_MODE_SIZE (mode) <= 4)
5394 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
5395 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
5396 XVECEXP (vals, 0, 0));
5397 x = gen_rtx_UNSPEC (VOIDmode,
5398 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
5399 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5400 gen_rtvec (2,
5401 gen_rtx_SET (VOIDmode,
5402 target, mem),
5403 x)));
5404 x = gen_rtx_VEC_SELECT (inner_mode, target,
5405 gen_rtx_PARALLEL (VOIDmode,
5406 gen_rtvec (1, const0_rtx)));
5407 emit_insn (gen_rtx_SET (VOIDmode, target,
5408 gen_rtx_VEC_DUPLICATE (mode, x)));
5409 return;
5412 /* One field is non-constant. Load constant then overwrite
5413 varying field. */
5414 if (n_var == 1)
5416 rtx copy = copy_rtx (vals);
5418 /* Load constant part of vector, substitute neighboring value for
5419 varying element. */
5420 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
5421 rs6000_expand_vector_init (target, copy);
5423 /* Insert variable. */
5424 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
5425 return;
5428 /* Construct the vector in memory one field at a time
5429 and load the whole vector. */
5430 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
5431 for (i = 0; i < n_elts; i++)
5432 emit_move_insn (adjust_address_nv (mem, inner_mode,
5433 i * GET_MODE_SIZE (inner_mode)),
5434 XVECEXP (vals, 0, i));
5435 emit_move_insn (target, mem);
5438 /* Set field ELT of TARGET to VAL. */
5440 void
5441 rs6000_expand_vector_set (rtx target, rtx val, int elt)
5443 enum machine_mode mode = GET_MODE (target);
5444 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5445 rtx reg = gen_reg_rtx (mode);
5446 rtx mask, mem, x;
5447 int width = GET_MODE_SIZE (inner_mode);
5448 int i;
5450 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5452 rtx (*set_func) (rtx, rtx, rtx, rtx)
5453 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
5454 emit_insn (set_func (target, target, val, GEN_INT (elt)));
5455 return;
5458 /* Load single variable value. */
5459 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
5460 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
5461 x = gen_rtx_UNSPEC (VOIDmode,
5462 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
5463 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5464 gen_rtvec (2,
5465 gen_rtx_SET (VOIDmode,
5466 reg, mem),
5467 x)));
5469 /* Linear sequence. */
5470 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
5471 for (i = 0; i < 16; ++i)
5472 XVECEXP (mask, 0, i) = GEN_INT (i);
5474 /* Set permute mask to insert element into target. */
5475 for (i = 0; i < width; ++i)
5476 XVECEXP (mask, 0, elt*width + i)
5477 = GEN_INT (i + 0x10);
5478 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
5479 x = gen_rtx_UNSPEC (mode,
5480 gen_rtvec (3, target, reg,
5481 force_reg (V16QImode, x)),
5482 UNSPEC_VPERM);
5483 emit_insn (gen_rtx_SET (VOIDmode, target, x));
5486 /* Extract field ELT from VEC into TARGET. */
5488 void
5489 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
5491 enum machine_mode mode = GET_MODE (vec);
5492 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5493 rtx mem;
5495 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5497 rtx (*extract_func) (rtx, rtx, rtx)
5498 = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
5499 emit_insn (extract_func (target, vec, GEN_INT (elt)));
5500 return;
5503 /* Allocate mode-sized buffer. */
5504 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
5506 emit_move_insn (mem, vec);
5508 /* Add offset to field within buffer matching vector element. */
5509 mem = adjust_address_nv (mem, inner_mode, elt * GET_MODE_SIZE (inner_mode));
5511 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
5514 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
5515 implement ANDing by the mask IN. */
5516 void
5517 build_mask64_2_operands (rtx in, rtx *out)
5519 #if HOST_BITS_PER_WIDE_INT >= 64
5520 unsigned HOST_WIDE_INT c, lsb, m1, m2;
5521 int shift;
5523 gcc_assert (GET_CODE (in) == CONST_INT);
5525 c = INTVAL (in);
5526 if (c & 1)
5528 /* Assume c initially something like 0x00fff000000fffff. The idea
5529 is to rotate the word so that the middle ^^^^^^ group of zeros
5530 is at the MS end and can be cleared with an rldicl mask. We then
5531 rotate back and clear off the MS ^^ group of zeros with a
5532 second rldicl. */
5533 c = ~c; /* c == 0xff000ffffff00000 */
5534 lsb = c & -c; /* lsb == 0x0000000000100000 */
5535 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
5536 c = ~c; /* c == 0x00fff000000fffff */
5537 c &= -lsb; /* c == 0x00fff00000000000 */
5538 lsb = c & -c; /* lsb == 0x0000100000000000 */
5539 c = ~c; /* c == 0xff000fffffffffff */
5540 c &= -lsb; /* c == 0xff00000000000000 */
5541 shift = 0;
5542 while ((lsb >>= 1) != 0)
5543 shift++; /* shift == 44 on exit from loop */
5544 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
5545 m1 = ~m1; /* m1 == 0x000000ffffffffff */
5546 m2 = ~c; /* m2 == 0x00ffffffffffffff */
5548 else
5550 /* Assume c initially something like 0xff000f0000000000. The idea
5551 is to rotate the word so that the ^^^ middle group of zeros
5552 is at the LS end and can be cleared with an rldicr mask. We then
5553 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
5554 a second rldicr. */
5555 lsb = c & -c; /* lsb == 0x0000010000000000 */
5556 m2 = -lsb; /* m2 == 0xffffff0000000000 */
5557 c = ~c; /* c == 0x00fff0ffffffffff */
5558 c &= -lsb; /* c == 0x00fff00000000000 */
5559 lsb = c & -c; /* lsb == 0x0000100000000000 */
5560 c = ~c; /* c == 0xff000fffffffffff */
5561 c &= -lsb; /* c == 0xff00000000000000 */
5562 shift = 0;
5563 while ((lsb >>= 1) != 0)
5564 shift++; /* shift == 44 on exit from loop */
5565 m1 = ~c; /* m1 == 0x00ffffffffffffff */
5566 m1 >>= shift; /* m1 == 0x0000000000000fff */
5567 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
5570 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
5571 masks will be all 1's. We are guaranteed more than one transition. */
5572 out[0] = GEN_INT (64 - shift);
5573 out[1] = GEN_INT (m1);
5574 out[2] = GEN_INT (shift);
5575 out[3] = GEN_INT (m2);
5576 #else
5577 (void)in;
5578 (void)out;
5579 gcc_unreachable ();
5580 #endif
5583 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
5585 bool
5586 invalid_e500_subreg (rtx op, enum machine_mode mode)
5588 if (TARGET_E500_DOUBLE)
5590 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
5591 subreg:TI and reg:TF. Decimal float modes are like integer
5592 modes (only low part of each register used) for this
5593 purpose. */
5594 if (GET_CODE (op) == SUBREG
5595 && (mode == SImode || mode == DImode || mode == TImode
5596 || mode == DDmode || mode == TDmode)
5597 && REG_P (SUBREG_REG (op))
5598 && (GET_MODE (SUBREG_REG (op)) == DFmode
5599 || GET_MODE (SUBREG_REG (op)) == TFmode))
5600 return true;
5602 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
5603 reg:TI. */
5604 if (GET_CODE (op) == SUBREG
5605 && (mode == DFmode || mode == TFmode)
5606 && REG_P (SUBREG_REG (op))
5607 && (GET_MODE (SUBREG_REG (op)) == DImode
5608 || GET_MODE (SUBREG_REG (op)) == TImode
5609 || GET_MODE (SUBREG_REG (op)) == DDmode
5610 || GET_MODE (SUBREG_REG (op)) == TDmode))
5611 return true;
5614 if (TARGET_SPE
5615 && GET_CODE (op) == SUBREG
5616 && mode == SImode
5617 && REG_P (SUBREG_REG (op))
5618 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
5619 return true;
5621 return false;
5624 /* AIX increases natural record alignment to doubleword if the first
5625 field is an FP double while the FP fields remain word aligned. */
5627 unsigned int
5628 rs6000_special_round_type_align (tree type, unsigned int computed,
5629 unsigned int specified)
5631 unsigned int align = MAX (computed, specified);
5632 tree field = TYPE_FIELDS (type);
5634 /* Skip all non field decls */
5635 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5636 field = DECL_CHAIN (field);
5638 if (field != NULL && field != type)
5640 type = TREE_TYPE (field);
5641 while (TREE_CODE (type) == ARRAY_TYPE)
5642 type = TREE_TYPE (type);
5644 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
5645 align = MAX (align, 64);
5648 return align;
5651 /* Darwin increases record alignment to the natural alignment of
5652 the first field. */
5654 unsigned int
5655 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
5656 unsigned int specified)
5658 unsigned int align = MAX (computed, specified);
5660 if (TYPE_PACKED (type))
5661 return align;
5663 /* Find the first field, looking down into aggregates. */
5664 do {
5665 tree field = TYPE_FIELDS (type);
5666 /* Skip all non field decls */
5667 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5668 field = DECL_CHAIN (field);
5669 if (! field)
5670 break;
5671 /* A packed field does not contribute any extra alignment. */
5672 if (DECL_PACKED (field))
5673 return align;
5674 type = TREE_TYPE (field);
5675 while (TREE_CODE (type) == ARRAY_TYPE)
5676 type = TREE_TYPE (type);
5677 } while (AGGREGATE_TYPE_P (type));
5679 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
5680 align = MAX (align, TYPE_ALIGN (type));
5682 return align;
5685 /* Return 1 for an operand in small memory on V.4/eabi. */
5688 small_data_operand (rtx op ATTRIBUTE_UNUSED,
5689 enum machine_mode mode ATTRIBUTE_UNUSED)
5691 #if TARGET_ELF
5692 rtx sym_ref;
5694 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
5695 return 0;
5697 if (DEFAULT_ABI != ABI_V4)
5698 return 0;
5700 /* Vector and float memory instructions have a limited offset on the
5701 SPE, so using a vector or float variable directly as an operand is
5702 not useful. */
5703 if (TARGET_SPE
5704 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
5705 return 0;
5707 if (GET_CODE (op) == SYMBOL_REF)
5708 sym_ref = op;
5710 else if (GET_CODE (op) != CONST
5711 || GET_CODE (XEXP (op, 0)) != PLUS
5712 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
5713 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
5714 return 0;
5716 else
5718 rtx sum = XEXP (op, 0);
5719 HOST_WIDE_INT summand;
5721 /* We have to be careful here, because it is the referenced address
5722 that must be 32k from _SDA_BASE_, not just the symbol. */
5723 summand = INTVAL (XEXP (sum, 1));
5724 if (summand < 0 || summand > g_switch_value)
5725 return 0;
5727 sym_ref = XEXP (sum, 0);
5730 return SYMBOL_REF_SMALL_P (sym_ref);
5731 #else
5732 return 0;
5733 #endif
5736 /* Return true if either operand is a general purpose register. */
5738 bool
5739 gpr_or_gpr_p (rtx op0, rtx op1)
5741 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
5742 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
5746 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
5748 static bool
5749 reg_offset_addressing_ok_p (enum machine_mode mode)
5751 switch (mode)
5753 case V16QImode:
5754 case V8HImode:
5755 case V4SFmode:
5756 case V4SImode:
5757 case V2DFmode:
5758 case V2DImode:
5759 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
5760 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
5761 return false;
5762 break;
5764 case V4HImode:
5765 case V2SImode:
5766 case V1DImode:
5767 case V2SFmode:
5768 /* Paired vector modes. Only reg+reg addressing is valid. */
5769 if (TARGET_PAIRED_FLOAT)
5770 return false;
5771 break;
5773 default:
5774 break;
5777 return true;
5780 static bool
5781 virtual_stack_registers_memory_p (rtx op)
5783 int regnum;
5785 if (GET_CODE (op) == REG)
5786 regnum = REGNO (op);
5788 else if (GET_CODE (op) == PLUS
5789 && GET_CODE (XEXP (op, 0)) == REG
5790 && GET_CODE (XEXP (op, 1)) == CONST_INT)
5791 regnum = REGNO (XEXP (op, 0));
5793 else
5794 return false;
5796 return (regnum >= FIRST_VIRTUAL_REGISTER
5797 && regnum <= LAST_VIRTUAL_POINTER_REGISTER);
5800 /* Return true if memory accesses to OP are known to never straddle
5801 a 32k boundary. */
5803 static bool
5804 offsettable_ok_by_alignment (rtx op, HOST_WIDE_INT offset,
5805 enum machine_mode mode)
5807 tree decl, type;
5808 unsigned HOST_WIDE_INT dsize, dalign;
5810 if (GET_CODE (op) != SYMBOL_REF)
5811 return false;
5813 decl = SYMBOL_REF_DECL (op);
5814 if (!decl)
5816 if (GET_MODE_SIZE (mode) == 0)
5817 return false;
5819 /* -fsection-anchors loses the original SYMBOL_REF_DECL when
5820 replacing memory addresses with an anchor plus offset. We
5821 could find the decl by rummaging around in the block->objects
5822 VEC for the given offset but that seems like too much work. */
5823 dalign = 1;
5824 if (SYMBOL_REF_HAS_BLOCK_INFO_P (op)
5825 && SYMBOL_REF_ANCHOR_P (op)
5826 && SYMBOL_REF_BLOCK (op) != NULL)
5828 struct object_block *block = SYMBOL_REF_BLOCK (op);
5829 HOST_WIDE_INT lsb, mask;
5831 /* Given the alignment of the block.. */
5832 dalign = block->alignment;
5833 mask = dalign / BITS_PER_UNIT - 1;
5835 /* ..and the combined offset of the anchor and any offset
5836 to this block object.. */
5837 offset += SYMBOL_REF_BLOCK_OFFSET (op);
5838 lsb = offset & -offset;
5840 /* ..find how many bits of the alignment we know for the
5841 object. */
5842 mask &= lsb - 1;
5843 dalign = mask + 1;
5845 return dalign >= GET_MODE_SIZE (mode);
5848 if (DECL_P (decl))
5850 if (TREE_CODE (decl) == FUNCTION_DECL)
5851 return true;
5853 if (!DECL_SIZE_UNIT (decl))
5854 return false;
5856 if (!host_integerp (DECL_SIZE_UNIT (decl), 1))
5857 return false;
5859 dsize = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
5860 if (dsize > 32768)
5861 return false;
5863 dalign = DECL_ALIGN_UNIT (decl);
5864 return dalign >= dsize;
5867 type = TREE_TYPE (decl);
5869 if (TREE_CODE (decl) == STRING_CST)
5870 dsize = TREE_STRING_LENGTH (decl);
5871 else if (TYPE_SIZE_UNIT (type)
5872 && host_integerp (TYPE_SIZE_UNIT (type), 1))
5873 dsize = tree_low_cst (TYPE_SIZE_UNIT (type), 1);
5874 else
5875 return false;
5876 if (dsize > 32768)
5877 return false;
5879 dalign = TYPE_ALIGN (type);
5880 if (CONSTANT_CLASS_P (decl))
5881 dalign = CONSTANT_ALIGNMENT (decl, dalign);
5882 else
5883 dalign = DATA_ALIGNMENT (decl, dalign);
5884 dalign /= BITS_PER_UNIT;
5885 return dalign >= dsize;
5888 static bool
5889 constant_pool_expr_p (rtx op)
5891 rtx base, offset;
5893 split_const (op, &base, &offset);
5894 return (GET_CODE (base) == SYMBOL_REF
5895 && CONSTANT_POOL_ADDRESS_P (base)
5896 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
5899 static rtx tocrel_base, tocrel_offset;
5901 bool
5902 toc_relative_expr_p (rtx op)
5904 if (GET_CODE (op) != CONST)
5905 return false;
5907 split_const (op, &tocrel_base, &tocrel_offset);
5908 return (GET_CODE (tocrel_base) == UNSPEC
5909 && XINT (tocrel_base, 1) == UNSPEC_TOCREL);
5912 /* Return true if X is a constant pool address, and also for cmodel=medium
5913 if X is a toc-relative address known to be offsettable within MODE. */
5915 bool
5916 legitimate_constant_pool_address_p (const_rtx x, enum machine_mode mode,
5917 bool strict)
5919 return (TARGET_TOC
5920 && (GET_CODE (x) == PLUS || GET_CODE (x) == LO_SUM)
5921 && GET_CODE (XEXP (x, 0)) == REG
5922 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5923 || ((TARGET_MINIMAL_TOC
5924 || TARGET_CMODEL != CMODEL_SMALL)
5925 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict)))
5926 && toc_relative_expr_p (XEXP (x, 1))
5927 && (TARGET_CMODEL != CMODEL_MEDIUM
5928 || constant_pool_expr_p (XVECEXP (tocrel_base, 0, 0))
5929 || mode == QImode
5930 || offsettable_ok_by_alignment (XVECEXP (tocrel_base, 0, 0),
5931 INTVAL (tocrel_offset), mode)));
5934 static bool
5935 legitimate_small_data_p (enum machine_mode mode, rtx x)
5937 return (DEFAULT_ABI == ABI_V4
5938 && !flag_pic && !TARGET_TOC
5939 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
5940 && small_data_operand (x, mode));
5943 /* SPE offset addressing is limited to 5-bits worth of double words. */
5944 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
5946 bool
5947 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
5949 unsigned HOST_WIDE_INT offset, extra;
5951 if (GET_CODE (x) != PLUS)
5952 return false;
5953 if (GET_CODE (XEXP (x, 0)) != REG)
5954 return false;
5955 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5956 return false;
5957 if (!reg_offset_addressing_ok_p (mode))
5958 return virtual_stack_registers_memory_p (x);
5959 if (legitimate_constant_pool_address_p (x, mode, strict))
5960 return true;
5961 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5962 return false;
5964 offset = INTVAL (XEXP (x, 1));
5965 extra = 0;
5966 switch (mode)
5968 case V4HImode:
5969 case V2SImode:
5970 case V1DImode:
5971 case V2SFmode:
5972 /* SPE vector modes. */
5973 return SPE_CONST_OFFSET_OK (offset);
5975 case DFmode:
5976 if (TARGET_E500_DOUBLE)
5977 return SPE_CONST_OFFSET_OK (offset);
5979 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
5980 addressing. */
5981 if (VECTOR_MEM_VSX_P (DFmode))
5982 return false;
5984 case DDmode:
5985 case DImode:
5986 /* On e500v2, we may have:
5988 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
5990 Which gets addressed with evldd instructions. */
5991 if (TARGET_E500_DOUBLE)
5992 return SPE_CONST_OFFSET_OK (offset);
5994 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
5995 extra = 4;
5996 else if (offset & 3)
5997 return false;
5998 break;
6000 case TFmode:
6001 if (TARGET_E500_DOUBLE)
6002 return (SPE_CONST_OFFSET_OK (offset)
6003 && SPE_CONST_OFFSET_OK (offset + 8));
6005 case TDmode:
6006 case TImode:
6007 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
6008 extra = 12;
6009 else if (offset & 3)
6010 return false;
6011 else
6012 extra = 8;
6013 break;
6015 default:
6016 break;
6019 offset += 0x8000;
6020 return (offset < 0x10000) && (offset + extra < 0x10000);
6023 bool
6024 legitimate_indexed_address_p (rtx x, int strict)
6026 rtx op0, op1;
6028 if (GET_CODE (x) != PLUS)
6029 return false;
6031 op0 = XEXP (x, 0);
6032 op1 = XEXP (x, 1);
6034 /* Recognize the rtl generated by reload which we know will later be
6035 replaced with proper base and index regs. */
6036 if (!strict
6037 && reload_in_progress
6038 && (REG_P (op0) || GET_CODE (op0) == PLUS)
6039 && REG_P (op1))
6040 return true;
6042 return (REG_P (op0) && REG_P (op1)
6043 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
6044 && INT_REG_OK_FOR_INDEX_P (op1, strict))
6045 || (INT_REG_OK_FOR_BASE_P (op1, strict)
6046 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
6049 bool
6050 avoiding_indexed_address_p (enum machine_mode mode)
6052 /* Avoid indexed addressing for modes that have non-indexed
6053 load/store instruction forms. */
6054 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
6057 inline bool
6058 legitimate_indirect_address_p (rtx x, int strict)
6060 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
6063 bool
6064 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
6066 if (!TARGET_MACHO || !flag_pic
6067 || mode != SImode || GET_CODE (x) != MEM)
6068 return false;
6069 x = XEXP (x, 0);
6071 if (GET_CODE (x) != LO_SUM)
6072 return false;
6073 if (GET_CODE (XEXP (x, 0)) != REG)
6074 return false;
6075 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
6076 return false;
6077 x = XEXP (x, 1);
6079 return CONSTANT_P (x);
6082 static bool
6083 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
6085 if (GET_CODE (x) != LO_SUM)
6086 return false;
6087 if (GET_CODE (XEXP (x, 0)) != REG)
6088 return false;
6089 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
6090 return false;
6091 /* Restrict addressing for DI because of our SUBREG hackery. */
6092 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6093 || mode == DDmode || mode == TDmode
6094 || mode == DImode))
6095 return false;
6096 x = XEXP (x, 1);
6098 if (TARGET_ELF || TARGET_MACHO)
6100 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
6101 return false;
6102 if (TARGET_TOC)
6103 return false;
6104 if (GET_MODE_NUNITS (mode) != 1)
6105 return false;
6106 if (GET_MODE_BITSIZE (mode) > 64
6107 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
6108 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6109 && (mode == DFmode || mode == DDmode))))
6110 return false;
6112 return CONSTANT_P (x);
6115 return false;
6119 /* Try machine-dependent ways of modifying an illegitimate address
6120 to be legitimate. If we find one, return the new, valid address.
6121 This is used from only one place: `memory_address' in explow.c.
6123 OLDX is the address as it was before break_out_memory_refs was
6124 called. In some cases it is useful to look at this to decide what
6125 needs to be done.
6127 It is always safe for this function to do nothing. It exists to
6128 recognize opportunities to optimize the output.
6130 On RS/6000, first check for the sum of a register with a constant
6131 integer that is out of range. If so, generate code to add the
6132 constant with the low-order 16 bits masked to the register and force
6133 this result into another register (this can be done with `cau').
6134 Then generate an address of REG+(CONST&0xffff), allowing for the
6135 possibility of bit 16 being a one.
6137 Then check for the sum of a register and something not constant, try to
6138 load the other things into a register and return the sum. */
6140 static rtx
6141 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
6142 enum machine_mode mode)
6144 unsigned int extra = 0;
6146 if (!reg_offset_addressing_ok_p (mode))
6148 if (virtual_stack_registers_memory_p (x))
6149 return x;
6151 /* In theory we should not be seeing addresses of the form reg+0,
6152 but just in case it is generated, optimize it away. */
6153 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
6154 return force_reg (Pmode, XEXP (x, 0));
6156 /* Make sure both operands are registers. */
6157 else if (GET_CODE (x) == PLUS)
6158 return gen_rtx_PLUS (Pmode,
6159 force_reg (Pmode, XEXP (x, 0)),
6160 force_reg (Pmode, XEXP (x, 1)));
6161 else
6162 return force_reg (Pmode, x);
6164 if (GET_CODE (x) == SYMBOL_REF)
6166 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
6167 if (model != 0)
6168 return rs6000_legitimize_tls_address (x, model);
6171 switch (mode)
6173 case DFmode:
6174 case DDmode:
6175 extra = 4;
6176 break;
6177 case DImode:
6178 if (!TARGET_POWERPC64)
6179 extra = 4;
6180 break;
6181 case TFmode:
6182 case TDmode:
6183 extra = 12;
6184 break;
6185 case TImode:
6186 extra = TARGET_POWERPC64 ? 8 : 12;
6187 break;
6188 default:
6189 break;
6192 if (GET_CODE (x) == PLUS
6193 && GET_CODE (XEXP (x, 0)) == REG
6194 && GET_CODE (XEXP (x, 1)) == CONST_INT
6195 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
6196 >= 0x10000 - extra)
6197 && !((TARGET_POWERPC64
6198 && (mode == DImode || mode == TImode)
6199 && (INTVAL (XEXP (x, 1)) & 3) != 0)
6200 || SPE_VECTOR_MODE (mode)
6201 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6202 || mode == DImode || mode == DDmode
6203 || mode == TDmode))))
6205 HOST_WIDE_INT high_int, low_int;
6206 rtx sum;
6207 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
6208 if (low_int >= 0x8000 - extra)
6209 low_int = 0;
6210 high_int = INTVAL (XEXP (x, 1)) - low_int;
6211 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
6212 GEN_INT (high_int)), 0);
6213 return plus_constant (sum, low_int);
6215 else if (GET_CODE (x) == PLUS
6216 && GET_CODE (XEXP (x, 0)) == REG
6217 && GET_CODE (XEXP (x, 1)) != CONST_INT
6218 && GET_MODE_NUNITS (mode) == 1
6219 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6220 || TARGET_POWERPC64
6221 || ((mode != DImode && mode != DFmode && mode != DDmode)
6222 || (TARGET_E500_DOUBLE && mode != DDmode)))
6223 && (TARGET_POWERPC64 || mode != DImode)
6224 && !avoiding_indexed_address_p (mode)
6225 && mode != TImode
6226 && mode != TFmode
6227 && mode != TDmode)
6229 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
6230 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
6232 else if (SPE_VECTOR_MODE (mode)
6233 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6234 || mode == DDmode || mode == TDmode
6235 || mode == DImode)))
6237 if (mode == DImode)
6238 return x;
6239 /* We accept [reg + reg] and [reg + OFFSET]. */
6241 if (GET_CODE (x) == PLUS)
6243 rtx op1 = XEXP (x, 0);
6244 rtx op2 = XEXP (x, 1);
6245 rtx y;
6247 op1 = force_reg (Pmode, op1);
6249 if (GET_CODE (op2) != REG
6250 && (GET_CODE (op2) != CONST_INT
6251 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
6252 || (GET_MODE_SIZE (mode) > 8
6253 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
6254 op2 = force_reg (Pmode, op2);
6256 /* We can't always do [reg + reg] for these, because [reg +
6257 reg + offset] is not a legitimate addressing mode. */
6258 y = gen_rtx_PLUS (Pmode, op1, op2);
6260 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
6261 return force_reg (Pmode, y);
6262 else
6263 return y;
6266 return force_reg (Pmode, x);
6268 else if (TARGET_ELF
6269 && TARGET_32BIT
6270 && TARGET_NO_TOC
6271 && ! flag_pic
6272 && GET_CODE (x) != CONST_INT
6273 && GET_CODE (x) != CONST_DOUBLE
6274 && CONSTANT_P (x)
6275 && GET_MODE_NUNITS (mode) == 1
6276 && (GET_MODE_BITSIZE (mode) <= 32
6277 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6278 && (mode == DFmode || mode == DDmode))))
6280 rtx reg = gen_reg_rtx (Pmode);
6281 emit_insn (gen_elf_high (reg, x));
6282 return gen_rtx_LO_SUM (Pmode, reg, x);
6284 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
6285 && ! flag_pic
6286 #if TARGET_MACHO
6287 && ! MACHO_DYNAMIC_NO_PIC_P
6288 #endif
6289 && GET_CODE (x) != CONST_INT
6290 && GET_CODE (x) != CONST_DOUBLE
6291 && CONSTANT_P (x)
6292 && GET_MODE_NUNITS (mode) == 1
6293 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6294 || (mode != DFmode && mode != DDmode))
6295 && mode != DImode
6296 && mode != TImode)
6298 rtx reg = gen_reg_rtx (Pmode);
6299 emit_insn (gen_macho_high (reg, x));
6300 return gen_rtx_LO_SUM (Pmode, reg, x);
6302 else if (TARGET_TOC
6303 && GET_CODE (x) == SYMBOL_REF
6304 && constant_pool_expr_p (x)
6305 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
6307 rtx reg = TARGET_CMODEL != CMODEL_SMALL ? gen_reg_rtx (Pmode) : NULL_RTX;
6308 return create_TOC_reference (x, reg);
6310 else
6311 return x;
6314 /* Debug version of rs6000_legitimize_address. */
6315 static rtx
6316 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
6318 rtx ret;
6319 rtx insns;
6321 start_sequence ();
6322 ret = rs6000_legitimize_address (x, oldx, mode);
6323 insns = get_insns ();
6324 end_sequence ();
6326 if (ret != x)
6328 fprintf (stderr,
6329 "\nrs6000_legitimize_address: mode %s, old code %s, "
6330 "new code %s, modified\n",
6331 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
6332 GET_RTX_NAME (GET_CODE (ret)));
6334 fprintf (stderr, "Original address:\n");
6335 debug_rtx (x);
6337 fprintf (stderr, "oldx:\n");
6338 debug_rtx (oldx);
6340 fprintf (stderr, "New address:\n");
6341 debug_rtx (ret);
6343 if (insns)
6345 fprintf (stderr, "Insns added:\n");
6346 debug_rtx_list (insns, 20);
6349 else
6351 fprintf (stderr,
6352 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
6353 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
6355 debug_rtx (x);
6358 if (insns)
6359 emit_insn (insns);
6361 return ret;
6364 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
6365 We need to emit DTP-relative relocations. */
6367 static void
6368 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
6370 switch (size)
6372 case 4:
6373 fputs ("\t.long\t", file);
6374 break;
6375 case 8:
6376 fputs (DOUBLE_INT_ASM_OP, file);
6377 break;
6378 default:
6379 gcc_unreachable ();
6381 output_addr_const (file, x);
6382 fputs ("@dtprel+0x8000", file);
6385 /* In the name of slightly smaller debug output, and to cater to
6386 general assembler lossage, recognize various UNSPEC sequences
6387 and turn them back into a direct symbol reference. */
6389 static rtx
6390 rs6000_delegitimize_address (rtx orig_x)
6392 rtx x, y;
6394 orig_x = delegitimize_mem_from_attrs (orig_x);
6395 x = orig_x;
6396 if (MEM_P (x))
6397 x = XEXP (x, 0);
6399 if (GET_CODE (x) == (TARGET_CMODEL != CMODEL_SMALL ? LO_SUM : PLUS)
6400 && GET_CODE (XEXP (x, 1)) == CONST)
6402 y = XEXP (XEXP (x, 1), 0);
6403 if (GET_CODE (y) == UNSPEC
6404 && XINT (y, 1) == UNSPEC_TOCREL
6405 && ((GET_CODE (XEXP (x, 0)) == REG
6406 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
6407 || TARGET_MINIMAL_TOC
6408 || TARGET_CMODEL != CMODEL_SMALL))
6409 || (TARGET_CMODEL != CMODEL_SMALL
6410 && GET_CODE (XEXP (x, 0)) == PLUS
6411 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6412 && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER
6413 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6414 && rtx_equal_p (XEXP (x, 1),
6415 XEXP (XEXP (XEXP (x, 0), 1), 0)))))
6417 y = XVECEXP (y, 0, 0);
6418 if (!MEM_P (orig_x))
6419 return y;
6420 else
6421 return replace_equiv_address_nv (orig_x, y);
6425 if (TARGET_MACHO
6426 && GET_CODE (orig_x) == LO_SUM
6427 && GET_CODE (XEXP (x, 1)) == CONST)
6429 y = XEXP (XEXP (x, 1), 0);
6430 if (GET_CODE (y) == UNSPEC
6431 && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET)
6432 return XVECEXP (y, 0, 0);
6435 return orig_x;
6438 /* Construct the SYMBOL_REF for the tls_get_addr function. */
6440 static GTY(()) rtx rs6000_tls_symbol;
6441 static rtx
6442 rs6000_tls_get_addr (void)
6444 if (!rs6000_tls_symbol)
6445 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
6447 return rs6000_tls_symbol;
6450 /* Construct the SYMBOL_REF for TLS GOT references. */
6452 static GTY(()) rtx rs6000_got_symbol;
6453 static rtx
6454 rs6000_got_sym (void)
6456 if (!rs6000_got_symbol)
6458 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
6459 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
6460 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
6463 return rs6000_got_symbol;
6466 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
6467 this (thread-local) address. */
6469 static rtx
6470 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
6472 rtx dest, insn;
6474 dest = gen_reg_rtx (Pmode);
6475 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
6477 rtx tlsreg;
6479 if (TARGET_64BIT)
6481 tlsreg = gen_rtx_REG (Pmode, 13);
6482 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
6484 else
6486 tlsreg = gen_rtx_REG (Pmode, 2);
6487 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
6489 emit_insn (insn);
6491 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
6493 rtx tlsreg, tmp;
6495 tmp = gen_reg_rtx (Pmode);
6496 if (TARGET_64BIT)
6498 tlsreg = gen_rtx_REG (Pmode, 13);
6499 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
6501 else
6503 tlsreg = gen_rtx_REG (Pmode, 2);
6504 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
6506 emit_insn (insn);
6507 if (TARGET_64BIT)
6508 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
6509 else
6510 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
6511 emit_insn (insn);
6513 else
6515 rtx r3, got, tga, tmp1, tmp2, call_insn;
6517 /* We currently use relocations like @got@tlsgd for tls, which
6518 means the linker will handle allocation of tls entries, placing
6519 them in the .got section. So use a pointer to the .got section,
6520 not one to secondary TOC sections used by 64-bit -mminimal-toc,
6521 or to secondary GOT sections used by 32-bit -fPIC. */
6522 if (TARGET_64BIT)
6523 got = gen_rtx_REG (Pmode, 2);
6524 else
6526 if (flag_pic == 1)
6527 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
6528 else
6530 rtx gsym = rs6000_got_sym ();
6531 got = gen_reg_rtx (Pmode);
6532 if (flag_pic == 0)
6533 rs6000_emit_move (got, gsym, Pmode);
6534 else
6536 rtx mem, lab, last;
6538 tmp1 = gen_reg_rtx (Pmode);
6539 tmp2 = gen_reg_rtx (Pmode);
6540 mem = gen_const_mem (Pmode, tmp1);
6541 lab = gen_label_rtx ();
6542 emit_insn (gen_load_toc_v4_PIC_1b (gsym, lab));
6543 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
6544 emit_move_insn (tmp2, mem);
6545 last = emit_insn (gen_addsi3 (got, tmp1, tmp2));
6546 set_unique_reg_note (last, REG_EQUAL, gsym);
6551 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
6553 r3 = gen_rtx_REG (Pmode, 3);
6554 tga = rs6000_tls_get_addr ();
6555 emit_library_call_value (tga, dest, LCT_CONST, Pmode, 1, r3, Pmode);
6557 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6558 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
6559 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
6560 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
6561 else if (DEFAULT_ABI == ABI_V4)
6562 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
6563 else
6564 gcc_unreachable ();
6565 call_insn = last_call_insn ();
6566 PATTERN (call_insn) = insn;
6567 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
6568 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
6569 pic_offset_table_rtx);
6571 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
6573 r3 = gen_rtx_REG (Pmode, 3);
6574 tga = rs6000_tls_get_addr ();
6575 tmp1 = gen_reg_rtx (Pmode);
6576 emit_library_call_value (tga, tmp1, LCT_CONST, Pmode, 1, r3, Pmode);
6578 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6579 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
6580 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
6581 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
6582 else if (DEFAULT_ABI == ABI_V4)
6583 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
6584 else
6585 gcc_unreachable ();
6586 call_insn = last_call_insn ();
6587 PATTERN (call_insn) = insn;
6588 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
6589 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
6590 pic_offset_table_rtx);
6592 if (rs6000_tls_size == 16)
6594 if (TARGET_64BIT)
6595 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
6596 else
6597 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
6599 else if (rs6000_tls_size == 32)
6601 tmp2 = gen_reg_rtx (Pmode);
6602 if (TARGET_64BIT)
6603 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
6604 else
6605 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
6606 emit_insn (insn);
6607 if (TARGET_64BIT)
6608 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
6609 else
6610 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
6612 else
6614 tmp2 = gen_reg_rtx (Pmode);
6615 if (TARGET_64BIT)
6616 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
6617 else
6618 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
6619 emit_insn (insn);
6620 insn = gen_rtx_SET (Pmode, dest,
6621 gen_rtx_PLUS (Pmode, tmp2, tmp1));
6623 emit_insn (insn);
6625 else
6627 /* IE, or 64-bit offset LE. */
6628 tmp2 = gen_reg_rtx (Pmode);
6629 if (TARGET_64BIT)
6630 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
6631 else
6632 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
6633 emit_insn (insn);
6634 if (TARGET_64BIT)
6635 insn = gen_tls_tls_64 (dest, tmp2, addr);
6636 else
6637 insn = gen_tls_tls_32 (dest, tmp2, addr);
6638 emit_insn (insn);
6642 return dest;
6645 /* Return 1 if X contains a thread-local symbol. */
6647 bool
6648 rs6000_tls_referenced_p (rtx x)
6650 if (! TARGET_HAVE_TLS)
6651 return false;
6653 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
6656 /* Return 1 if *X is a thread-local symbol. This is the same as
6657 rs6000_tls_symbol_ref except for the type of the unused argument. */
6659 static int
6660 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
6662 return RS6000_SYMBOL_REF_TLS_P (*x);
6665 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
6666 replace the input X, or the original X if no replacement is called for.
6667 The output parameter *WIN is 1 if the calling macro should goto WIN,
6668 0 if it should not.
6670 For RS/6000, we wish to handle large displacements off a base
6671 register by splitting the addend across an addiu/addis and the mem insn.
6672 This cuts number of extra insns needed from 3 to 1.
6674 On Darwin, we use this to generate code for floating point constants.
6675 A movsf_low is generated so we wind up with 2 instructions rather than 3.
6676 The Darwin code is inside #if TARGET_MACHO because only then are the
6677 machopic_* functions defined. */
6678 static rtx
6679 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
6680 int opnum, int type,
6681 int ind_levels ATTRIBUTE_UNUSED, int *win)
6683 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6685 /* Nasty hack for vsx_splat_V2DF/V2DI load from mem, which takes a
6686 DFmode/DImode MEM. */
6687 if (reg_offset_p
6688 && opnum == 1
6689 && ((mode == DFmode && recog_data.operand_mode[0] == V2DFmode)
6690 || (mode == DImode && recog_data.operand_mode[0] == V2DImode)))
6691 reg_offset_p = false;
6693 /* We must recognize output that we have already generated ourselves. */
6694 if (GET_CODE (x) == PLUS
6695 && GET_CODE (XEXP (x, 0)) == PLUS
6696 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6697 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6698 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6700 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6701 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6702 opnum, (enum reload_type)type);
6703 *win = 1;
6704 return x;
6707 /* Likewise for (lo_sum (high ...) ...) output we have generated. */
6708 if (GET_CODE (x) == LO_SUM
6709 && GET_CODE (XEXP (x, 0)) == HIGH)
6711 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6712 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6713 opnum, (enum reload_type)type);
6714 *win = 1;
6715 return x;
6718 #if TARGET_MACHO
6719 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
6720 && GET_CODE (x) == LO_SUM
6721 && GET_CODE (XEXP (x, 0)) == PLUS
6722 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
6723 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6724 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
6725 && machopic_operand_p (XEXP (x, 1)))
6727 /* Result of previous invocation of this function on Darwin
6728 floating point constant. */
6729 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6730 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6731 opnum, (enum reload_type)type);
6732 *win = 1;
6733 return x;
6735 #endif
6737 if (TARGET_CMODEL != CMODEL_SMALL
6738 && GET_CODE (x) == LO_SUM
6739 && GET_CODE (XEXP (x, 0)) == PLUS
6740 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6741 && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER
6742 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6743 && GET_CODE (XEXP (x, 1)) == CONST
6744 && GET_CODE (XEXP (XEXP (x, 1), 0)) == UNSPEC
6745 && XINT (XEXP (XEXP (x, 1), 0), 1) == UNSPEC_TOCREL
6746 && rtx_equal_p (XEXP (XEXP (XEXP (x, 0), 1), 0), XEXP (x, 1)))
6748 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6749 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6750 opnum, (enum reload_type) type);
6751 *win = 1;
6752 return x;
6755 /* Force ld/std non-word aligned offset into base register by wrapping
6756 in offset 0. */
6757 if (GET_CODE (x) == PLUS
6758 && GET_CODE (XEXP (x, 0)) == REG
6759 && REGNO (XEXP (x, 0)) < 32
6760 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6761 && GET_CODE (XEXP (x, 1)) == CONST_INT
6762 && reg_offset_p
6763 && (INTVAL (XEXP (x, 1)) & 3) != 0
6764 && VECTOR_MEM_NONE_P (mode)
6765 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
6766 && TARGET_POWERPC64)
6768 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
6769 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6770 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6771 opnum, (enum reload_type) type);
6772 *win = 1;
6773 return x;
6776 if (GET_CODE (x) == PLUS
6777 && GET_CODE (XEXP (x, 0)) == REG
6778 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
6779 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6780 && GET_CODE (XEXP (x, 1)) == CONST_INT
6781 && reg_offset_p
6782 && !SPE_VECTOR_MODE (mode)
6783 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6784 || mode == DDmode || mode == TDmode
6785 || mode == DImode))
6786 && VECTOR_MEM_NONE_P (mode))
6788 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
6789 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
6790 HOST_WIDE_INT high
6791 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
6793 /* Check for 32-bit overflow. */
6794 if (high + low != val)
6796 *win = 0;
6797 return x;
6800 /* Reload the high part into a base reg; leave the low part
6801 in the mem directly. */
6803 x = gen_rtx_PLUS (GET_MODE (x),
6804 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
6805 GEN_INT (high)),
6806 GEN_INT (low));
6808 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6809 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6810 opnum, (enum reload_type)type);
6811 *win = 1;
6812 return x;
6815 if (GET_CODE (x) == SYMBOL_REF
6816 && reg_offset_p
6817 && VECTOR_MEM_NONE_P (mode)
6818 && !SPE_VECTOR_MODE (mode)
6819 #if TARGET_MACHO
6820 && DEFAULT_ABI == ABI_DARWIN
6821 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
6822 #else
6823 && DEFAULT_ABI == ABI_V4
6824 && !flag_pic
6825 #endif
6826 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
6827 The same goes for DImode without 64-bit gprs and DFmode and DDmode
6828 without fprs. */
6829 && mode != TFmode
6830 && mode != TDmode
6831 && (mode != DImode || TARGET_POWERPC64)
6832 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
6833 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
6835 #if TARGET_MACHO
6836 if (flag_pic)
6838 rtx offset = machopic_gen_offset (x);
6839 x = gen_rtx_LO_SUM (GET_MODE (x),
6840 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
6841 gen_rtx_HIGH (Pmode, offset)), offset);
6843 else
6844 #endif
6845 x = gen_rtx_LO_SUM (GET_MODE (x),
6846 gen_rtx_HIGH (Pmode, x), x);
6848 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6849 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6850 opnum, (enum reload_type)type);
6851 *win = 1;
6852 return x;
6855 /* Reload an offset address wrapped by an AND that represents the
6856 masking of the lower bits. Strip the outer AND and let reload
6857 convert the offset address into an indirect address. For VSX,
6858 force reload to create the address with an AND in a separate
6859 register, because we can't guarantee an altivec register will
6860 be used. */
6861 if (VECTOR_MEM_ALTIVEC_P (mode)
6862 && GET_CODE (x) == AND
6863 && GET_CODE (XEXP (x, 0)) == PLUS
6864 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6865 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6866 && GET_CODE (XEXP (x, 1)) == CONST_INT
6867 && INTVAL (XEXP (x, 1)) == -16)
6869 x = XEXP (x, 0);
6870 *win = 1;
6871 return x;
6874 if (TARGET_TOC
6875 && reg_offset_p
6876 && GET_CODE (x) == SYMBOL_REF
6877 && constant_pool_expr_p (x)
6878 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
6880 x = create_TOC_reference (x, NULL_RTX);
6881 if (TARGET_CMODEL != CMODEL_SMALL)
6882 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6883 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6884 opnum, (enum reload_type) type);
6885 *win = 1;
6886 return x;
6888 *win = 0;
6889 return x;
6892 /* Debug version of rs6000_legitimize_reload_address. */
6893 static rtx
6894 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
6895 int opnum, int type,
6896 int ind_levels, int *win)
6898 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
6899 ind_levels, win);
6900 fprintf (stderr,
6901 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
6902 "type = %d, ind_levels = %d, win = %d, original addr:\n",
6903 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
6904 debug_rtx (x);
6906 if (x == ret)
6907 fprintf (stderr, "Same address returned\n");
6908 else if (!ret)
6909 fprintf (stderr, "NULL returned\n");
6910 else
6912 fprintf (stderr, "New address:\n");
6913 debug_rtx (ret);
6916 return ret;
6919 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
6920 that is a valid memory address for an instruction.
6921 The MODE argument is the machine mode for the MEM expression
6922 that wants to use this address.
6924 On the RS/6000, there are four valid address: a SYMBOL_REF that
6925 refers to a constant pool entry of an address (or the sum of it
6926 plus a constant), a short (16-bit signed) constant plus a register,
6927 the sum of two registers, or a register indirect, possibly with an
6928 auto-increment. For DFmode, DDmode and DImode with a constant plus
6929 register, we must ensure that both words are addressable or PowerPC64
6930 with offset word aligned.
6932 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
6933 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
6934 because adjacent memory cells are accessed by adding word-sized offsets
6935 during assembly output. */
6936 bool
6937 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
6939 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6941 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
6942 if (VECTOR_MEM_ALTIVEC_P (mode)
6943 && GET_CODE (x) == AND
6944 && GET_CODE (XEXP (x, 1)) == CONST_INT
6945 && INTVAL (XEXP (x, 1)) == -16)
6946 x = XEXP (x, 0);
6948 if (RS6000_SYMBOL_REF_TLS_P (x))
6949 return 0;
6950 if (legitimate_indirect_address_p (x, reg_ok_strict))
6951 return 1;
6952 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
6953 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6954 && !SPE_VECTOR_MODE (mode)
6955 && mode != TFmode
6956 && mode != TDmode
6957 /* Restrict addressing for DI because of our SUBREG hackery. */
6958 && !(TARGET_E500_DOUBLE
6959 && (mode == DFmode || mode == DDmode || mode == DImode))
6960 && TARGET_UPDATE
6961 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
6962 return 1;
6963 if (virtual_stack_registers_memory_p (x))
6964 return 1;
6965 if (reg_offset_p && legitimate_small_data_p (mode, x))
6966 return 1;
6967 if (reg_offset_p
6968 && legitimate_constant_pool_address_p (x, mode, reg_ok_strict))
6969 return 1;
6970 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
6971 if (! reg_ok_strict
6972 && reg_offset_p
6973 && GET_CODE (x) == PLUS
6974 && GET_CODE (XEXP (x, 0)) == REG
6975 && (XEXP (x, 0) == virtual_stack_vars_rtx
6976 || XEXP (x, 0) == arg_pointer_rtx)
6977 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6978 return 1;
6979 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
6980 return 1;
6981 if (mode != TImode
6982 && mode != TFmode
6983 && mode != TDmode
6984 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6985 || TARGET_POWERPC64
6986 || (mode != DFmode && mode != DDmode)
6987 || (TARGET_E500_DOUBLE && mode != DDmode))
6988 && (TARGET_POWERPC64 || mode != DImode)
6989 && !avoiding_indexed_address_p (mode)
6990 && legitimate_indexed_address_p (x, reg_ok_strict))
6991 return 1;
6992 if (GET_CODE (x) == PRE_MODIFY
6993 && mode != TImode
6994 && mode != TFmode
6995 && mode != TDmode
6996 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6997 || TARGET_POWERPC64
6998 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
6999 && (TARGET_POWERPC64 || mode != DImode)
7000 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
7001 && !SPE_VECTOR_MODE (mode)
7002 /* Restrict addressing for DI because of our SUBREG hackery. */
7003 && !(TARGET_E500_DOUBLE
7004 && (mode == DFmode || mode == DDmode || mode == DImode))
7005 && TARGET_UPDATE
7006 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
7007 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
7008 || (!avoiding_indexed_address_p (mode)
7009 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
7010 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
7011 return 1;
7012 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
7013 return 1;
7014 return 0;
7017 /* Debug version of rs6000_legitimate_address_p. */
7018 static bool
7019 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
7020 bool reg_ok_strict)
7022 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
7023 fprintf (stderr,
7024 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
7025 "strict = %d, code = %s\n",
7026 ret ? "true" : "false",
7027 GET_MODE_NAME (mode),
7028 reg_ok_strict,
7029 GET_RTX_NAME (GET_CODE (x)));
7030 debug_rtx (x);
7032 return ret;
7035 /* Implement TARGET_MODE_DEPENDENT_ADDRESS_P. */
7037 static bool
7038 rs6000_mode_dependent_address_p (const_rtx addr)
7040 return rs6000_mode_dependent_address_ptr (addr);
7043 /* Go to LABEL if ADDR (a legitimate address expression)
7044 has an effect that depends on the machine mode it is used for.
7046 On the RS/6000 this is true of all integral offsets (since AltiVec
7047 and VSX modes don't allow them) or is a pre-increment or decrement.
7049 ??? Except that due to conceptual problems in offsettable_address_p
7050 we can't really report the problems of integral offsets. So leave
7051 this assuming that the adjustable offset must be valid for the
7052 sub-words of a TFmode operand, which is what we had before. */
7054 static bool
7055 rs6000_mode_dependent_address (const_rtx addr)
7057 switch (GET_CODE (addr))
7059 case PLUS:
7060 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
7061 is considered a legitimate address before reload, so there
7062 are no offset restrictions in that case. Note that this
7063 condition is safe in strict mode because any address involving
7064 virtual_stack_vars_rtx or arg_pointer_rtx would already have
7065 been rejected as illegitimate. */
7066 if (XEXP (addr, 0) != virtual_stack_vars_rtx
7067 && XEXP (addr, 0) != arg_pointer_rtx
7068 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
7070 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
7071 return val + 12 + 0x8000 >= 0x10000;
7073 break;
7075 case LO_SUM:
7076 /* Anything in the constant pool is sufficiently aligned that
7077 all bytes have the same high part address. */
7078 return !legitimate_constant_pool_address_p (addr, QImode, false);
7080 /* Auto-increment cases are now treated generically in recog.c. */
7081 case PRE_MODIFY:
7082 return TARGET_UPDATE;
7084 /* AND is only allowed in Altivec loads. */
7085 case AND:
7086 return true;
7088 default:
7089 break;
7092 return false;
7095 /* Debug version of rs6000_mode_dependent_address. */
7096 static bool
7097 rs6000_debug_mode_dependent_address (const_rtx addr)
7099 bool ret = rs6000_mode_dependent_address (addr);
7101 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
7102 ret ? "true" : "false");
7103 debug_rtx (addr);
7105 return ret;
7108 /* Implement FIND_BASE_TERM. */
7111 rs6000_find_base_term (rtx op)
7113 rtx base, offset;
7115 split_const (op, &base, &offset);
7116 if (GET_CODE (base) == UNSPEC)
7117 switch (XINT (base, 1))
7119 case UNSPEC_TOCREL:
7120 case UNSPEC_MACHOPIC_OFFSET:
7121 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
7122 for aliasing purposes. */
7123 return XVECEXP (base, 0, 0);
7126 return op;
7129 /* More elaborate version of recog's offsettable_memref_p predicate
7130 that works around the ??? note of rs6000_mode_dependent_address.
7131 In particular it accepts
7133 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
7135 in 32-bit mode, that the recog predicate rejects. */
7137 bool
7138 rs6000_offsettable_memref_p (rtx op)
7140 if (!MEM_P (op))
7141 return false;
7143 /* First mimic offsettable_memref_p. */
7144 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
7145 return true;
7147 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
7148 the latter predicate knows nothing about the mode of the memory
7149 reference and, therefore, assumes that it is the largest supported
7150 mode (TFmode). As a consequence, legitimate offsettable memory
7151 references are rejected. rs6000_legitimate_offset_address_p contains
7152 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
7153 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
7156 /* Change register usage conditional on target flags. */
7157 static void
7158 rs6000_conditional_register_usage (void)
7160 int i;
7162 if (TARGET_DEBUG_TARGET)
7163 fprintf (stderr, "rs6000_conditional_register_usage called\n");
7165 /* Set MQ register fixed (already call_used) if not POWER
7166 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
7167 be allocated. */
7168 if (! TARGET_POWER)
7169 fixed_regs[64] = 1;
7171 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
7172 if (TARGET_64BIT)
7173 fixed_regs[13] = call_used_regs[13]
7174 = call_really_used_regs[13] = 1;
7176 /* Conditionally disable FPRs. */
7177 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
7178 for (i = 32; i < 64; i++)
7179 fixed_regs[i] = call_used_regs[i]
7180 = call_really_used_regs[i] = 1;
7182 /* The TOC register is not killed across calls in a way that is
7183 visible to the compiler. */
7184 if (DEFAULT_ABI == ABI_AIX)
7185 call_really_used_regs[2] = 0;
7187 if (DEFAULT_ABI == ABI_V4
7188 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
7189 && flag_pic == 2)
7190 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
7192 if (DEFAULT_ABI == ABI_V4
7193 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
7194 && flag_pic == 1)
7195 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7196 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7197 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
7199 if (DEFAULT_ABI == ABI_DARWIN
7200 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
7201 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7202 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7203 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
7205 if (TARGET_TOC && TARGET_MINIMAL_TOC)
7206 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7207 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
7209 if (TARGET_SPE)
7211 global_regs[SPEFSCR_REGNO] = 1;
7212 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
7213 registers in prologues and epilogues. We no longer use r14
7214 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
7215 pool for link-compatibility with older versions of GCC. Once
7216 "old" code has died out, we can return r14 to the allocation
7217 pool. */
7218 fixed_regs[14]
7219 = call_used_regs[14]
7220 = call_really_used_regs[14] = 1;
7223 if (!TARGET_ALTIVEC && !TARGET_VSX)
7225 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
7226 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
7227 call_really_used_regs[VRSAVE_REGNO] = 1;
7230 if (TARGET_ALTIVEC || TARGET_VSX)
7231 global_regs[VSCR_REGNO] = 1;
7233 if (TARGET_ALTIVEC_ABI)
7235 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
7236 call_used_regs[i] = call_really_used_regs[i] = 1;
7238 /* AIX reserves VR20:31 in non-extended ABI mode. */
7239 if (TARGET_XCOFF)
7240 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
7241 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
7245 /* Try to output insns to set TARGET equal to the constant C if it can
7246 be done in less than N insns. Do all computations in MODE.
7247 Returns the place where the output has been placed if it can be
7248 done and the insns have been emitted. If it would take more than N
7249 insns, zero is returned and no insns and emitted. */
7252 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
7253 rtx source, int n ATTRIBUTE_UNUSED)
7255 rtx result, insn, set;
7256 HOST_WIDE_INT c0, c1;
7258 switch (mode)
7260 case QImode:
7261 case HImode:
7262 if (dest == NULL)
7263 dest = gen_reg_rtx (mode);
7264 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
7265 return dest;
7267 case SImode:
7268 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
7270 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
7271 GEN_INT (INTVAL (source)
7272 & (~ (HOST_WIDE_INT) 0xffff))));
7273 emit_insn (gen_rtx_SET (VOIDmode, dest,
7274 gen_rtx_IOR (SImode, copy_rtx (result),
7275 GEN_INT (INTVAL (source) & 0xffff))));
7276 result = dest;
7277 break;
7279 case DImode:
7280 switch (GET_CODE (source))
7282 case CONST_INT:
7283 c0 = INTVAL (source);
7284 c1 = -(c0 < 0);
7285 break;
7287 case CONST_DOUBLE:
7288 #if HOST_BITS_PER_WIDE_INT >= 64
7289 c0 = CONST_DOUBLE_LOW (source);
7290 c1 = -(c0 < 0);
7291 #else
7292 c0 = CONST_DOUBLE_LOW (source);
7293 c1 = CONST_DOUBLE_HIGH (source);
7294 #endif
7295 break;
7297 default:
7298 gcc_unreachable ();
7301 result = rs6000_emit_set_long_const (dest, c0, c1);
7302 break;
7304 default:
7305 gcc_unreachable ();
7308 insn = get_last_insn ();
7309 set = single_set (insn);
7310 if (! CONSTANT_P (SET_SRC (set)))
7311 set_unique_reg_note (insn, REG_EQUAL, source);
7313 return result;
7316 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
7317 fall back to a straight forward decomposition. We do this to avoid
7318 exponential run times encountered when looking for longer sequences
7319 with rs6000_emit_set_const. */
7320 static rtx
7321 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
7323 if (!TARGET_POWERPC64)
7325 rtx operand1, operand2;
7327 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
7328 DImode);
7329 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
7330 DImode);
7331 emit_move_insn (operand1, GEN_INT (c1));
7332 emit_move_insn (operand2, GEN_INT (c2));
7334 else
7336 HOST_WIDE_INT ud1, ud2, ud3, ud4;
7338 ud1 = c1 & 0xffff;
7339 ud2 = (c1 & 0xffff0000) >> 16;
7340 #if HOST_BITS_PER_WIDE_INT >= 64
7341 c2 = c1 >> 32;
7342 #endif
7343 ud3 = c2 & 0xffff;
7344 ud4 = (c2 & 0xffff0000) >> 16;
7346 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
7347 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
7349 if (ud1 & 0x8000)
7350 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
7351 else
7352 emit_move_insn (dest, GEN_INT (ud1));
7355 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
7356 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
7358 if (ud2 & 0x8000)
7359 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
7360 - 0x80000000));
7361 else
7362 emit_move_insn (dest, GEN_INT (ud2 << 16));
7363 if (ud1 != 0)
7364 emit_move_insn (copy_rtx (dest),
7365 gen_rtx_IOR (DImode, copy_rtx (dest),
7366 GEN_INT (ud1)));
7368 else if (ud3 == 0 && ud4 == 0)
7370 gcc_assert (ud2 & 0x8000);
7371 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
7372 - 0x80000000));
7373 if (ud1 != 0)
7374 emit_move_insn (copy_rtx (dest),
7375 gen_rtx_IOR (DImode, copy_rtx (dest),
7376 GEN_INT (ud1)));
7377 emit_move_insn (copy_rtx (dest),
7378 gen_rtx_ZERO_EXTEND (DImode,
7379 gen_lowpart (SImode,
7380 copy_rtx (dest))));
7382 else if ((ud4 == 0xffff && (ud3 & 0x8000))
7383 || (ud4 == 0 && ! (ud3 & 0x8000)))
7385 if (ud3 & 0x8000)
7386 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
7387 - 0x80000000));
7388 else
7389 emit_move_insn (dest, GEN_INT (ud3 << 16));
7391 if (ud2 != 0)
7392 emit_move_insn (copy_rtx (dest),
7393 gen_rtx_IOR (DImode, copy_rtx (dest),
7394 GEN_INT (ud2)));
7395 emit_move_insn (copy_rtx (dest),
7396 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
7397 GEN_INT (16)));
7398 if (ud1 != 0)
7399 emit_move_insn (copy_rtx (dest),
7400 gen_rtx_IOR (DImode, copy_rtx (dest),
7401 GEN_INT (ud1)));
7403 else
7405 if (ud4 & 0x8000)
7406 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
7407 - 0x80000000));
7408 else
7409 emit_move_insn (dest, GEN_INT (ud4 << 16));
7411 if (ud3 != 0)
7412 emit_move_insn (copy_rtx (dest),
7413 gen_rtx_IOR (DImode, copy_rtx (dest),
7414 GEN_INT (ud3)));
7416 emit_move_insn (copy_rtx (dest),
7417 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
7418 GEN_INT (32)));
7419 if (ud2 != 0)
7420 emit_move_insn (copy_rtx (dest),
7421 gen_rtx_IOR (DImode, copy_rtx (dest),
7422 GEN_INT (ud2 << 16)));
7423 if (ud1 != 0)
7424 emit_move_insn (copy_rtx (dest),
7425 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
7428 return dest;
7431 /* Helper for the following. Get rid of [r+r] memory refs
7432 in cases where it won't work (TImode, TFmode, TDmode). */
7434 static void
7435 rs6000_eliminate_indexed_memrefs (rtx operands[2])
7437 if (reload_in_progress)
7438 return;
7440 if (GET_CODE (operands[0]) == MEM
7441 && GET_CODE (XEXP (operands[0], 0)) != REG
7442 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0),
7443 GET_MODE (operands[0]), false))
7444 operands[0]
7445 = replace_equiv_address (operands[0],
7446 copy_addr_to_reg (XEXP (operands[0], 0)));
7448 if (GET_CODE (operands[1]) == MEM
7449 && GET_CODE (XEXP (operands[1], 0)) != REG
7450 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0),
7451 GET_MODE (operands[1]), false))
7452 operands[1]
7453 = replace_equiv_address (operands[1],
7454 copy_addr_to_reg (XEXP (operands[1], 0)));
7457 /* Emit a move from SOURCE to DEST in mode MODE. */
7458 void
7459 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
7461 rtx operands[2];
7462 operands[0] = dest;
7463 operands[1] = source;
7465 if (TARGET_DEBUG_ADDR)
7467 fprintf (stderr,
7468 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
7469 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
7470 GET_MODE_NAME (mode),
7471 reload_in_progress,
7472 reload_completed,
7473 can_create_pseudo_p ());
7474 debug_rtx (dest);
7475 fprintf (stderr, "source:\n");
7476 debug_rtx (source);
7479 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
7480 if (GET_CODE (operands[1]) == CONST_DOUBLE
7481 && ! FLOAT_MODE_P (mode)
7482 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
7484 /* FIXME. This should never happen. */
7485 /* Since it seems that it does, do the safe thing and convert
7486 to a CONST_INT. */
7487 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
7489 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
7490 || FLOAT_MODE_P (mode)
7491 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
7492 || CONST_DOUBLE_LOW (operands[1]) < 0)
7493 && (CONST_DOUBLE_HIGH (operands[1]) != -1
7494 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
7496 /* Check if GCC is setting up a block move that will end up using FP
7497 registers as temporaries. We must make sure this is acceptable. */
7498 if (GET_CODE (operands[0]) == MEM
7499 && GET_CODE (operands[1]) == MEM
7500 && mode == DImode
7501 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
7502 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
7503 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
7504 ? 32 : MEM_ALIGN (operands[0])))
7505 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
7506 ? 32
7507 : MEM_ALIGN (operands[1]))))
7508 && ! MEM_VOLATILE_P (operands [0])
7509 && ! MEM_VOLATILE_P (operands [1]))
7511 emit_move_insn (adjust_address (operands[0], SImode, 0),
7512 adjust_address (operands[1], SImode, 0));
7513 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
7514 adjust_address (copy_rtx (operands[1]), SImode, 4));
7515 return;
7518 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
7519 && !gpc_reg_operand (operands[1], mode))
7520 operands[1] = force_reg (mode, operands[1]);
7522 if (mode == SFmode && ! TARGET_POWERPC
7523 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7524 && GET_CODE (operands[0]) == MEM)
7526 int regnum;
7528 if (reload_in_progress || reload_completed)
7529 regnum = true_regnum (operands[1]);
7530 else if (GET_CODE (operands[1]) == REG)
7531 regnum = REGNO (operands[1]);
7532 else
7533 regnum = -1;
7535 /* If operands[1] is a register, on POWER it may have
7536 double-precision data in it, so truncate it to single
7537 precision. */
7538 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
7540 rtx newreg;
7541 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
7542 : gen_reg_rtx (mode));
7543 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
7544 operands[1] = newreg;
7548 /* Recognize the case where operand[1] is a reference to thread-local
7549 data and load its address to a register. */
7550 if (rs6000_tls_referenced_p (operands[1]))
7552 enum tls_model model;
7553 rtx tmp = operands[1];
7554 rtx addend = NULL;
7556 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
7558 addend = XEXP (XEXP (tmp, 0), 1);
7559 tmp = XEXP (XEXP (tmp, 0), 0);
7562 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
7563 model = SYMBOL_REF_TLS_MODEL (tmp);
7564 gcc_assert (model != 0);
7566 tmp = rs6000_legitimize_tls_address (tmp, model);
7567 if (addend)
7569 tmp = gen_rtx_PLUS (mode, tmp, addend);
7570 tmp = force_operand (tmp, operands[0]);
7572 operands[1] = tmp;
7575 /* Handle the case where reload calls us with an invalid address. */
7576 if (reload_in_progress && mode == Pmode
7577 && (! general_operand (operands[1], mode)
7578 || ! nonimmediate_operand (operands[0], mode)))
7579 goto emit_set;
7581 /* 128-bit constant floating-point values on Darwin should really be
7582 loaded as two parts. */
7583 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
7584 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
7586 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
7587 know how to get a DFmode SUBREG of a TFmode. */
7588 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
7589 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
7590 simplify_gen_subreg (imode, operands[1], mode, 0),
7591 imode);
7592 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
7593 GET_MODE_SIZE (imode)),
7594 simplify_gen_subreg (imode, operands[1], mode,
7595 GET_MODE_SIZE (imode)),
7596 imode);
7597 return;
7600 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
7601 cfun->machine->sdmode_stack_slot =
7602 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
7604 if (reload_in_progress
7605 && mode == SDmode
7606 && MEM_P (operands[0])
7607 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
7608 && REG_P (operands[1]))
7610 if (FP_REGNO_P (REGNO (operands[1])))
7612 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
7613 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7614 emit_insn (gen_movsd_store (mem, operands[1]));
7616 else if (INT_REGNO_P (REGNO (operands[1])))
7618 rtx mem = adjust_address_nv (operands[0], mode, 4);
7619 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7620 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
7622 else
7623 gcc_unreachable();
7624 return;
7626 if (reload_in_progress
7627 && mode == SDmode
7628 && REG_P (operands[0])
7629 && MEM_P (operands[1])
7630 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
7632 if (FP_REGNO_P (REGNO (operands[0])))
7634 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
7635 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7636 emit_insn (gen_movsd_load (operands[0], mem));
7638 else if (INT_REGNO_P (REGNO (operands[0])))
7640 rtx mem = adjust_address_nv (operands[1], mode, 4);
7641 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7642 emit_insn (gen_movsd_hardfloat (operands[0], mem));
7644 else
7645 gcc_unreachable();
7646 return;
7649 /* FIXME: In the long term, this switch statement should go away
7650 and be replaced by a sequence of tests based on things like
7651 mode == Pmode. */
7652 switch (mode)
7654 case HImode:
7655 case QImode:
7656 if (CONSTANT_P (operands[1])
7657 && GET_CODE (operands[1]) != CONST_INT)
7658 operands[1] = force_const_mem (mode, operands[1]);
7659 break;
7661 case TFmode:
7662 case TDmode:
7663 rs6000_eliminate_indexed_memrefs (operands);
7664 /* fall through */
7666 case DFmode:
7667 case DDmode:
7668 case SFmode:
7669 case SDmode:
7670 if (CONSTANT_P (operands[1])
7671 && ! easy_fp_constant (operands[1], mode))
7672 operands[1] = force_const_mem (mode, operands[1]);
7673 break;
7675 case V16QImode:
7676 case V8HImode:
7677 case V4SFmode:
7678 case V4SImode:
7679 case V4HImode:
7680 case V2SFmode:
7681 case V2SImode:
7682 case V1DImode:
7683 case V2DFmode:
7684 case V2DImode:
7685 if (CONSTANT_P (operands[1])
7686 && !easy_vector_constant (operands[1], mode))
7687 operands[1] = force_const_mem (mode, operands[1]);
7688 break;
7690 case SImode:
7691 case DImode:
7692 /* Use default pattern for address of ELF small data */
7693 if (TARGET_ELF
7694 && mode == Pmode
7695 && DEFAULT_ABI == ABI_V4
7696 && (GET_CODE (operands[1]) == SYMBOL_REF
7697 || GET_CODE (operands[1]) == CONST)
7698 && small_data_operand (operands[1], mode))
7700 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7701 return;
7704 if (DEFAULT_ABI == ABI_V4
7705 && mode == Pmode && mode == SImode
7706 && flag_pic == 1 && got_operand (operands[1], mode))
7708 emit_insn (gen_movsi_got (operands[0], operands[1]));
7709 return;
7712 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
7713 && TARGET_NO_TOC
7714 && ! flag_pic
7715 && mode == Pmode
7716 && CONSTANT_P (operands[1])
7717 && GET_CODE (operands[1]) != HIGH
7718 && GET_CODE (operands[1]) != CONST_INT)
7720 rtx target = (!can_create_pseudo_p ()
7721 ? operands[0]
7722 : gen_reg_rtx (mode));
7724 /* If this is a function address on -mcall-aixdesc,
7725 convert it to the address of the descriptor. */
7726 if (DEFAULT_ABI == ABI_AIX
7727 && GET_CODE (operands[1]) == SYMBOL_REF
7728 && XSTR (operands[1], 0)[0] == '.')
7730 const char *name = XSTR (operands[1], 0);
7731 rtx new_ref;
7732 while (*name == '.')
7733 name++;
7734 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
7735 CONSTANT_POOL_ADDRESS_P (new_ref)
7736 = CONSTANT_POOL_ADDRESS_P (operands[1]);
7737 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
7738 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
7739 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
7740 operands[1] = new_ref;
7743 if (DEFAULT_ABI == ABI_DARWIN)
7745 #if TARGET_MACHO
7746 if (MACHO_DYNAMIC_NO_PIC_P)
7748 /* Take care of any required data indirection. */
7749 operands[1] = rs6000_machopic_legitimize_pic_address (
7750 operands[1], mode, operands[0]);
7751 if (operands[0] != operands[1])
7752 emit_insn (gen_rtx_SET (VOIDmode,
7753 operands[0], operands[1]));
7754 return;
7756 #endif
7757 emit_insn (gen_macho_high (target, operands[1]));
7758 emit_insn (gen_macho_low (operands[0], target, operands[1]));
7759 return;
7762 emit_insn (gen_elf_high (target, operands[1]));
7763 emit_insn (gen_elf_low (operands[0], target, operands[1]));
7764 return;
7767 /* If this is a SYMBOL_REF that refers to a constant pool entry,
7768 and we have put it in the TOC, we just need to make a TOC-relative
7769 reference to it. */
7770 if ((TARGET_TOC
7771 && GET_CODE (operands[1]) == SYMBOL_REF
7772 && constant_pool_expr_p (operands[1])
7773 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
7774 get_pool_mode (operands[1])))
7775 || (TARGET_CMODEL == CMODEL_MEDIUM
7776 && GET_CODE (operands[1]) == SYMBOL_REF
7777 && !CONSTANT_POOL_ADDRESS_P (operands[1])
7778 && SYMBOL_REF_LOCAL_P (operands[1])))
7780 rtx reg = NULL_RTX;
7781 if (TARGET_CMODEL != CMODEL_SMALL)
7783 if (can_create_pseudo_p ())
7784 reg = gen_reg_rtx (Pmode);
7785 else
7786 reg = operands[0];
7788 operands[1] = create_TOC_reference (operands[1], reg);
7790 else if (mode == Pmode
7791 && CONSTANT_P (operands[1])
7792 && ((GET_CODE (operands[1]) != CONST_INT
7793 && ! easy_fp_constant (operands[1], mode))
7794 || (GET_CODE (operands[1]) == CONST_INT
7795 && (num_insns_constant (operands[1], mode)
7796 > (TARGET_CMODEL != CMODEL_SMALL ? 3 : 2)))
7797 || (GET_CODE (operands[0]) == REG
7798 && FP_REGNO_P (REGNO (operands[0]))))
7799 && GET_CODE (operands[1]) != HIGH
7800 && ! legitimate_constant_pool_address_p (operands[1], mode,
7801 false)
7802 && ! toc_relative_expr_p (operands[1])
7803 && (TARGET_CMODEL == CMODEL_SMALL
7804 || can_create_pseudo_p ()
7805 || (REG_P (operands[0])
7806 && INT_REG_OK_FOR_BASE_P (operands[0], true))))
7809 #if TARGET_MACHO
7810 /* Darwin uses a special PIC legitimizer. */
7811 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
7813 operands[1] =
7814 rs6000_machopic_legitimize_pic_address (operands[1], mode,
7815 operands[0]);
7816 if (operands[0] != operands[1])
7817 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7818 return;
7820 #endif
7822 /* If we are to limit the number of things we put in the TOC and
7823 this is a symbol plus a constant we can add in one insn,
7824 just put the symbol in the TOC and add the constant. Don't do
7825 this if reload is in progress. */
7826 if (GET_CODE (operands[1]) == CONST
7827 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
7828 && GET_CODE (XEXP (operands[1], 0)) == PLUS
7829 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
7830 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
7831 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
7832 && ! side_effects_p (operands[0]))
7834 rtx sym =
7835 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
7836 rtx other = XEXP (XEXP (operands[1], 0), 1);
7838 sym = force_reg (mode, sym);
7839 emit_insn (gen_add3_insn (operands[0], sym, other));
7840 return;
7843 operands[1] = force_const_mem (mode, operands[1]);
7845 if (TARGET_TOC
7846 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7847 && constant_pool_expr_p (XEXP (operands[1], 0))
7848 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
7849 get_pool_constant (XEXP (operands[1], 0)),
7850 get_pool_mode (XEXP (operands[1], 0))))
7852 rtx tocref;
7853 rtx reg = NULL_RTX;
7854 if (TARGET_CMODEL != CMODEL_SMALL)
7856 if (can_create_pseudo_p ())
7857 reg = gen_reg_rtx (Pmode);
7858 else
7859 reg = operands[0];
7861 tocref = create_TOC_reference (XEXP (operands[1], 0), reg);
7862 operands[1] = gen_const_mem (mode, tocref);
7863 set_mem_alias_set (operands[1], get_TOC_alias_set ());
7866 break;
7868 case TImode:
7869 rs6000_eliminate_indexed_memrefs (operands);
7871 if (TARGET_POWER)
7873 emit_insn (gen_rtx_PARALLEL (VOIDmode,
7874 gen_rtvec (2,
7875 gen_rtx_SET (VOIDmode,
7876 operands[0], operands[1]),
7877 gen_rtx_CLOBBER (VOIDmode,
7878 gen_rtx_SCRATCH (SImode)))));
7879 return;
7881 break;
7883 default:
7884 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
7887 /* Above, we may have called force_const_mem which may have returned
7888 an invalid address. If we can, fix this up; otherwise, reload will
7889 have to deal with it. */
7890 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
7891 operands[1] = validize_mem (operands[1]);
7893 emit_set:
7894 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7897 /* Nonzero if we can use a floating-point register to pass this arg. */
7898 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
7899 (SCALAR_FLOAT_MODE_P (MODE) \
7900 && (CUM)->fregno <= FP_ARG_MAX_REG \
7901 && TARGET_HARD_FLOAT && TARGET_FPRS)
7903 /* Nonzero if we can use an AltiVec register to pass this arg. */
7904 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
7905 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
7906 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
7907 && TARGET_ALTIVEC_ABI \
7908 && (NAMED))
7910 /* Return a nonzero value to say to return the function value in
7911 memory, just as large structures are always returned. TYPE will be
7912 the data type of the value, and FNTYPE will be the type of the
7913 function doing the returning, or @code{NULL} for libcalls.
7915 The AIX ABI for the RS/6000 specifies that all structures are
7916 returned in memory. The Darwin ABI does the same.
7918 For the Darwin 64 Bit ABI, a function result can be returned in
7919 registers or in memory, depending on the size of the return data
7920 type. If it is returned in registers, the value occupies the same
7921 registers as it would if it were the first and only function
7922 argument. Otherwise, the function places its result in memory at
7923 the location pointed to by GPR3.
7925 The SVR4 ABI specifies that structures <= 8 bytes are returned in r3/r4,
7926 but a draft put them in memory, and GCC used to implement the draft
7927 instead of the final standard. Therefore, aix_struct_return
7928 controls this instead of DEFAULT_ABI; V.4 targets needing backward
7929 compatibility can change DRAFT_V4_STRUCT_RET to override the
7930 default, and -m switches get the final word. See
7931 rs6000_option_override_internal for more details.
7933 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
7934 long double support is enabled. These values are returned in memory.
7936 int_size_in_bytes returns -1 for variable size objects, which go in
7937 memory always. The cast to unsigned makes -1 > 8. */
7939 static bool
7940 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
7942 /* For the Darwin64 ABI, test if we can fit the return value in regs. */
7943 if (TARGET_MACHO
7944 && rs6000_darwin64_abi
7945 && TREE_CODE (type) == RECORD_TYPE
7946 && int_size_in_bytes (type) > 0)
7948 CUMULATIVE_ARGS valcum;
7949 rtx valret;
7951 valcum.words = 0;
7952 valcum.fregno = FP_ARG_MIN_REG;
7953 valcum.vregno = ALTIVEC_ARG_MIN_REG;
7954 /* Do a trial code generation as if this were going to be passed
7955 as an argument; if any part goes in memory, we return NULL. */
7956 valret = rs6000_darwin64_record_arg (&valcum, type, true, true);
7957 if (valret)
7958 return false;
7959 /* Otherwise fall through to more conventional ABI rules. */
7962 if (AGGREGATE_TYPE_P (type)
7963 && (aix_struct_return
7964 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
7965 return true;
7967 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7968 modes only exist for GCC vector types if -maltivec. */
7969 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
7970 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
7971 return false;
7973 /* Return synthetic vectors in memory. */
7974 if (TREE_CODE (type) == VECTOR_TYPE
7975 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
7977 static bool warned_for_return_big_vectors = false;
7978 if (!warned_for_return_big_vectors)
7980 warning (0, "GCC vector returned by reference: "
7981 "non-standard ABI extension with no compatibility guarantee");
7982 warned_for_return_big_vectors = true;
7984 return true;
7987 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
7988 return true;
7990 return false;
7993 #ifdef HAVE_AS_GNU_ATTRIBUTE
7994 /* Return TRUE if a call to function FNDECL may be one that
7995 potentially affects the function calling ABI of the object file. */
7997 static bool
7998 call_ABI_of_interest (tree fndecl)
8000 if (cgraph_state == CGRAPH_STATE_EXPANSION)
8002 struct cgraph_node *c_node;
8004 /* Libcalls are always interesting. */
8005 if (fndecl == NULL_TREE)
8006 return true;
8008 /* Any call to an external function is interesting. */
8009 if (DECL_EXTERNAL (fndecl))
8010 return true;
8012 /* Interesting functions that we are emitting in this object file. */
8013 c_node = cgraph_node (fndecl);
8014 return !cgraph_only_called_directly_p (c_node);
8016 return false;
8018 #endif
8020 /* Initialize a variable CUM of type CUMULATIVE_ARGS
8021 for a call to a function whose data type is FNTYPE.
8022 For a library call, FNTYPE is 0 and RETURN_MODE the return value mode.
8024 For incoming args we set the number of arguments in the prototype large
8025 so we never return a PARALLEL. */
8027 void
8028 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
8029 rtx libname ATTRIBUTE_UNUSED, int incoming,
8030 int libcall, int n_named_args,
8031 tree fndecl ATTRIBUTE_UNUSED,
8032 enum machine_mode return_mode ATTRIBUTE_UNUSED)
8034 static CUMULATIVE_ARGS zero_cumulative;
8036 *cum = zero_cumulative;
8037 cum->words = 0;
8038 cum->fregno = FP_ARG_MIN_REG;
8039 cum->vregno = ALTIVEC_ARG_MIN_REG;
8040 cum->prototype = (fntype && prototype_p (fntype));
8041 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
8042 ? CALL_LIBCALL : CALL_NORMAL);
8043 cum->sysv_gregno = GP_ARG_MIN_REG;
8044 cum->stdarg = stdarg_p (fntype);
8046 cum->nargs_prototype = 0;
8047 if (incoming || cum->prototype)
8048 cum->nargs_prototype = n_named_args;
8050 /* Check for a longcall attribute. */
8051 if ((!fntype && rs6000_default_long_calls)
8052 || (fntype
8053 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
8054 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
8055 cum->call_cookie |= CALL_LONG;
8057 if (TARGET_DEBUG_ARG)
8059 fprintf (stderr, "\ninit_cumulative_args:");
8060 if (fntype)
8062 tree ret_type = TREE_TYPE (fntype);
8063 fprintf (stderr, " ret code = %s,",
8064 tree_code_name[ (int)TREE_CODE (ret_type) ]);
8067 if (cum->call_cookie & CALL_LONG)
8068 fprintf (stderr, " longcall,");
8070 fprintf (stderr, " proto = %d, nargs = %d\n",
8071 cum->prototype, cum->nargs_prototype);
8074 #ifdef HAVE_AS_GNU_ATTRIBUTE
8075 if (DEFAULT_ABI == ABI_V4)
8077 cum->escapes = call_ABI_of_interest (fndecl);
8078 if (cum->escapes)
8080 tree return_type;
8082 if (fntype)
8084 return_type = TREE_TYPE (fntype);
8085 return_mode = TYPE_MODE (return_type);
8087 else
8088 return_type = lang_hooks.types.type_for_mode (return_mode, 0);
8090 if (return_type != NULL)
8092 if (TREE_CODE (return_type) == RECORD_TYPE
8093 && TYPE_TRANSPARENT_AGGR (return_type))
8095 return_type = TREE_TYPE (first_field (return_type));
8096 return_mode = TYPE_MODE (return_type);
8098 if (AGGREGATE_TYPE_P (return_type)
8099 && ((unsigned HOST_WIDE_INT) int_size_in_bytes (return_type)
8100 <= 8))
8101 rs6000_returns_struct = true;
8103 if (SCALAR_FLOAT_MODE_P (return_mode))
8104 rs6000_passes_float = true;
8105 else if (ALTIVEC_VECTOR_MODE (return_mode)
8106 || VSX_VECTOR_MODE (return_mode)
8107 || SPE_VECTOR_MODE (return_mode))
8108 rs6000_passes_vector = true;
8111 #endif
8113 if (fntype
8114 && !TARGET_ALTIVEC
8115 && TARGET_ALTIVEC_ABI
8116 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
8118 error ("cannot return value in vector register because"
8119 " altivec instructions are disabled, use -maltivec"
8120 " to enable them");
8124 /* Return true if TYPE must be passed on the stack and not in registers. */
8126 static bool
8127 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
8129 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
8130 return must_pass_in_stack_var_size (mode, type);
8131 else
8132 return must_pass_in_stack_var_size_or_pad (mode, type);
8135 /* If defined, a C expression which determines whether, and in which
8136 direction, to pad out an argument with extra space. The value
8137 should be of type `enum direction': either `upward' to pad above
8138 the argument, `downward' to pad below, or `none' to inhibit
8139 padding.
8141 For the AIX ABI structs are always stored left shifted in their
8142 argument slot. */
8144 enum direction
8145 function_arg_padding (enum machine_mode mode, const_tree type)
8147 #ifndef AGGREGATE_PADDING_FIXED
8148 #define AGGREGATE_PADDING_FIXED 0
8149 #endif
8150 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
8151 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
8152 #endif
8154 if (!AGGREGATE_PADDING_FIXED)
8156 /* GCC used to pass structures of the same size as integer types as
8157 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
8158 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
8159 passed padded downward, except that -mstrict-align further
8160 muddied the water in that multi-component structures of 2 and 4
8161 bytes in size were passed padded upward.
8163 The following arranges for best compatibility with previous
8164 versions of gcc, but removes the -mstrict-align dependency. */
8165 if (BYTES_BIG_ENDIAN)
8167 HOST_WIDE_INT size = 0;
8169 if (mode == BLKmode)
8171 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
8172 size = int_size_in_bytes (type);
8174 else
8175 size = GET_MODE_SIZE (mode);
8177 if (size == 1 || size == 2 || size == 4)
8178 return downward;
8180 return upward;
8183 if (AGGREGATES_PAD_UPWARD_ALWAYS)
8185 if (type != 0 && AGGREGATE_TYPE_P (type))
8186 return upward;
8189 /* Fall back to the default. */
8190 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
8193 /* If defined, a C expression that gives the alignment boundary, in bits,
8194 of an argument with the specified mode and type. If it is not defined,
8195 PARM_BOUNDARY is used for all arguments.
8197 V.4 wants long longs and doubles to be double word aligned. Just
8198 testing the mode size is a boneheaded way to do this as it means
8199 that other types such as complex int are also double word aligned.
8200 However, we're stuck with this because changing the ABI might break
8201 existing library interfaces.
8203 Doubleword align SPE vectors.
8204 Quadword align Altivec vectors.
8205 Quadword align large synthetic vector types. */
8207 static unsigned int
8208 rs6000_function_arg_boundary (enum machine_mode mode, const_tree type)
8210 if (DEFAULT_ABI == ABI_V4
8211 && (GET_MODE_SIZE (mode) == 8
8212 || (TARGET_HARD_FLOAT
8213 && TARGET_FPRS
8214 && (mode == TFmode || mode == TDmode))))
8215 return 64;
8216 else if (SPE_VECTOR_MODE (mode)
8217 || (type && TREE_CODE (type) == VECTOR_TYPE
8218 && int_size_in_bytes (type) >= 8
8219 && int_size_in_bytes (type) < 16))
8220 return 64;
8221 else if ((ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode))
8222 || (type && TREE_CODE (type) == VECTOR_TYPE
8223 && int_size_in_bytes (type) >= 16))
8224 return 128;
8225 else if (TARGET_MACHO
8226 && rs6000_darwin64_abi
8227 && mode == BLKmode
8228 && type && TYPE_ALIGN (type) > 64)
8229 return 128;
8230 else
8231 return PARM_BOUNDARY;
8234 /* For a function parm of MODE and TYPE, return the starting word in
8235 the parameter area. NWORDS of the parameter area are already used. */
8237 static unsigned int
8238 rs6000_parm_start (enum machine_mode mode, const_tree type,
8239 unsigned int nwords)
8241 unsigned int align;
8242 unsigned int parm_offset;
8244 align = rs6000_function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
8245 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
8246 return nwords + (-(parm_offset + nwords) & align);
8249 /* Compute the size (in words) of a function argument. */
8251 static unsigned long
8252 rs6000_arg_size (enum machine_mode mode, const_tree type)
8254 unsigned long size;
8256 if (mode != BLKmode)
8257 size = GET_MODE_SIZE (mode);
8258 else
8259 size = int_size_in_bytes (type);
8261 if (TARGET_32BIT)
8262 return (size + 3) >> 2;
8263 else
8264 return (size + 7) >> 3;
8267 /* Use this to flush pending int fields. */
8269 static void
8270 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
8271 HOST_WIDE_INT bitpos, int final)
8273 unsigned int startbit, endbit;
8274 int intregs, intoffset;
8275 enum machine_mode mode;
8277 /* Handle the situations where a float is taking up the first half
8278 of the GPR, and the other half is empty (typically due to
8279 alignment restrictions). We can detect this by a 8-byte-aligned
8280 int field, or by seeing that this is the final flush for this
8281 argument. Count the word and continue on. */
8282 if (cum->floats_in_gpr == 1
8283 && (cum->intoffset % 64 == 0
8284 || (cum->intoffset == -1 && final)))
8286 cum->words++;
8287 cum->floats_in_gpr = 0;
8290 if (cum->intoffset == -1)
8291 return;
8293 intoffset = cum->intoffset;
8294 cum->intoffset = -1;
8295 cum->floats_in_gpr = 0;
8297 if (intoffset % BITS_PER_WORD != 0)
8299 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
8300 MODE_INT, 0);
8301 if (mode == BLKmode)
8303 /* We couldn't find an appropriate mode, which happens,
8304 e.g., in packed structs when there are 3 bytes to load.
8305 Back intoffset back to the beginning of the word in this
8306 case. */
8307 intoffset = intoffset & -BITS_PER_WORD;
8311 startbit = intoffset & -BITS_PER_WORD;
8312 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
8313 intregs = (endbit - startbit) / BITS_PER_WORD;
8314 cum->words += intregs;
8315 /* words should be unsigned. */
8316 if ((unsigned)cum->words < (endbit/BITS_PER_WORD))
8318 int pad = (endbit/BITS_PER_WORD) - cum->words;
8319 cum->words += pad;
8323 /* The darwin64 ABI calls for us to recurse down through structs,
8324 looking for elements passed in registers. Unfortunately, we have
8325 to track int register count here also because of misalignments
8326 in powerpc alignment mode. */
8328 static void
8329 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
8330 const_tree type,
8331 HOST_WIDE_INT startbitpos)
8333 tree f;
8335 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
8336 if (TREE_CODE (f) == FIELD_DECL)
8338 HOST_WIDE_INT bitpos = startbitpos;
8339 tree ftype = TREE_TYPE (f);
8340 enum machine_mode mode;
8341 if (ftype == error_mark_node)
8342 continue;
8343 mode = TYPE_MODE (ftype);
8345 if (DECL_SIZE (f) != 0
8346 && host_integerp (bit_position (f), 1))
8347 bitpos += int_bit_position (f);
8349 /* ??? FIXME: else assume zero offset. */
8351 if (TREE_CODE (ftype) == RECORD_TYPE)
8352 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
8353 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
8355 unsigned n_fpregs = (GET_MODE_SIZE (mode) + 7) >> 3;
8356 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
8357 cum->fregno += n_fpregs;
8358 /* Single-precision floats present a special problem for
8359 us, because they are smaller than an 8-byte GPR, and so
8360 the structure-packing rules combined with the standard
8361 varargs behavior mean that we want to pack float/float
8362 and float/int combinations into a single register's
8363 space. This is complicated by the arg advance flushing,
8364 which works on arbitrarily large groups of int-type
8365 fields. */
8366 if (mode == SFmode)
8368 if (cum->floats_in_gpr == 1)
8370 /* Two floats in a word; count the word and reset
8371 the float count. */
8372 cum->words++;
8373 cum->floats_in_gpr = 0;
8375 else if (bitpos % 64 == 0)
8377 /* A float at the beginning of an 8-byte word;
8378 count it and put off adjusting cum->words until
8379 we see if a arg advance flush is going to do it
8380 for us. */
8381 cum->floats_in_gpr++;
8383 else
8385 /* The float is at the end of a word, preceded
8386 by integer fields, so the arg advance flush
8387 just above has already set cum->words and
8388 everything is taken care of. */
8391 else
8392 cum->words += n_fpregs;
8394 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
8396 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
8397 cum->vregno++;
8398 cum->words += 2;
8400 else if (cum->intoffset == -1)
8401 cum->intoffset = bitpos;
8405 /* Check for an item that needs to be considered specially under the darwin 64
8406 bit ABI. These are record types where the mode is BLK or the structure is
8407 8 bytes in size. */
8408 static int
8409 rs6000_darwin64_struct_check_p (enum machine_mode mode, const_tree type)
8411 return rs6000_darwin64_abi
8412 && ((mode == BLKmode
8413 && TREE_CODE (type) == RECORD_TYPE
8414 && int_size_in_bytes (type) > 0)
8415 || (type && TREE_CODE (type) == RECORD_TYPE
8416 && int_size_in_bytes (type) == 8)) ? 1 : 0;
8419 /* Update the data in CUM to advance over an argument
8420 of mode MODE and data type TYPE.
8421 (TYPE is null for libcalls where that information may not be available.)
8423 Note that for args passed by reference, function_arg will be called
8424 with MODE and TYPE set to that of the pointer to the arg, not the arg
8425 itself. */
8427 static void
8428 rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8429 const_tree type, bool named, int depth)
8431 /* Only tick off an argument if we're not recursing. */
8432 if (depth == 0)
8433 cum->nargs_prototype--;
8435 #ifdef HAVE_AS_GNU_ATTRIBUTE
8436 if (DEFAULT_ABI == ABI_V4
8437 && cum->escapes)
8439 if (SCALAR_FLOAT_MODE_P (mode))
8440 rs6000_passes_float = true;
8441 else if (named && (ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode)))
8442 rs6000_passes_vector = true;
8443 else if (SPE_VECTOR_MODE (mode)
8444 && !cum->stdarg
8445 && cum->sysv_gregno <= GP_ARG_MAX_REG)
8446 rs6000_passes_vector = true;
8448 #endif
8450 if (TARGET_ALTIVEC_ABI
8451 && (ALTIVEC_VECTOR_MODE (mode)
8452 || VSX_VECTOR_MODE (mode)
8453 || (type && TREE_CODE (type) == VECTOR_TYPE
8454 && int_size_in_bytes (type) == 16)))
8456 bool stack = false;
8458 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
8460 cum->vregno++;
8461 if (!TARGET_ALTIVEC)
8462 error ("cannot pass argument in vector register because"
8463 " altivec instructions are disabled, use -maltivec"
8464 " to enable them");
8466 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
8467 even if it is going to be passed in a vector register.
8468 Darwin does the same for variable-argument functions. */
8469 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
8470 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
8471 stack = true;
8473 else
8474 stack = true;
8476 if (stack)
8478 int align;
8480 /* Vector parameters must be 16-byte aligned. This places
8481 them at 2 mod 4 in terms of words in 32-bit mode, since
8482 the parameter save area starts at offset 24 from the
8483 stack. In 64-bit mode, they just have to start on an
8484 even word, since the parameter save area is 16-byte
8485 aligned. Space for GPRs is reserved even if the argument
8486 will be passed in memory. */
8487 if (TARGET_32BIT)
8488 align = (2 - cum->words) & 3;
8489 else
8490 align = cum->words & 1;
8491 cum->words += align + rs6000_arg_size (mode, type);
8493 if (TARGET_DEBUG_ARG)
8495 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
8496 cum->words, align);
8497 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
8498 cum->nargs_prototype, cum->prototype,
8499 GET_MODE_NAME (mode));
8503 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
8504 && !cum->stdarg
8505 && cum->sysv_gregno <= GP_ARG_MAX_REG)
8506 cum->sysv_gregno++;
8508 else if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8510 int size = int_size_in_bytes (type);
8511 /* Variable sized types have size == -1 and are
8512 treated as if consisting entirely of ints.
8513 Pad to 16 byte boundary if needed. */
8514 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8515 && (cum->words % 2) != 0)
8516 cum->words++;
8517 /* For varargs, we can just go up by the size of the struct. */
8518 if (!named)
8519 cum->words += (size + 7) / 8;
8520 else
8522 /* It is tempting to say int register count just goes up by
8523 sizeof(type)/8, but this is wrong in a case such as
8524 { int; double; int; } [powerpc alignment]. We have to
8525 grovel through the fields for these too. */
8526 cum->intoffset = 0;
8527 cum->floats_in_gpr = 0;
8528 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
8529 rs6000_darwin64_record_arg_advance_flush (cum,
8530 size * BITS_PER_UNIT, 1);
8532 if (TARGET_DEBUG_ARG)
8534 fprintf (stderr, "function_adv: words = %2d, align=%d, size=%d",
8535 cum->words, TYPE_ALIGN (type), size);
8536 fprintf (stderr,
8537 "nargs = %4d, proto = %d, mode = %4s (darwin64 abi)\n",
8538 cum->nargs_prototype, cum->prototype,
8539 GET_MODE_NAME (mode));
8542 else if (DEFAULT_ABI == ABI_V4)
8544 if (TARGET_HARD_FLOAT && TARGET_FPRS
8545 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8546 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8547 || (mode == TFmode && !TARGET_IEEEQUAD)
8548 || mode == SDmode || mode == DDmode || mode == TDmode))
8550 /* _Decimal128 must use an even/odd register pair. This assumes
8551 that the register number is odd when fregno is odd. */
8552 if (mode == TDmode && (cum->fregno % 2) == 1)
8553 cum->fregno++;
8555 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8556 <= FP_ARG_V4_MAX_REG)
8557 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8558 else
8560 cum->fregno = FP_ARG_V4_MAX_REG + 1;
8561 if (mode == DFmode || mode == TFmode
8562 || mode == DDmode || mode == TDmode)
8563 cum->words += cum->words & 1;
8564 cum->words += rs6000_arg_size (mode, type);
8567 else
8569 int n_words = rs6000_arg_size (mode, type);
8570 int gregno = cum->sysv_gregno;
8572 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8573 (r7,r8) or (r9,r10). As does any other 2 word item such
8574 as complex int due to a historical mistake. */
8575 if (n_words == 2)
8576 gregno += (1 - gregno) & 1;
8578 /* Multi-reg args are not split between registers and stack. */
8579 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8581 /* Long long and SPE vectors are aligned on the stack.
8582 So are other 2 word items such as complex int due to
8583 a historical mistake. */
8584 if (n_words == 2)
8585 cum->words += cum->words & 1;
8586 cum->words += n_words;
8589 /* Note: continuing to accumulate gregno past when we've started
8590 spilling to the stack indicates the fact that we've started
8591 spilling to the stack to expand_builtin_saveregs. */
8592 cum->sysv_gregno = gregno + n_words;
8595 if (TARGET_DEBUG_ARG)
8597 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8598 cum->words, cum->fregno);
8599 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
8600 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
8601 fprintf (stderr, "mode = %4s, named = %d\n",
8602 GET_MODE_NAME (mode), named);
8605 else
8607 int n_words = rs6000_arg_size (mode, type);
8608 int start_words = cum->words;
8609 int align_words = rs6000_parm_start (mode, type, start_words);
8611 cum->words = align_words + n_words;
8613 if (SCALAR_FLOAT_MODE_P (mode)
8614 && TARGET_HARD_FLOAT && TARGET_FPRS)
8616 /* _Decimal128 must be passed in an even/odd float register pair.
8617 This assumes that the register number is odd when fregno is
8618 odd. */
8619 if (mode == TDmode && (cum->fregno % 2) == 1)
8620 cum->fregno++;
8621 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8624 if (TARGET_DEBUG_ARG)
8626 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8627 cum->words, cum->fregno);
8628 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
8629 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
8630 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
8631 named, align_words - start_words, depth);
8636 static void
8637 rs6000_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8638 const_tree type, bool named)
8640 rs6000_function_arg_advance_1 (cum, mode, type, named, 0);
8643 static rtx
8644 spe_build_register_parallel (enum machine_mode mode, int gregno)
8646 rtx r1, r3, r5, r7;
8648 switch (mode)
8650 case DFmode:
8651 r1 = gen_rtx_REG (DImode, gregno);
8652 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8653 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
8655 case DCmode:
8656 case TFmode:
8657 r1 = gen_rtx_REG (DImode, gregno);
8658 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8659 r3 = gen_rtx_REG (DImode, gregno + 2);
8660 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8661 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
8663 case TCmode:
8664 r1 = gen_rtx_REG (DImode, gregno);
8665 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8666 r3 = gen_rtx_REG (DImode, gregno + 2);
8667 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8668 r5 = gen_rtx_REG (DImode, gregno + 4);
8669 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
8670 r7 = gen_rtx_REG (DImode, gregno + 6);
8671 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
8672 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
8674 default:
8675 gcc_unreachable ();
8679 /* Determine where to put a SIMD argument on the SPE. */
8680 static rtx
8681 rs6000_spe_function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
8682 const_tree type)
8684 int gregno = cum->sysv_gregno;
8686 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
8687 are passed and returned in a pair of GPRs for ABI compatibility. */
8688 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
8689 || mode == DCmode || mode == TCmode))
8691 int n_words = rs6000_arg_size (mode, type);
8693 /* Doubles go in an odd/even register pair (r5/r6, etc). */
8694 if (mode == DFmode)
8695 gregno += (1 - gregno) & 1;
8697 /* Multi-reg args are not split between registers and stack. */
8698 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8699 return NULL_RTX;
8701 return spe_build_register_parallel (mode, gregno);
8703 if (cum->stdarg)
8705 int n_words = rs6000_arg_size (mode, type);
8707 /* SPE vectors are put in odd registers. */
8708 if (n_words == 2 && (gregno & 1) == 0)
8709 gregno += 1;
8711 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
8713 rtx r1, r2;
8714 enum machine_mode m = SImode;
8716 r1 = gen_rtx_REG (m, gregno);
8717 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
8718 r2 = gen_rtx_REG (m, gregno + 1);
8719 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
8720 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
8722 else
8723 return NULL_RTX;
8725 else
8727 if (gregno <= GP_ARG_MAX_REG)
8728 return gen_rtx_REG (mode, gregno);
8729 else
8730 return NULL_RTX;
8734 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
8735 structure between cum->intoffset and bitpos to integer registers. */
8737 static void
8738 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
8739 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
8741 enum machine_mode mode;
8742 unsigned int regno;
8743 unsigned int startbit, endbit;
8744 int this_regno, intregs, intoffset;
8745 rtx reg;
8747 if (cum->intoffset == -1)
8748 return;
8750 intoffset = cum->intoffset;
8751 cum->intoffset = -1;
8753 /* If this is the trailing part of a word, try to only load that
8754 much into the register. Otherwise load the whole register. Note
8755 that in the latter case we may pick up unwanted bits. It's not a
8756 problem at the moment but may wish to revisit. */
8758 if (intoffset % BITS_PER_WORD != 0)
8760 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
8761 MODE_INT, 0);
8762 if (mode == BLKmode)
8764 /* We couldn't find an appropriate mode, which happens,
8765 e.g., in packed structs when there are 3 bytes to load.
8766 Back intoffset back to the beginning of the word in this
8767 case. */
8768 intoffset = intoffset & -BITS_PER_WORD;
8769 mode = word_mode;
8772 else
8773 mode = word_mode;
8775 startbit = intoffset & -BITS_PER_WORD;
8776 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
8777 intregs = (endbit - startbit) / BITS_PER_WORD;
8778 this_regno = cum->words + intoffset / BITS_PER_WORD;
8780 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
8781 cum->use_stack = 1;
8783 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
8784 if (intregs <= 0)
8785 return;
8787 intoffset /= BITS_PER_UNIT;
8790 regno = GP_ARG_MIN_REG + this_regno;
8791 reg = gen_rtx_REG (mode, regno);
8792 rvec[(*k)++] =
8793 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
8795 this_regno += 1;
8796 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
8797 mode = word_mode;
8798 intregs -= 1;
8800 while (intregs > 0);
8803 /* Recursive workhorse for the following. */
8805 static void
8806 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
8807 HOST_WIDE_INT startbitpos, rtx rvec[],
8808 int *k)
8810 tree f;
8812 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
8813 if (TREE_CODE (f) == FIELD_DECL)
8815 HOST_WIDE_INT bitpos = startbitpos;
8816 tree ftype = TREE_TYPE (f);
8817 enum machine_mode mode;
8818 if (ftype == error_mark_node)
8819 continue;
8820 mode = TYPE_MODE (ftype);
8822 if (DECL_SIZE (f) != 0
8823 && host_integerp (bit_position (f), 1))
8824 bitpos += int_bit_position (f);
8826 /* ??? FIXME: else assume zero offset. */
8828 if (TREE_CODE (ftype) == RECORD_TYPE)
8829 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
8830 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
8832 unsigned n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
8833 #if 0
8834 switch (mode)
8836 case SCmode: mode = SFmode; break;
8837 case DCmode: mode = DFmode; break;
8838 case TCmode: mode = TFmode; break;
8839 default: break;
8841 #endif
8842 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8843 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
8845 gcc_assert (cum->fregno == FP_ARG_MAX_REG
8846 && (mode == TFmode || mode == TDmode));
8847 /* Long double or _Decimal128 split over regs and memory. */
8848 mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : DFmode;
8849 cum->use_stack=1;
8851 rvec[(*k)++]
8852 = gen_rtx_EXPR_LIST (VOIDmode,
8853 gen_rtx_REG (mode, cum->fregno++),
8854 GEN_INT (bitpos / BITS_PER_UNIT));
8855 if (mode == TFmode || mode == TDmode)
8856 cum->fregno++;
8858 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
8860 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8861 rvec[(*k)++]
8862 = gen_rtx_EXPR_LIST (VOIDmode,
8863 gen_rtx_REG (mode, cum->vregno++),
8864 GEN_INT (bitpos / BITS_PER_UNIT));
8866 else if (cum->intoffset == -1)
8867 cum->intoffset = bitpos;
8871 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
8872 the register(s) to be used for each field and subfield of a struct
8873 being passed by value, along with the offset of where the
8874 register's value may be found in the block. FP fields go in FP
8875 register, vector fields go in vector registers, and everything
8876 else goes in int registers, packed as in memory.
8878 This code is also used for function return values. RETVAL indicates
8879 whether this is the case.
8881 Much of this is taken from the SPARC V9 port, which has a similar
8882 calling convention. */
8884 static rtx
8885 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
8886 bool named, bool retval)
8888 rtx rvec[FIRST_PSEUDO_REGISTER];
8889 int k = 1, kbase = 1;
8890 HOST_WIDE_INT typesize = int_size_in_bytes (type);
8891 /* This is a copy; modifications are not visible to our caller. */
8892 CUMULATIVE_ARGS copy_cum = *orig_cum;
8893 CUMULATIVE_ARGS *cum = &copy_cum;
8895 /* Pad to 16 byte boundary if needed. */
8896 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8897 && (cum->words % 2) != 0)
8898 cum->words++;
8900 cum->intoffset = 0;
8901 cum->use_stack = 0;
8902 cum->named = named;
8904 /* Put entries into rvec[] for individual FP and vector fields, and
8905 for the chunks of memory that go in int regs. Note we start at
8906 element 1; 0 is reserved for an indication of using memory, and
8907 may or may not be filled in below. */
8908 rs6000_darwin64_record_arg_recurse (cum, type, /* startbit pos= */ 0, rvec, &k);
8909 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
8911 /* If any part of the struct went on the stack put all of it there.
8912 This hack is because the generic code for
8913 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
8914 parts of the struct are not at the beginning. */
8915 if (cum->use_stack)
8917 if (retval)
8918 return NULL_RTX; /* doesn't go in registers at all */
8919 kbase = 0;
8920 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8922 if (k > 1 || cum->use_stack)
8923 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
8924 else
8925 return NULL_RTX;
8928 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
8930 static rtx
8931 rs6000_mixed_function_arg (enum machine_mode mode, const_tree type,
8932 int align_words)
8934 int n_units;
8935 int i, k;
8936 rtx rvec[GP_ARG_NUM_REG + 1];
8938 if (align_words >= GP_ARG_NUM_REG)
8939 return NULL_RTX;
8941 n_units = rs6000_arg_size (mode, type);
8943 /* Optimize the simple case where the arg fits in one gpr, except in
8944 the case of BLKmode due to assign_parms assuming that registers are
8945 BITS_PER_WORD wide. */
8946 if (n_units == 0
8947 || (n_units == 1 && mode != BLKmode))
8948 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8950 k = 0;
8951 if (align_words + n_units > GP_ARG_NUM_REG)
8952 /* Not all of the arg fits in gprs. Say that it goes in memory too,
8953 using a magic NULL_RTX component.
8954 This is not strictly correct. Only some of the arg belongs in
8955 memory, not all of it. However, the normal scheme using
8956 function_arg_partial_nregs can result in unusual subregs, eg.
8957 (subreg:SI (reg:DF) 4), which are not handled well. The code to
8958 store the whole arg to memory is often more efficient than code
8959 to store pieces, and we know that space is available in the right
8960 place for the whole arg. */
8961 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8963 i = 0;
8966 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
8967 rtx off = GEN_INT (i++ * 4);
8968 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8970 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
8972 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8975 /* Determine where to put an argument to a function.
8976 Value is zero to push the argument on the stack,
8977 or a hard register in which to store the argument.
8979 MODE is the argument's machine mode.
8980 TYPE is the data type of the argument (as a tree).
8981 This is null for libcalls where that information may
8982 not be available.
8983 CUM is a variable of type CUMULATIVE_ARGS which gives info about
8984 the preceding args and about the function being called. It is
8985 not modified in this routine.
8986 NAMED is nonzero if this argument is a named parameter
8987 (otherwise it is an extra parameter matching an ellipsis).
8989 On RS/6000 the first eight words of non-FP are normally in registers
8990 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
8991 Under V.4, the first 8 FP args are in registers.
8993 If this is floating-point and no prototype is specified, we use
8994 both an FP and integer register (or possibly FP reg and stack). Library
8995 functions (when CALL_LIBCALL is set) always have the proper types for args,
8996 so we can pass the FP value just in one register. emit_library_function
8997 doesn't support PARALLEL anyway.
8999 Note that for args passed by reference, function_arg will be called
9000 with MODE and TYPE set to that of the pointer to the arg, not the arg
9001 itself. */
9003 static rtx
9004 rs6000_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
9005 const_tree type, bool named)
9007 enum rs6000_abi abi = DEFAULT_ABI;
9009 /* Return a marker to indicate whether CR1 needs to set or clear the
9010 bit that V.4 uses to say fp args were passed in registers.
9011 Assume that we don't need the marker for software floating point,
9012 or compiler generated library calls. */
9013 if (mode == VOIDmode)
9015 if (abi == ABI_V4
9016 && (cum->call_cookie & CALL_LIBCALL) == 0
9017 && (cum->stdarg
9018 || (cum->nargs_prototype < 0
9019 && (cum->prototype || TARGET_NO_PROTOTYPE))))
9021 /* For the SPE, we need to crxor CR6 always. */
9022 if (TARGET_SPE_ABI)
9023 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
9024 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
9025 return GEN_INT (cum->call_cookie
9026 | ((cum->fregno == FP_ARG_MIN_REG)
9027 ? CALL_V4_SET_FP_ARGS
9028 : CALL_V4_CLEAR_FP_ARGS));
9031 return GEN_INT (cum->call_cookie);
9034 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
9036 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, /*retval= */false);
9037 if (rslt != NULL_RTX)
9038 return rslt;
9039 /* Else fall through to usual handling. */
9042 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
9043 if (TARGET_64BIT && ! cum->prototype)
9045 /* Vector parameters get passed in vector register
9046 and also in GPRs or memory, in absence of prototype. */
9047 int align_words;
9048 rtx slot;
9049 align_words = (cum->words + 1) & ~1;
9051 if (align_words >= GP_ARG_NUM_REG)
9053 slot = NULL_RTX;
9055 else
9057 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
9059 return gen_rtx_PARALLEL (mode,
9060 gen_rtvec (2,
9061 gen_rtx_EXPR_LIST (VOIDmode,
9062 slot, const0_rtx),
9063 gen_rtx_EXPR_LIST (VOIDmode,
9064 gen_rtx_REG (mode, cum->vregno),
9065 const0_rtx)));
9067 else
9068 return gen_rtx_REG (mode, cum->vregno);
9069 else if (TARGET_ALTIVEC_ABI
9070 && (ALTIVEC_VECTOR_MODE (mode)
9071 || VSX_VECTOR_MODE (mode)
9072 || (type && TREE_CODE (type) == VECTOR_TYPE
9073 && int_size_in_bytes (type) == 16)))
9075 if (named || abi == ABI_V4)
9076 return NULL_RTX;
9077 else
9079 /* Vector parameters to varargs functions under AIX or Darwin
9080 get passed in memory and possibly also in GPRs. */
9081 int align, align_words, n_words;
9082 enum machine_mode part_mode;
9084 /* Vector parameters must be 16-byte aligned. This places them at
9085 2 mod 4 in terms of words in 32-bit mode, since the parameter
9086 save area starts at offset 24 from the stack. In 64-bit mode,
9087 they just have to start on an even word, since the parameter
9088 save area is 16-byte aligned. */
9089 if (TARGET_32BIT)
9090 align = (2 - cum->words) & 3;
9091 else
9092 align = cum->words & 1;
9093 align_words = cum->words + align;
9095 /* Out of registers? Memory, then. */
9096 if (align_words >= GP_ARG_NUM_REG)
9097 return NULL_RTX;
9099 if (TARGET_32BIT && TARGET_POWERPC64)
9100 return rs6000_mixed_function_arg (mode, type, align_words);
9102 /* The vector value goes in GPRs. Only the part of the
9103 value in GPRs is reported here. */
9104 part_mode = mode;
9105 n_words = rs6000_arg_size (mode, type);
9106 if (align_words + n_words > GP_ARG_NUM_REG)
9107 /* Fortunately, there are only two possibilities, the value
9108 is either wholly in GPRs or half in GPRs and half not. */
9109 part_mode = DImode;
9111 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
9114 else if (TARGET_SPE_ABI && TARGET_SPE
9115 && (SPE_VECTOR_MODE (mode)
9116 || (TARGET_E500_DOUBLE && (mode == DFmode
9117 || mode == DCmode
9118 || mode == TFmode
9119 || mode == TCmode))))
9120 return rs6000_spe_function_arg (cum, mode, type);
9122 else if (abi == ABI_V4)
9124 if (TARGET_HARD_FLOAT && TARGET_FPRS
9125 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
9126 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
9127 || (mode == TFmode && !TARGET_IEEEQUAD)
9128 || mode == SDmode || mode == DDmode || mode == TDmode))
9130 /* _Decimal128 must use an even/odd register pair. This assumes
9131 that the register number is odd when fregno is odd. */
9132 if (mode == TDmode && (cum->fregno % 2) == 1)
9133 cum->fregno++;
9135 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
9136 <= FP_ARG_V4_MAX_REG)
9137 return gen_rtx_REG (mode, cum->fregno);
9138 else
9139 return NULL_RTX;
9141 else
9143 int n_words = rs6000_arg_size (mode, type);
9144 int gregno = cum->sysv_gregno;
9146 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
9147 (r7,r8) or (r9,r10). As does any other 2 word item such
9148 as complex int due to a historical mistake. */
9149 if (n_words == 2)
9150 gregno += (1 - gregno) & 1;
9152 /* Multi-reg args are not split between registers and stack. */
9153 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
9154 return NULL_RTX;
9156 if (TARGET_32BIT && TARGET_POWERPC64)
9157 return rs6000_mixed_function_arg (mode, type,
9158 gregno - GP_ARG_MIN_REG);
9159 return gen_rtx_REG (mode, gregno);
9162 else
9164 int align_words = rs6000_parm_start (mode, type, cum->words);
9166 /* _Decimal128 must be passed in an even/odd float register pair.
9167 This assumes that the register number is odd when fregno is odd. */
9168 if (mode == TDmode && (cum->fregno % 2) == 1)
9169 cum->fregno++;
9171 if (USE_FP_FOR_ARG_P (cum, mode, type))
9173 rtx rvec[GP_ARG_NUM_REG + 1];
9174 rtx r;
9175 int k;
9176 bool needs_psave;
9177 enum machine_mode fmode = mode;
9178 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
9180 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
9182 /* Currently, we only ever need one reg here because complex
9183 doubles are split. */
9184 gcc_assert (cum->fregno == FP_ARG_MAX_REG
9185 && (fmode == TFmode || fmode == TDmode));
9187 /* Long double or _Decimal128 split over regs and memory. */
9188 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
9191 /* Do we also need to pass this arg in the parameter save
9192 area? */
9193 needs_psave = (type
9194 && (cum->nargs_prototype <= 0
9195 || (DEFAULT_ABI == ABI_AIX
9196 && TARGET_XL_COMPAT
9197 && align_words >= GP_ARG_NUM_REG)));
9199 if (!needs_psave && mode == fmode)
9200 return gen_rtx_REG (fmode, cum->fregno);
9202 k = 0;
9203 if (needs_psave)
9205 /* Describe the part that goes in gprs or the stack.
9206 This piece must come first, before the fprs. */
9207 if (align_words < GP_ARG_NUM_REG)
9209 unsigned long n_words = rs6000_arg_size (mode, type);
9211 if (align_words + n_words > GP_ARG_NUM_REG
9212 || (TARGET_32BIT && TARGET_POWERPC64))
9214 /* If this is partially on the stack, then we only
9215 include the portion actually in registers here. */
9216 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
9217 rtx off;
9218 int i = 0;
9219 if (align_words + n_words > GP_ARG_NUM_REG)
9220 /* Not all of the arg fits in gprs. Say that it
9221 goes in memory too, using a magic NULL_RTX
9222 component. Also see comment in
9223 rs6000_mixed_function_arg for why the normal
9224 function_arg_partial_nregs scheme doesn't work
9225 in this case. */
9226 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
9227 const0_rtx);
9230 r = gen_rtx_REG (rmode,
9231 GP_ARG_MIN_REG + align_words);
9232 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
9233 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
9235 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
9237 else
9239 /* The whole arg fits in gprs. */
9240 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
9241 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
9244 else
9245 /* It's entirely in memory. */
9246 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
9249 /* Describe where this piece goes in the fprs. */
9250 r = gen_rtx_REG (fmode, cum->fregno);
9251 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
9253 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
9255 else if (align_words < GP_ARG_NUM_REG)
9257 if (TARGET_32BIT && TARGET_POWERPC64)
9258 return rs6000_mixed_function_arg (mode, type, align_words);
9260 if (mode == BLKmode)
9261 mode = Pmode;
9263 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
9265 else
9266 return NULL_RTX;
9270 /* For an arg passed partly in registers and partly in memory, this is
9271 the number of bytes passed in registers. For args passed entirely in
9272 registers or entirely in memory, zero. When an arg is described by a
9273 PARALLEL, perhaps using more than one register type, this function
9274 returns the number of bytes used by the first element of the PARALLEL. */
9276 static int
9277 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
9278 tree type, bool named)
9280 int ret = 0;
9281 int align_words;
9283 if (DEFAULT_ABI == ABI_V4)
9284 return 0;
9286 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
9287 && cum->nargs_prototype >= 0)
9288 return 0;
9290 /* In this complicated case we just disable the partial_nregs code. */
9291 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
9292 return 0;
9294 align_words = rs6000_parm_start (mode, type, cum->words);
9296 if (USE_FP_FOR_ARG_P (cum, mode, type))
9298 /* If we are passing this arg in the fixed parameter save area
9299 (gprs or memory) as well as fprs, then this function should
9300 return the number of partial bytes passed in the parameter
9301 save area rather than partial bytes passed in fprs. */
9302 if (type
9303 && (cum->nargs_prototype <= 0
9304 || (DEFAULT_ABI == ABI_AIX
9305 && TARGET_XL_COMPAT
9306 && align_words >= GP_ARG_NUM_REG)))
9307 return 0;
9308 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
9309 > FP_ARG_MAX_REG + 1)
9310 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
9311 else if (cum->nargs_prototype >= 0)
9312 return 0;
9315 if (align_words < GP_ARG_NUM_REG
9316 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
9317 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
9319 if (ret != 0 && TARGET_DEBUG_ARG)
9320 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
9322 return ret;
9325 /* A C expression that indicates when an argument must be passed by
9326 reference. If nonzero for an argument, a copy of that argument is
9327 made in memory and a pointer to the argument is passed instead of
9328 the argument itself. The pointer is passed in whatever way is
9329 appropriate for passing a pointer to that type.
9331 Under V.4, aggregates and long double are passed by reference.
9333 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
9334 reference unless the AltiVec vector extension ABI is in force.
9336 As an extension to all ABIs, variable sized types are passed by
9337 reference. */
9339 static bool
9340 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
9341 enum machine_mode mode, const_tree type,
9342 bool named ATTRIBUTE_UNUSED)
9344 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
9346 if (TARGET_DEBUG_ARG)
9347 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
9348 return 1;
9351 if (!type)
9352 return 0;
9354 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
9356 if (TARGET_DEBUG_ARG)
9357 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
9358 return 1;
9361 if (int_size_in_bytes (type) < 0)
9363 if (TARGET_DEBUG_ARG)
9364 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
9365 return 1;
9368 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
9369 modes only exist for GCC vector types if -maltivec. */
9370 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
9372 if (TARGET_DEBUG_ARG)
9373 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
9374 return 1;
9377 /* Pass synthetic vectors in memory. */
9378 if (TREE_CODE (type) == VECTOR_TYPE
9379 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
9381 static bool warned_for_pass_big_vectors = false;
9382 if (TARGET_DEBUG_ARG)
9383 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
9384 if (!warned_for_pass_big_vectors)
9386 warning (0, "GCC vector passed by reference: "
9387 "non-standard ABI extension with no compatibility guarantee");
9388 warned_for_pass_big_vectors = true;
9390 return 1;
9393 return 0;
9396 static void
9397 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
9399 int i;
9400 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
9402 if (nregs == 0)
9403 return;
9405 for (i = 0; i < nregs; i++)
9407 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
9408 if (reload_completed)
9410 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
9411 tem = NULL_RTX;
9412 else
9413 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
9414 i * GET_MODE_SIZE (reg_mode));
9416 else
9417 tem = replace_equiv_address (tem, XEXP (tem, 0));
9419 gcc_assert (tem);
9421 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
9425 /* Perform any needed actions needed for a function that is receiving a
9426 variable number of arguments.
9428 CUM is as above.
9430 MODE and TYPE are the mode and type of the current parameter.
9432 PRETEND_SIZE is a variable that should be set to the amount of stack
9433 that must be pushed by the prolog to pretend that our caller pushed
9436 Normally, this macro will push all remaining incoming registers on the
9437 stack and set PRETEND_SIZE to the length of the registers pushed. */
9439 static void
9440 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
9441 tree type, int *pretend_size ATTRIBUTE_UNUSED,
9442 int no_rtl)
9444 CUMULATIVE_ARGS next_cum;
9445 int reg_size = TARGET_32BIT ? 4 : 8;
9446 rtx save_area = NULL_RTX, mem;
9447 int first_reg_offset;
9448 alias_set_type set;
9450 /* Skip the last named argument. */
9451 next_cum = *cum;
9452 rs6000_function_arg_advance_1 (&next_cum, mode, type, true, 0);
9454 if (DEFAULT_ABI == ABI_V4)
9456 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
9458 if (! no_rtl)
9460 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
9461 HOST_WIDE_INT offset = 0;
9463 /* Try to optimize the size of the varargs save area.
9464 The ABI requires that ap.reg_save_area is doubleword
9465 aligned, but we don't need to allocate space for all
9466 the bytes, only those to which we actually will save
9467 anything. */
9468 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
9469 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
9470 if (TARGET_HARD_FLOAT && TARGET_FPRS
9471 && next_cum.fregno <= FP_ARG_V4_MAX_REG
9472 && cfun->va_list_fpr_size)
9474 if (gpr_reg_num)
9475 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
9476 * UNITS_PER_FP_WORD;
9477 if (cfun->va_list_fpr_size
9478 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
9479 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
9480 else
9481 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
9482 * UNITS_PER_FP_WORD;
9484 if (gpr_reg_num)
9486 offset = -((first_reg_offset * reg_size) & ~7);
9487 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
9489 gpr_reg_num = cfun->va_list_gpr_size;
9490 if (reg_size == 4 && (first_reg_offset & 1))
9491 gpr_reg_num++;
9493 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
9495 else if (fpr_size)
9496 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
9497 * UNITS_PER_FP_WORD
9498 - (int) (GP_ARG_NUM_REG * reg_size);
9500 if (gpr_size + fpr_size)
9502 rtx reg_save_area
9503 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
9504 gcc_assert (GET_CODE (reg_save_area) == MEM);
9505 reg_save_area = XEXP (reg_save_area, 0);
9506 if (GET_CODE (reg_save_area) == PLUS)
9508 gcc_assert (XEXP (reg_save_area, 0)
9509 == virtual_stack_vars_rtx);
9510 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
9511 offset += INTVAL (XEXP (reg_save_area, 1));
9513 else
9514 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
9517 cfun->machine->varargs_save_offset = offset;
9518 save_area = plus_constant (virtual_stack_vars_rtx, offset);
9521 else
9523 first_reg_offset = next_cum.words;
9524 save_area = virtual_incoming_args_rtx;
9526 if (targetm.calls.must_pass_in_stack (mode, type))
9527 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
9530 set = get_varargs_alias_set ();
9531 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
9532 && cfun->va_list_gpr_size)
9534 int nregs = GP_ARG_NUM_REG - first_reg_offset;
9536 if (va_list_gpr_counter_field)
9538 /* V4 va_list_gpr_size counts number of registers needed. */
9539 if (nregs > cfun->va_list_gpr_size)
9540 nregs = cfun->va_list_gpr_size;
9542 else
9544 /* char * va_list instead counts number of bytes needed. */
9545 if (nregs > cfun->va_list_gpr_size / reg_size)
9546 nregs = cfun->va_list_gpr_size / reg_size;
9549 mem = gen_rtx_MEM (BLKmode,
9550 plus_constant (save_area,
9551 first_reg_offset * reg_size));
9552 MEM_NOTRAP_P (mem) = 1;
9553 set_mem_alias_set (mem, set);
9554 set_mem_align (mem, BITS_PER_WORD);
9556 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
9557 nregs);
9560 /* Save FP registers if needed. */
9561 if (DEFAULT_ABI == ABI_V4
9562 && TARGET_HARD_FLOAT && TARGET_FPRS
9563 && ! no_rtl
9564 && next_cum.fregno <= FP_ARG_V4_MAX_REG
9565 && cfun->va_list_fpr_size)
9567 int fregno = next_cum.fregno, nregs;
9568 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
9569 rtx lab = gen_label_rtx ();
9570 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
9571 * UNITS_PER_FP_WORD);
9573 emit_jump_insn
9574 (gen_rtx_SET (VOIDmode,
9575 pc_rtx,
9576 gen_rtx_IF_THEN_ELSE (VOIDmode,
9577 gen_rtx_NE (VOIDmode, cr1,
9578 const0_rtx),
9579 gen_rtx_LABEL_REF (VOIDmode, lab),
9580 pc_rtx)));
9582 for (nregs = 0;
9583 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
9584 fregno++, off += UNITS_PER_FP_WORD, nregs++)
9586 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9587 ? DFmode : SFmode,
9588 plus_constant (save_area, off));
9589 MEM_NOTRAP_P (mem) = 1;
9590 set_mem_alias_set (mem, set);
9591 set_mem_align (mem, GET_MODE_ALIGNMENT (
9592 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9593 ? DFmode : SFmode));
9594 emit_move_insn (mem, gen_rtx_REG (
9595 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9596 ? DFmode : SFmode, fregno));
9599 emit_label (lab);
9603 /* Create the va_list data type. */
9605 static tree
9606 rs6000_build_builtin_va_list (void)
9608 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
9610 /* For AIX, prefer 'char *' because that's what the system
9611 header files like. */
9612 if (DEFAULT_ABI != ABI_V4)
9613 return build_pointer_type (char_type_node);
9615 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
9616 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
9617 get_identifier ("__va_list_tag"), record);
9619 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
9620 unsigned_char_type_node);
9621 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
9622 unsigned_char_type_node);
9623 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
9624 every user file. */
9625 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9626 get_identifier ("reserved"), short_unsigned_type_node);
9627 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9628 get_identifier ("overflow_arg_area"),
9629 ptr_type_node);
9630 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9631 get_identifier ("reg_save_area"),
9632 ptr_type_node);
9634 va_list_gpr_counter_field = f_gpr;
9635 va_list_fpr_counter_field = f_fpr;
9637 DECL_FIELD_CONTEXT (f_gpr) = record;
9638 DECL_FIELD_CONTEXT (f_fpr) = record;
9639 DECL_FIELD_CONTEXT (f_res) = record;
9640 DECL_FIELD_CONTEXT (f_ovf) = record;
9641 DECL_FIELD_CONTEXT (f_sav) = record;
9643 TYPE_STUB_DECL (record) = type_decl;
9644 TYPE_NAME (record) = type_decl;
9645 TYPE_FIELDS (record) = f_gpr;
9646 DECL_CHAIN (f_gpr) = f_fpr;
9647 DECL_CHAIN (f_fpr) = f_res;
9648 DECL_CHAIN (f_res) = f_ovf;
9649 DECL_CHAIN (f_ovf) = f_sav;
9651 layout_type (record);
9653 /* The correct type is an array type of one element. */
9654 return build_array_type (record, build_index_type (size_zero_node));
9657 /* Implement va_start. */
9659 static void
9660 rs6000_va_start (tree valist, rtx nextarg)
9662 HOST_WIDE_INT words, n_gpr, n_fpr;
9663 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9664 tree gpr, fpr, ovf, sav, t;
9666 /* Only SVR4 needs something special. */
9667 if (DEFAULT_ABI != ABI_V4)
9669 std_expand_builtin_va_start (valist, nextarg);
9670 return;
9673 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9674 f_fpr = DECL_CHAIN (f_gpr);
9675 f_res = DECL_CHAIN (f_fpr);
9676 f_ovf = DECL_CHAIN (f_res);
9677 f_sav = DECL_CHAIN (f_ovf);
9679 valist = build_simple_mem_ref (valist);
9680 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9681 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9682 f_fpr, NULL_TREE);
9683 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9684 f_ovf, NULL_TREE);
9685 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9686 f_sav, NULL_TREE);
9688 /* Count number of gp and fp argument registers used. */
9689 words = crtl->args.info.words;
9690 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
9691 GP_ARG_NUM_REG);
9692 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
9693 FP_ARG_NUM_REG);
9695 if (TARGET_DEBUG_ARG)
9696 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
9697 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
9698 words, n_gpr, n_fpr);
9700 if (cfun->va_list_gpr_size)
9702 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
9703 build_int_cst (NULL_TREE, n_gpr));
9704 TREE_SIDE_EFFECTS (t) = 1;
9705 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9708 if (cfun->va_list_fpr_size)
9710 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
9711 build_int_cst (NULL_TREE, n_fpr));
9712 TREE_SIDE_EFFECTS (t) = 1;
9713 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9715 #ifdef HAVE_AS_GNU_ATTRIBUTE
9716 if (call_ABI_of_interest (cfun->decl))
9717 rs6000_passes_float = true;
9718 #endif
9721 /* Find the overflow area. */
9722 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
9723 if (words != 0)
9724 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
9725 size_int (words * UNITS_PER_WORD));
9726 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
9727 TREE_SIDE_EFFECTS (t) = 1;
9728 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9730 /* If there were no va_arg invocations, don't set up the register
9731 save area. */
9732 if (!cfun->va_list_gpr_size
9733 && !cfun->va_list_fpr_size
9734 && n_gpr < GP_ARG_NUM_REG
9735 && n_fpr < FP_ARG_V4_MAX_REG)
9736 return;
9738 /* Find the register save area. */
9739 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
9740 if (cfun->machine->varargs_save_offset)
9741 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
9742 size_int (cfun->machine->varargs_save_offset));
9743 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
9744 TREE_SIDE_EFFECTS (t) = 1;
9745 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9748 /* Implement va_arg. */
9750 tree
9751 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
9752 gimple_seq *post_p)
9754 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9755 tree gpr, fpr, ovf, sav, reg, t, u;
9756 int size, rsize, n_reg, sav_ofs, sav_scale;
9757 tree lab_false, lab_over, addr;
9758 int align;
9759 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
9760 int regalign = 0;
9761 gimple stmt;
9763 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
9765 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
9766 return build_va_arg_indirect_ref (t);
9769 /* We need to deal with the fact that the darwin ppc64 ABI is defined by an
9770 earlier version of gcc, with the property that it always applied alignment
9771 adjustments to the va-args (even for zero-sized types). The cheapest way
9772 to deal with this is to replicate the effect of the part of
9773 std_gimplify_va_arg_expr that carries out the align adjust, for the case
9774 of relevance.
9775 We don't need to check for pass-by-reference because of the test above.
9776 We can return a simplifed answer, since we know there's no offset to add. */
9778 if (TARGET_MACHO
9779 && rs6000_darwin64_abi
9780 && integer_zerop (TYPE_SIZE (type)))
9782 unsigned HOST_WIDE_INT align, boundary;
9783 tree valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
9784 align = PARM_BOUNDARY / BITS_PER_UNIT;
9785 boundary = rs6000_function_arg_boundary (TYPE_MODE (type), type);
9786 if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
9787 boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
9788 boundary /= BITS_PER_UNIT;
9789 if (boundary > align)
9791 tree t ;
9792 /* This updates arg ptr by the amount that would be necessary
9793 to align the zero-sized (but not zero-alignment) item. */
9794 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9795 fold_build2 (POINTER_PLUS_EXPR,
9796 TREE_TYPE (valist),
9797 valist_tmp, size_int (boundary - 1)));
9798 gimplify_and_add (t, pre_p);
9800 t = fold_convert (sizetype, valist_tmp);
9801 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9802 fold_convert (TREE_TYPE (valist),
9803 fold_build2 (BIT_AND_EXPR, sizetype, t,
9804 size_int (-boundary))));
9805 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
9806 gimplify_and_add (t, pre_p);
9808 /* Since it is zero-sized there's no increment for the item itself. */
9809 valist_tmp = fold_convert (build_pointer_type (type), valist_tmp);
9810 return build_va_arg_indirect_ref (valist_tmp);
9813 if (DEFAULT_ABI != ABI_V4)
9815 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
9817 tree elem_type = TREE_TYPE (type);
9818 enum machine_mode elem_mode = TYPE_MODE (elem_type);
9819 int elem_size = GET_MODE_SIZE (elem_mode);
9821 if (elem_size < UNITS_PER_WORD)
9823 tree real_part, imag_part;
9824 gimple_seq post = NULL;
9826 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9827 &post);
9828 /* Copy the value into a temporary, lest the formal temporary
9829 be reused out from under us. */
9830 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
9831 gimple_seq_add_seq (pre_p, post);
9833 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9834 post_p);
9836 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
9840 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
9843 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9844 f_fpr = DECL_CHAIN (f_gpr);
9845 f_res = DECL_CHAIN (f_fpr);
9846 f_ovf = DECL_CHAIN (f_res);
9847 f_sav = DECL_CHAIN (f_ovf);
9849 valist = build_va_arg_indirect_ref (valist);
9850 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9851 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9852 f_fpr, NULL_TREE);
9853 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9854 f_ovf, NULL_TREE);
9855 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9856 f_sav, NULL_TREE);
9858 size = int_size_in_bytes (type);
9859 rsize = (size + 3) / 4;
9860 align = 1;
9862 if (TARGET_HARD_FLOAT && TARGET_FPRS
9863 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
9864 || (TARGET_DOUBLE_FLOAT
9865 && (TYPE_MODE (type) == DFmode
9866 || TYPE_MODE (type) == TFmode
9867 || TYPE_MODE (type) == SDmode
9868 || TYPE_MODE (type) == DDmode
9869 || TYPE_MODE (type) == TDmode))))
9871 /* FP args go in FP registers, if present. */
9872 reg = fpr;
9873 n_reg = (size + 7) / 8;
9874 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
9875 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
9876 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
9877 align = 8;
9879 else
9881 /* Otherwise into GP registers. */
9882 reg = gpr;
9883 n_reg = rsize;
9884 sav_ofs = 0;
9885 sav_scale = 4;
9886 if (n_reg == 2)
9887 align = 8;
9890 /* Pull the value out of the saved registers.... */
9892 lab_over = NULL;
9893 addr = create_tmp_var (ptr_type_node, "addr");
9895 /* AltiVec vectors never go in registers when -mabi=altivec. */
9896 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
9897 align = 16;
9898 else
9900 lab_false = create_artificial_label (input_location);
9901 lab_over = create_artificial_label (input_location);
9903 /* Long long and SPE vectors are aligned in the registers.
9904 As are any other 2 gpr item such as complex int due to a
9905 historical mistake. */
9906 u = reg;
9907 if (n_reg == 2 && reg == gpr)
9909 regalign = 1;
9910 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9911 build_int_cst (TREE_TYPE (reg), n_reg - 1));
9912 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
9913 unshare_expr (reg), u);
9915 /* _Decimal128 is passed in even/odd fpr pairs; the stored
9916 reg number is 0 for f1, so we want to make it odd. */
9917 else if (reg == fpr && TYPE_MODE (type) == TDmode)
9919 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9920 build_int_cst (TREE_TYPE (reg), 1));
9921 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
9924 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
9925 t = build2 (GE_EXPR, boolean_type_node, u, t);
9926 u = build1 (GOTO_EXPR, void_type_node, lab_false);
9927 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
9928 gimplify_and_add (t, pre_p);
9930 t = sav;
9931 if (sav_ofs)
9932 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
9934 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9935 build_int_cst (TREE_TYPE (reg), n_reg));
9936 u = fold_convert (sizetype, u);
9937 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
9938 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
9940 /* _Decimal32 varargs are located in the second word of the 64-bit
9941 FP register for 32-bit binaries. */
9942 if (!TARGET_POWERPC64
9943 && TARGET_HARD_FLOAT && TARGET_FPRS
9944 && TYPE_MODE (type) == SDmode)
9945 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9947 gimplify_assign (addr, t, pre_p);
9949 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
9951 stmt = gimple_build_label (lab_false);
9952 gimple_seq_add_stmt (pre_p, stmt);
9954 if ((n_reg == 2 && !regalign) || n_reg > 2)
9956 /* Ensure that we don't find any more args in regs.
9957 Alignment has taken care of for special cases. */
9958 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
9962 /* ... otherwise out of the overflow area. */
9964 /* Care for on-stack alignment if needed. */
9965 t = ovf;
9966 if (align != 1)
9968 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
9969 t = fold_convert (sizetype, t);
9970 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
9971 size_int (-align));
9972 t = fold_convert (TREE_TYPE (ovf), t);
9974 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
9976 gimplify_assign (unshare_expr (addr), t, pre_p);
9978 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9979 gimplify_assign (unshare_expr (ovf), t, pre_p);
9981 if (lab_over)
9983 stmt = gimple_build_label (lab_over);
9984 gimple_seq_add_stmt (pre_p, stmt);
9987 if (STRICT_ALIGNMENT
9988 && (TYPE_ALIGN (type)
9989 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
9991 /* The value (of type complex double, for example) may not be
9992 aligned in memory in the saved registers, so copy via a
9993 temporary. (This is the same code as used for SPARC.) */
9994 tree tmp = create_tmp_var (type, "va_arg_tmp");
9995 tree dest_addr = build_fold_addr_expr (tmp);
9997 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
9998 3, dest_addr, addr, size_int (rsize * 4));
10000 gimplify_and_add (copy, pre_p);
10001 addr = dest_addr;
10004 addr = fold_convert (ptrtype, addr);
10005 return build_va_arg_indirect_ref (addr);
10008 /* Builtins. */
10010 static void
10011 def_builtin (int mask, const char *name, tree type, int code)
10013 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
10015 tree t;
10016 if (rs6000_builtin_decls[code])
10017 fatal_error ("internal error: builtin function to %s already processed",
10018 name);
10020 rs6000_builtin_decls[code] = t =
10021 add_builtin_function (name, type, code, BUILT_IN_MD,
10022 NULL, NULL_TREE);
10024 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT);
10025 switch (builtin_classify[code])
10027 default:
10028 gcc_unreachable ();
10030 /* assume builtin can do anything. */
10031 case RS6000_BTC_MISC:
10032 break;
10034 /* const function, function only depends on the inputs. */
10035 case RS6000_BTC_CONST:
10036 TREE_READONLY (t) = 1;
10037 TREE_NOTHROW (t) = 1;
10038 break;
10040 /* pure function, function can read global memory. */
10041 case RS6000_BTC_PURE:
10042 DECL_PURE_P (t) = 1;
10043 TREE_NOTHROW (t) = 1;
10044 break;
10046 /* Function is a math function. If rounding mode is on, then treat
10047 the function as not reading global memory, but it can have
10048 arbitrary side effects. If it is off, then assume the function is
10049 a const function. This mimics the ATTR_MATHFN_FPROUNDING
10050 attribute in builtin-attribute.def that is used for the math
10051 functions. */
10052 case RS6000_BTC_FP_PURE:
10053 TREE_NOTHROW (t) = 1;
10054 if (flag_rounding_math)
10056 DECL_PURE_P (t) = 1;
10057 DECL_IS_NOVOPS (t) = 1;
10059 else
10060 TREE_READONLY (t) = 1;
10061 break;
10066 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
10068 static const struct builtin_description bdesc_3arg[] =
10070 { MASK_ALTIVEC, CODE_FOR_fmav4sf4, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
10071 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
10072 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
10073 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
10074 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
10075 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
10076 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
10077 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
10078 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
10079 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
10080 { MASK_ALTIVEC, CODE_FOR_nfmsv4sf4, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
10081 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
10082 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
10083 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
10084 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
10085 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
10086 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
10087 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
10088 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
10089 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
10090 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
10091 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
10092 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
10093 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
10094 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
10095 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
10096 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
10097 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
10098 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
10099 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
10100 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
10101 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
10102 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
10103 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
10104 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
10106 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
10107 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
10108 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
10109 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
10110 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
10111 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
10112 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
10113 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
10114 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
10115 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
10116 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
10117 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
10118 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
10119 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
10120 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
10122 { MASK_VSX, CODE_FOR_fmav2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
10123 { MASK_VSX, CODE_FOR_fmsv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
10124 { MASK_VSX, CODE_FOR_nfmav2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
10125 { MASK_VSX, CODE_FOR_nfmsv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
10127 { MASK_VSX, CODE_FOR_fmav4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
10128 { MASK_VSX, CODE_FOR_fmsv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
10129 { MASK_VSX, CODE_FOR_nfmav4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
10130 { MASK_VSX, CODE_FOR_nfmsv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
10132 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
10133 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
10135 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
10136 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
10137 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
10138 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
10139 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
10140 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
10141 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
10142 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
10143 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
10144 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
10146 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
10147 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
10148 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
10149 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
10150 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
10151 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
10152 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
10153 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
10154 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
10155 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
10157 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
10158 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
10159 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
10160 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
10161 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
10162 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
10163 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
10164 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
10165 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
10167 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
10168 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
10169 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
10170 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
10171 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
10172 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
10173 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
10175 { 0, CODE_FOR_fmsv2sf4, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
10176 { 0, CODE_FOR_fmav2sf4, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
10177 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
10178 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
10179 { 0, CODE_FOR_nfmsv2sf4, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
10180 { 0, CODE_FOR_nfmav2sf4, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
10181 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
10182 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
10183 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
10186 /* DST operations: void foo (void *, const int, const char). */
10188 static const struct builtin_description bdesc_dst[] =
10190 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
10191 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
10192 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
10193 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
10195 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
10196 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
10197 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
10198 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
10201 /* Simple binary operations: VECc = foo (VECa, VECb). */
10203 static struct builtin_description bdesc_2arg[] =
10205 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
10206 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
10207 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
10208 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
10209 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
10210 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
10211 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
10212 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
10213 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
10214 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
10215 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
10216 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
10217 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
10218 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
10219 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
10220 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
10221 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
10222 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
10223 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
10224 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
10225 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
10226 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
10227 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
10228 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
10229 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
10230 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
10231 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
10232 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
10233 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
10234 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
10235 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
10236 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
10237 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
10238 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
10239 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
10240 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
10241 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
10242 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
10243 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
10244 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
10245 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
10246 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
10247 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
10248 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
10249 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
10250 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
10251 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
10252 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
10253 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
10254 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
10255 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
10256 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
10257 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
10258 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
10259 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
10260 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
10261 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
10262 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
10263 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
10264 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
10265 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
10266 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
10267 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
10268 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
10269 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
10270 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
10271 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
10272 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
10273 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
10274 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
10275 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
10276 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
10277 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
10278 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
10279 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
10280 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
10281 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
10282 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
10283 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
10284 { MASK_ALTIVEC, CODE_FOR_recipv4sf3, "__builtin_altivec_vrecipdivfp", ALTIVEC_BUILTIN_VRECIPFP },
10285 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
10286 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
10287 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
10288 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
10289 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
10290 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
10291 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
10292 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
10293 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
10294 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
10295 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
10296 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
10297 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
10298 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
10299 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
10300 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
10301 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
10302 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
10303 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
10304 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
10305 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
10306 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
10307 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
10308 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
10309 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
10310 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
10311 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
10312 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
10313 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
10314 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
10315 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
10316 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
10317 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
10318 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
10319 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
10320 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
10321 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
10323 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
10324 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
10325 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
10326 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
10327 { MASK_VSX, CODE_FOR_recipv2df3, "__builtin_vsx_xvrecipdivdp", VSX_BUILTIN_RECIP_V2DF },
10328 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
10329 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
10330 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
10331 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
10332 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
10333 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
10334 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
10336 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
10337 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
10338 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
10339 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
10340 { MASK_VSX, CODE_FOR_recipv4sf3, "__builtin_vsx_xvrecipdivsp", VSX_BUILTIN_RECIP_V4SF },
10341 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
10342 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
10343 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
10344 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
10345 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
10346 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
10347 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
10349 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
10350 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
10351 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
10352 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
10353 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
10354 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
10356 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
10357 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
10358 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
10359 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
10360 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
10361 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
10362 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
10363 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
10364 { MASK_VSX, CODE_FOR_vec_interleave_lowv2df, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF },
10365 { MASK_VSX, CODE_FOR_vec_interleave_lowv2di, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI },
10366 { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF },
10367 { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI },
10369 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
10370 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
10371 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
10372 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
10373 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
10374 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
10375 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
10376 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
10377 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
10378 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
10379 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
10380 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
10381 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
10382 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
10383 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
10384 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
10385 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
10386 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
10387 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
10388 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
10389 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
10390 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
10391 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
10392 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
10393 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
10394 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
10395 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
10396 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
10397 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
10398 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
10399 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
10400 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
10401 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
10402 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
10403 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
10404 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
10405 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
10406 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
10407 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
10408 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
10409 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
10410 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
10411 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
10412 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
10413 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
10414 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
10415 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
10416 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
10417 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
10418 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
10419 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
10420 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
10421 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
10422 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
10423 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
10424 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
10425 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
10426 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
10427 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
10428 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
10429 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
10430 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
10431 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
10432 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
10433 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
10434 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
10435 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
10436 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
10437 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
10438 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
10439 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
10440 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
10441 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
10442 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
10443 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
10444 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
10445 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
10446 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
10447 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
10448 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
10449 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
10450 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
10451 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
10452 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
10453 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
10454 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
10455 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
10456 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
10457 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_recipdiv", ALTIVEC_BUILTIN_VEC_RECIP },
10458 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
10459 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
10460 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
10461 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
10462 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
10463 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
10464 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
10465 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
10466 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
10467 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
10468 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
10469 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
10470 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
10471 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
10472 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
10473 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
10474 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
10475 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
10476 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
10477 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
10478 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
10479 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
10480 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
10481 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
10482 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
10483 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
10484 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
10485 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
10486 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
10487 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
10488 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
10489 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
10490 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
10491 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
10492 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
10493 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
10494 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
10495 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
10496 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
10497 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
10499 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
10500 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
10502 { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
10503 { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
10504 { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
10505 { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
10506 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
10507 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
10508 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
10509 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
10510 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
10511 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
10513 /* Place holder, leave as first spe builtin. */
10514 { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
10515 { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
10516 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
10517 { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
10518 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
10519 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
10520 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
10521 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
10522 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
10523 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
10524 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
10525 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
10526 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
10527 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
10528 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
10529 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
10530 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
10531 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
10532 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
10533 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
10534 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
10535 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
10536 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
10537 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
10538 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
10539 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
10540 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
10541 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
10542 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
10543 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
10544 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
10545 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
10546 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
10547 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
10548 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
10549 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
10550 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
10551 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
10552 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
10553 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
10554 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
10555 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
10556 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
10557 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
10558 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
10559 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
10560 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
10561 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
10562 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
10563 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
10564 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
10565 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
10566 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
10567 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
10568 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
10569 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
10570 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
10571 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
10572 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
10573 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
10574 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
10575 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
10576 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
10577 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
10578 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
10579 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
10580 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
10581 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
10582 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
10583 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
10584 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
10585 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
10586 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
10587 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
10588 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
10589 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
10590 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
10591 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
10592 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
10593 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
10594 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
10595 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
10596 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
10597 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
10598 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
10599 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
10600 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
10601 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
10602 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
10603 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
10604 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
10605 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
10606 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
10607 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
10608 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
10609 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
10610 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
10611 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
10612 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
10613 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
10614 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
10615 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
10616 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
10617 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
10618 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
10619 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
10620 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
10621 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
10622 { 0, CODE_FOR_subv2si3, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
10624 /* SPE binary operations expecting a 5-bit unsigned literal. */
10625 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
10627 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
10628 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
10629 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
10630 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
10631 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
10632 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
10633 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
10634 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
10635 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
10636 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
10637 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
10638 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
10639 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
10640 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
10641 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
10642 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
10643 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
10644 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
10645 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
10646 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
10647 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
10648 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
10649 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
10650 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
10651 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
10652 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
10654 /* Place-holder. Leave as last binary SPE builtin. */
10655 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
10658 /* AltiVec predicates. */
10660 struct builtin_description_predicates
10662 const unsigned int mask;
10663 const enum insn_code icode;
10664 const char *const name;
10665 const enum rs6000_builtins code;
10668 static const struct builtin_description_predicates bdesc_altivec_preds[] =
10670 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
10671 ALTIVEC_BUILTIN_VCMPBFP_P },
10672 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
10673 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
10674 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
10675 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
10676 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
10677 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
10678 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
10679 ALTIVEC_BUILTIN_VCMPEQUW_P },
10680 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
10681 ALTIVEC_BUILTIN_VCMPGTSW_P },
10682 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
10683 ALTIVEC_BUILTIN_VCMPGTUW_P },
10684 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
10685 ALTIVEC_BUILTIN_VCMPEQUH_P },
10686 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
10687 ALTIVEC_BUILTIN_VCMPGTSH_P },
10688 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
10689 ALTIVEC_BUILTIN_VCMPGTUH_P },
10690 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
10691 ALTIVEC_BUILTIN_VCMPEQUB_P },
10692 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
10693 ALTIVEC_BUILTIN_VCMPGTSB_P },
10694 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
10695 ALTIVEC_BUILTIN_VCMPGTUB_P },
10697 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
10698 VSX_BUILTIN_XVCMPEQSP_P },
10699 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
10700 VSX_BUILTIN_XVCMPGESP_P },
10701 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
10702 VSX_BUILTIN_XVCMPGTSP_P },
10703 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
10704 VSX_BUILTIN_XVCMPEQDP_P },
10705 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
10706 VSX_BUILTIN_XVCMPGEDP_P },
10707 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
10708 VSX_BUILTIN_XVCMPGTDP_P },
10710 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
10711 ALTIVEC_BUILTIN_VCMPEQ_P },
10712 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
10713 ALTIVEC_BUILTIN_VCMPGT_P },
10714 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
10715 ALTIVEC_BUILTIN_VCMPGE_P }
10718 /* SPE predicates. */
10719 static struct builtin_description bdesc_spe_predicates[] =
10721 /* Place-holder. Leave as first. */
10722 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
10723 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
10724 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
10725 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
10726 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
10727 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
10728 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
10729 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
10730 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
10731 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
10732 /* Place-holder. Leave as last. */
10733 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
10736 /* SPE evsel predicates. */
10737 static struct builtin_description bdesc_spe_evsel[] =
10739 /* Place-holder. Leave as first. */
10740 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
10741 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
10742 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
10743 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
10744 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
10745 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
10746 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
10747 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
10748 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
10749 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
10750 /* Place-holder. Leave as last. */
10751 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
10754 /* PAIRED predicates. */
10755 static const struct builtin_description bdesc_paired_preds[] =
10757 /* Place-holder. Leave as first. */
10758 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
10759 /* Place-holder. Leave as last. */
10760 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
10763 /* ABS* operations. */
10765 static const struct builtin_description bdesc_abs[] =
10767 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
10768 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
10769 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
10770 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
10771 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
10772 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
10773 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
10774 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
10775 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
10776 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
10777 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
10780 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
10781 foo (VECa). */
10783 static struct builtin_description bdesc_1arg[] =
10785 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
10786 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
10787 { MASK_ALTIVEC, CODE_FOR_rev4sf2, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
10788 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
10789 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
10790 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
10791 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
10792 { MASK_ALTIVEC, CODE_FOR_rsqrtv4sf2, "__builtin_altivec_vrsqrtfp", ALTIVEC_BUILTIN_VRSQRTFP },
10793 { MASK_ALTIVEC, CODE_FOR_rsqrtev4sf2, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
10794 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
10795 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
10796 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
10797 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
10798 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
10799 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
10800 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
10801 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
10802 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
10804 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
10805 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
10806 { MASK_VSX, CODE_FOR_rsqrtv2df2, "__builtin_vsx_xvrsqrtdp", VSX_BUILTIN_VEC_RSQRT_V2DF },
10807 { MASK_VSX, CODE_FOR_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
10808 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
10809 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
10810 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
10812 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
10813 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
10814 { MASK_VSX, CODE_FOR_rsqrtv4sf2, "__builtin_vsx_xvrsqrtsp", VSX_BUILTIN_VEC_RSQRT_V4SF },
10815 { MASK_VSX, CODE_FOR_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
10816 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
10817 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
10818 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
10820 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
10821 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
10822 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
10823 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
10824 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
10825 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
10827 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
10828 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
10829 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
10830 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
10831 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
10832 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
10834 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
10835 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
10836 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
10837 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
10839 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
10840 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
10841 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
10842 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
10843 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
10844 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
10845 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
10846 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
10847 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
10849 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
10850 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
10851 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
10852 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
10853 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
10854 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
10855 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
10856 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
10857 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
10859 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
10860 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
10861 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
10862 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
10863 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
10865 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
10866 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
10867 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
10868 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
10869 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
10870 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
10871 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
10872 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
10873 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
10874 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrt", ALTIVEC_BUILTIN_VEC_RSQRT },
10875 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
10876 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
10877 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
10878 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
10879 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
10880 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
10881 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
10882 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
10883 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
10884 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
10886 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
10887 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
10888 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
10890 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
10891 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
10892 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
10893 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
10895 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
10896 end with SPE_BUILTIN_EVSUBFUSIAAW. */
10897 { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
10898 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
10899 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
10900 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
10901 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
10902 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
10903 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
10904 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
10905 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
10906 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
10907 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
10908 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
10909 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
10910 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
10911 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
10912 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
10913 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
10914 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
10915 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
10916 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
10917 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
10918 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
10919 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
10920 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
10921 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
10922 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
10923 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
10924 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
10926 /* Place-holder. Leave as last unary SPE builtin. */
10927 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
10929 { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
10930 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
10931 { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
10932 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
10933 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
10936 static rtx
10937 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
10939 rtx pat;
10940 tree arg0 = CALL_EXPR_ARG (exp, 0);
10941 rtx op0 = expand_normal (arg0);
10942 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10943 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10945 if (icode == CODE_FOR_nothing)
10946 /* Builtin not supported on this processor. */
10947 return 0;
10949 /* If we got invalid arguments bail out before generating bad rtl. */
10950 if (arg0 == error_mark_node)
10951 return const0_rtx;
10953 if (icode == CODE_FOR_altivec_vspltisb
10954 || icode == CODE_FOR_altivec_vspltish
10955 || icode == CODE_FOR_altivec_vspltisw
10956 || icode == CODE_FOR_spe_evsplatfi
10957 || icode == CODE_FOR_spe_evsplati)
10959 /* Only allow 5-bit *signed* literals. */
10960 if (GET_CODE (op0) != CONST_INT
10961 || INTVAL (op0) > 15
10962 || INTVAL (op0) < -16)
10964 error ("argument 1 must be a 5-bit signed literal");
10965 return const0_rtx;
10969 if (target == 0
10970 || GET_MODE (target) != tmode
10971 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10972 target = gen_reg_rtx (tmode);
10974 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10975 op0 = copy_to_mode_reg (mode0, op0);
10977 pat = GEN_FCN (icode) (target, op0);
10978 if (! pat)
10979 return 0;
10980 emit_insn (pat);
10982 return target;
10985 static rtx
10986 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
10988 rtx pat, scratch1, scratch2;
10989 tree arg0 = CALL_EXPR_ARG (exp, 0);
10990 rtx op0 = expand_normal (arg0);
10991 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10992 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10994 /* If we have invalid arguments, bail out before generating bad rtl. */
10995 if (arg0 == error_mark_node)
10996 return const0_rtx;
10998 if (target == 0
10999 || GET_MODE (target) != tmode
11000 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11001 target = gen_reg_rtx (tmode);
11003 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11004 op0 = copy_to_mode_reg (mode0, op0);
11006 scratch1 = gen_reg_rtx (mode0);
11007 scratch2 = gen_reg_rtx (mode0);
11009 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
11010 if (! pat)
11011 return 0;
11012 emit_insn (pat);
11014 return target;
11017 static rtx
11018 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
11020 rtx pat;
11021 tree arg0 = CALL_EXPR_ARG (exp, 0);
11022 tree arg1 = CALL_EXPR_ARG (exp, 1);
11023 rtx op0 = expand_normal (arg0);
11024 rtx op1 = expand_normal (arg1);
11025 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11026 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11027 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11029 if (icode == CODE_FOR_nothing)
11030 /* Builtin not supported on this processor. */
11031 return 0;
11033 /* If we got invalid arguments bail out before generating bad rtl. */
11034 if (arg0 == error_mark_node || arg1 == error_mark_node)
11035 return const0_rtx;
11037 if (icode == CODE_FOR_altivec_vcfux
11038 || icode == CODE_FOR_altivec_vcfsx
11039 || icode == CODE_FOR_altivec_vctsxs
11040 || icode == CODE_FOR_altivec_vctuxs
11041 || icode == CODE_FOR_altivec_vspltb
11042 || icode == CODE_FOR_altivec_vsplth
11043 || icode == CODE_FOR_altivec_vspltw
11044 || icode == CODE_FOR_spe_evaddiw
11045 || icode == CODE_FOR_spe_evldd
11046 || icode == CODE_FOR_spe_evldh
11047 || icode == CODE_FOR_spe_evldw
11048 || icode == CODE_FOR_spe_evlhhesplat
11049 || icode == CODE_FOR_spe_evlhhossplat
11050 || icode == CODE_FOR_spe_evlhhousplat
11051 || icode == CODE_FOR_spe_evlwhe
11052 || icode == CODE_FOR_spe_evlwhos
11053 || icode == CODE_FOR_spe_evlwhou
11054 || icode == CODE_FOR_spe_evlwhsplat
11055 || icode == CODE_FOR_spe_evlwwsplat
11056 || icode == CODE_FOR_spe_evrlwi
11057 || icode == CODE_FOR_spe_evslwi
11058 || icode == CODE_FOR_spe_evsrwis
11059 || icode == CODE_FOR_spe_evsubifw
11060 || icode == CODE_FOR_spe_evsrwiu)
11062 /* Only allow 5-bit unsigned literals. */
11063 STRIP_NOPS (arg1);
11064 if (TREE_CODE (arg1) != INTEGER_CST
11065 || TREE_INT_CST_LOW (arg1) & ~0x1f)
11067 error ("argument 2 must be a 5-bit unsigned literal");
11068 return const0_rtx;
11072 if (target == 0
11073 || GET_MODE (target) != tmode
11074 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11075 target = gen_reg_rtx (tmode);
11077 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11078 op0 = copy_to_mode_reg (mode0, op0);
11079 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11080 op1 = copy_to_mode_reg (mode1, op1);
11082 pat = GEN_FCN (icode) (target, op0, op1);
11083 if (! pat)
11084 return 0;
11085 emit_insn (pat);
11087 return target;
11090 static rtx
11091 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11093 rtx pat, scratch;
11094 tree cr6_form = CALL_EXPR_ARG (exp, 0);
11095 tree arg0 = CALL_EXPR_ARG (exp, 1);
11096 tree arg1 = CALL_EXPR_ARG (exp, 2);
11097 rtx op0 = expand_normal (arg0);
11098 rtx op1 = expand_normal (arg1);
11099 enum machine_mode tmode = SImode;
11100 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11101 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11102 int cr6_form_int;
11104 if (TREE_CODE (cr6_form) != INTEGER_CST)
11106 error ("argument 1 of __builtin_altivec_predicate must be a constant");
11107 return const0_rtx;
11109 else
11110 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
11112 gcc_assert (mode0 == mode1);
11114 /* If we have invalid arguments, bail out before generating bad rtl. */
11115 if (arg0 == error_mark_node || arg1 == error_mark_node)
11116 return const0_rtx;
11118 if (target == 0
11119 || GET_MODE (target) != tmode
11120 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11121 target = gen_reg_rtx (tmode);
11123 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11124 op0 = copy_to_mode_reg (mode0, op0);
11125 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11126 op1 = copy_to_mode_reg (mode1, op1);
11128 scratch = gen_reg_rtx (mode0);
11130 pat = GEN_FCN (icode) (scratch, op0, op1);
11131 if (! pat)
11132 return 0;
11133 emit_insn (pat);
11135 /* The vec_any* and vec_all* predicates use the same opcodes for two
11136 different operations, but the bits in CR6 will be different
11137 depending on what information we want. So we have to play tricks
11138 with CR6 to get the right bits out.
11140 If you think this is disgusting, look at the specs for the
11141 AltiVec predicates. */
11143 switch (cr6_form_int)
11145 case 0:
11146 emit_insn (gen_cr6_test_for_zero (target));
11147 break;
11148 case 1:
11149 emit_insn (gen_cr6_test_for_zero_reverse (target));
11150 break;
11151 case 2:
11152 emit_insn (gen_cr6_test_for_lt (target));
11153 break;
11154 case 3:
11155 emit_insn (gen_cr6_test_for_lt_reverse (target));
11156 break;
11157 default:
11158 error ("argument 1 of __builtin_altivec_predicate is out of range");
11159 break;
11162 return target;
11165 static rtx
11166 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
11168 rtx pat, addr;
11169 tree arg0 = CALL_EXPR_ARG (exp, 0);
11170 tree arg1 = CALL_EXPR_ARG (exp, 1);
11171 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11172 enum machine_mode mode0 = Pmode;
11173 enum machine_mode mode1 = Pmode;
11174 rtx op0 = expand_normal (arg0);
11175 rtx op1 = expand_normal (arg1);
11177 if (icode == CODE_FOR_nothing)
11178 /* Builtin not supported on this processor. */
11179 return 0;
11181 /* If we got invalid arguments bail out before generating bad rtl. */
11182 if (arg0 == error_mark_node || arg1 == error_mark_node)
11183 return const0_rtx;
11185 if (target == 0
11186 || GET_MODE (target) != tmode
11187 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11188 target = gen_reg_rtx (tmode);
11190 op1 = copy_to_mode_reg (mode1, op1);
11192 if (op0 == const0_rtx)
11194 addr = gen_rtx_MEM (tmode, op1);
11196 else
11198 op0 = copy_to_mode_reg (mode0, op0);
11199 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
11202 pat = GEN_FCN (icode) (target, addr);
11204 if (! pat)
11205 return 0;
11206 emit_insn (pat);
11208 return target;
11211 static rtx
11212 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
11214 rtx pat, addr;
11215 tree arg0 = CALL_EXPR_ARG (exp, 0);
11216 tree arg1 = CALL_EXPR_ARG (exp, 1);
11217 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11218 enum machine_mode mode0 = Pmode;
11219 enum machine_mode mode1 = Pmode;
11220 rtx op0 = expand_normal (arg0);
11221 rtx op1 = expand_normal (arg1);
11223 if (icode == CODE_FOR_nothing)
11224 /* Builtin not supported on this processor. */
11225 return 0;
11227 /* If we got invalid arguments bail out before generating bad rtl. */
11228 if (arg0 == error_mark_node || arg1 == error_mark_node)
11229 return const0_rtx;
11231 if (target == 0
11232 || GET_MODE (target) != tmode
11233 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11234 target = gen_reg_rtx (tmode);
11236 op1 = copy_to_mode_reg (mode1, op1);
11238 if (op0 == const0_rtx)
11240 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
11242 else
11244 op0 = copy_to_mode_reg (mode0, op0);
11245 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
11248 pat = GEN_FCN (icode) (target, addr);
11250 if (! pat)
11251 return 0;
11252 emit_insn (pat);
11254 return target;
11257 static rtx
11258 spe_expand_stv_builtin (enum insn_code icode, tree exp)
11260 tree arg0 = CALL_EXPR_ARG (exp, 0);
11261 tree arg1 = CALL_EXPR_ARG (exp, 1);
11262 tree arg2 = CALL_EXPR_ARG (exp, 2);
11263 rtx op0 = expand_normal (arg0);
11264 rtx op1 = expand_normal (arg1);
11265 rtx op2 = expand_normal (arg2);
11266 rtx pat;
11267 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
11268 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
11269 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
11271 /* Invalid arguments. Bail before doing anything stoopid! */
11272 if (arg0 == error_mark_node
11273 || arg1 == error_mark_node
11274 || arg2 == error_mark_node)
11275 return const0_rtx;
11277 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
11278 op0 = copy_to_mode_reg (mode2, op0);
11279 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
11280 op1 = copy_to_mode_reg (mode0, op1);
11281 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
11282 op2 = copy_to_mode_reg (mode1, op2);
11284 pat = GEN_FCN (icode) (op1, op2, op0);
11285 if (pat)
11286 emit_insn (pat);
11287 return NULL_RTX;
11290 static rtx
11291 paired_expand_stv_builtin (enum insn_code icode, tree exp)
11293 tree arg0 = CALL_EXPR_ARG (exp, 0);
11294 tree arg1 = CALL_EXPR_ARG (exp, 1);
11295 tree arg2 = CALL_EXPR_ARG (exp, 2);
11296 rtx op0 = expand_normal (arg0);
11297 rtx op1 = expand_normal (arg1);
11298 rtx op2 = expand_normal (arg2);
11299 rtx pat, addr;
11300 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11301 enum machine_mode mode1 = Pmode;
11302 enum machine_mode mode2 = Pmode;
11304 /* Invalid arguments. Bail before doing anything stoopid! */
11305 if (arg0 == error_mark_node
11306 || arg1 == error_mark_node
11307 || arg2 == error_mark_node)
11308 return const0_rtx;
11310 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
11311 op0 = copy_to_mode_reg (tmode, op0);
11313 op2 = copy_to_mode_reg (mode2, op2);
11315 if (op1 == const0_rtx)
11317 addr = gen_rtx_MEM (tmode, op2);
11319 else
11321 op1 = copy_to_mode_reg (mode1, op1);
11322 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
11325 pat = GEN_FCN (icode) (addr, op0);
11326 if (pat)
11327 emit_insn (pat);
11328 return NULL_RTX;
11331 static rtx
11332 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
11334 tree arg0 = CALL_EXPR_ARG (exp, 0);
11335 tree arg1 = CALL_EXPR_ARG (exp, 1);
11336 tree arg2 = CALL_EXPR_ARG (exp, 2);
11337 rtx op0 = expand_normal (arg0);
11338 rtx op1 = expand_normal (arg1);
11339 rtx op2 = expand_normal (arg2);
11340 rtx pat, addr;
11341 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11342 enum machine_mode smode = insn_data[icode].operand[1].mode;
11343 enum machine_mode mode1 = Pmode;
11344 enum machine_mode mode2 = Pmode;
11346 /* Invalid arguments. Bail before doing anything stoopid! */
11347 if (arg0 == error_mark_node
11348 || arg1 == error_mark_node
11349 || arg2 == error_mark_node)
11350 return const0_rtx;
11352 if (! (*insn_data[icode].operand[1].predicate) (op0, smode))
11353 op0 = copy_to_mode_reg (smode, op0);
11355 op2 = copy_to_mode_reg (mode2, op2);
11357 if (op1 == const0_rtx)
11359 addr = gen_rtx_MEM (tmode, op2);
11361 else
11363 op1 = copy_to_mode_reg (mode1, op1);
11364 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
11367 pat = GEN_FCN (icode) (addr, op0);
11368 if (pat)
11369 emit_insn (pat);
11370 return NULL_RTX;
11373 static rtx
11374 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
11376 rtx pat;
11377 tree arg0 = CALL_EXPR_ARG (exp, 0);
11378 tree arg1 = CALL_EXPR_ARG (exp, 1);
11379 tree arg2 = CALL_EXPR_ARG (exp, 2);
11380 rtx op0 = expand_normal (arg0);
11381 rtx op1 = expand_normal (arg1);
11382 rtx op2 = expand_normal (arg2);
11383 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11384 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11385 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11386 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
11388 if (icode == CODE_FOR_nothing)
11389 /* Builtin not supported on this processor. */
11390 return 0;
11392 /* If we got invalid arguments bail out before generating bad rtl. */
11393 if (arg0 == error_mark_node
11394 || arg1 == error_mark_node
11395 || arg2 == error_mark_node)
11396 return const0_rtx;
11398 /* Check and prepare argument depending on the instruction code.
11400 Note that a switch statement instead of the sequence of tests
11401 would be incorrect as many of the CODE_FOR values could be
11402 CODE_FOR_nothing and that would yield multiple alternatives
11403 with identical values. We'd never reach here at runtime in
11404 this case. */
11405 if (icode == CODE_FOR_altivec_vsldoi_v4sf
11406 || icode == CODE_FOR_altivec_vsldoi_v4si
11407 || icode == CODE_FOR_altivec_vsldoi_v8hi
11408 || icode == CODE_FOR_altivec_vsldoi_v16qi)
11410 /* Only allow 4-bit unsigned literals. */
11411 STRIP_NOPS (arg2);
11412 if (TREE_CODE (arg2) != INTEGER_CST
11413 || TREE_INT_CST_LOW (arg2) & ~0xf)
11415 error ("argument 3 must be a 4-bit unsigned literal");
11416 return const0_rtx;
11419 else if (icode == CODE_FOR_vsx_xxpermdi_v2df
11420 || icode == CODE_FOR_vsx_xxpermdi_v2di
11421 || icode == CODE_FOR_vsx_xxsldwi_v16qi
11422 || icode == CODE_FOR_vsx_xxsldwi_v8hi
11423 || icode == CODE_FOR_vsx_xxsldwi_v4si
11424 || icode == CODE_FOR_vsx_xxsldwi_v4sf
11425 || icode == CODE_FOR_vsx_xxsldwi_v2di
11426 || icode == CODE_FOR_vsx_xxsldwi_v2df)
11428 /* Only allow 2-bit unsigned literals. */
11429 STRIP_NOPS (arg2);
11430 if (TREE_CODE (arg2) != INTEGER_CST
11431 || TREE_INT_CST_LOW (arg2) & ~0x3)
11433 error ("argument 3 must be a 2-bit unsigned literal");
11434 return const0_rtx;
11437 else if (icode == CODE_FOR_vsx_set_v2df
11438 || icode == CODE_FOR_vsx_set_v2di)
11440 /* Only allow 1-bit unsigned literals. */
11441 STRIP_NOPS (arg2);
11442 if (TREE_CODE (arg2) != INTEGER_CST
11443 || TREE_INT_CST_LOW (arg2) & ~0x1)
11445 error ("argument 3 must be a 1-bit unsigned literal");
11446 return const0_rtx;
11450 if (target == 0
11451 || GET_MODE (target) != tmode
11452 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11453 target = gen_reg_rtx (tmode);
11455 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11456 op0 = copy_to_mode_reg (mode0, op0);
11457 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11458 op1 = copy_to_mode_reg (mode1, op1);
11459 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
11460 op2 = copy_to_mode_reg (mode2, op2);
11462 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
11463 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
11464 else
11465 pat = GEN_FCN (icode) (target, op0, op1, op2);
11466 if (! pat)
11467 return 0;
11468 emit_insn (pat);
11470 return target;
11473 /* Expand the lvx builtins. */
11474 static rtx
11475 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
11477 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11478 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11479 tree arg0;
11480 enum machine_mode tmode, mode0;
11481 rtx pat, op0;
11482 enum insn_code icode;
11484 switch (fcode)
11486 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
11487 icode = CODE_FOR_vector_altivec_load_v16qi;
11488 break;
11489 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
11490 icode = CODE_FOR_vector_altivec_load_v8hi;
11491 break;
11492 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
11493 icode = CODE_FOR_vector_altivec_load_v4si;
11494 break;
11495 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
11496 icode = CODE_FOR_vector_altivec_load_v4sf;
11497 break;
11498 case ALTIVEC_BUILTIN_LD_INTERNAL_2df:
11499 icode = CODE_FOR_vector_altivec_load_v2df;
11500 break;
11501 case ALTIVEC_BUILTIN_LD_INTERNAL_2di:
11502 icode = CODE_FOR_vector_altivec_load_v2di;
11503 break;
11504 default:
11505 *expandedp = false;
11506 return NULL_RTX;
11509 *expandedp = true;
11511 arg0 = CALL_EXPR_ARG (exp, 0);
11512 op0 = expand_normal (arg0);
11513 tmode = insn_data[icode].operand[0].mode;
11514 mode0 = insn_data[icode].operand[1].mode;
11516 if (target == 0
11517 || GET_MODE (target) != tmode
11518 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11519 target = gen_reg_rtx (tmode);
11521 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11522 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11524 pat = GEN_FCN (icode) (target, op0);
11525 if (! pat)
11526 return 0;
11527 emit_insn (pat);
11528 return target;
11531 /* Expand the stvx builtins. */
11532 static rtx
11533 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
11534 bool *expandedp)
11536 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11537 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11538 tree arg0, arg1;
11539 enum machine_mode mode0, mode1;
11540 rtx pat, op0, op1;
11541 enum insn_code icode;
11543 switch (fcode)
11545 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
11546 icode = CODE_FOR_vector_altivec_store_v16qi;
11547 break;
11548 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
11549 icode = CODE_FOR_vector_altivec_store_v8hi;
11550 break;
11551 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
11552 icode = CODE_FOR_vector_altivec_store_v4si;
11553 break;
11554 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
11555 icode = CODE_FOR_vector_altivec_store_v4sf;
11556 break;
11557 case ALTIVEC_BUILTIN_ST_INTERNAL_2df:
11558 icode = CODE_FOR_vector_altivec_store_v2df;
11559 break;
11560 case ALTIVEC_BUILTIN_ST_INTERNAL_2di:
11561 icode = CODE_FOR_vector_altivec_store_v2di;
11562 break;
11563 default:
11564 *expandedp = false;
11565 return NULL_RTX;
11568 arg0 = CALL_EXPR_ARG (exp, 0);
11569 arg1 = CALL_EXPR_ARG (exp, 1);
11570 op0 = expand_normal (arg0);
11571 op1 = expand_normal (arg1);
11572 mode0 = insn_data[icode].operand[0].mode;
11573 mode1 = insn_data[icode].operand[1].mode;
11575 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11576 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11577 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11578 op1 = copy_to_mode_reg (mode1, op1);
11580 pat = GEN_FCN (icode) (op0, op1);
11581 if (pat)
11582 emit_insn (pat);
11584 *expandedp = true;
11585 return NULL_RTX;
11588 /* Expand the dst builtins. */
11589 static rtx
11590 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
11591 bool *expandedp)
11593 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11594 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11595 tree arg0, arg1, arg2;
11596 enum machine_mode mode0, mode1;
11597 rtx pat, op0, op1, op2;
11598 const struct builtin_description *d;
11599 size_t i;
11601 *expandedp = false;
11603 /* Handle DST variants. */
11604 d = bdesc_dst;
11605 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
11606 if (d->code == fcode)
11608 arg0 = CALL_EXPR_ARG (exp, 0);
11609 arg1 = CALL_EXPR_ARG (exp, 1);
11610 arg2 = CALL_EXPR_ARG (exp, 2);
11611 op0 = expand_normal (arg0);
11612 op1 = expand_normal (arg1);
11613 op2 = expand_normal (arg2);
11614 mode0 = insn_data[d->icode].operand[0].mode;
11615 mode1 = insn_data[d->icode].operand[1].mode;
11617 /* Invalid arguments, bail out before generating bad rtl. */
11618 if (arg0 == error_mark_node
11619 || arg1 == error_mark_node
11620 || arg2 == error_mark_node)
11621 return const0_rtx;
11623 *expandedp = true;
11624 STRIP_NOPS (arg2);
11625 if (TREE_CODE (arg2) != INTEGER_CST
11626 || TREE_INT_CST_LOW (arg2) & ~0x3)
11628 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
11629 return const0_rtx;
11632 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
11633 op0 = copy_to_mode_reg (Pmode, op0);
11634 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
11635 op1 = copy_to_mode_reg (mode1, op1);
11637 pat = GEN_FCN (d->icode) (op0, op1, op2);
11638 if (pat != 0)
11639 emit_insn (pat);
11641 return NULL_RTX;
11644 return NULL_RTX;
11647 /* Expand vec_init builtin. */
11648 static rtx
11649 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
11651 enum machine_mode tmode = TYPE_MODE (type);
11652 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
11653 int i, n_elt = GET_MODE_NUNITS (tmode);
11654 rtvec v = rtvec_alloc (n_elt);
11656 gcc_assert (VECTOR_MODE_P (tmode));
11657 gcc_assert (n_elt == call_expr_nargs (exp));
11659 for (i = 0; i < n_elt; ++i)
11661 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
11662 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
11665 if (!target || !register_operand (target, tmode))
11666 target = gen_reg_rtx (tmode);
11668 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
11669 return target;
11672 /* Return the integer constant in ARG. Constrain it to be in the range
11673 of the subparts of VEC_TYPE; issue an error if not. */
11675 static int
11676 get_element_number (tree vec_type, tree arg)
11678 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
11680 if (!host_integerp (arg, 1)
11681 || (elt = tree_low_cst (arg, 1), elt > max))
11683 error ("selector must be an integer constant in the range 0..%wi", max);
11684 return 0;
11687 return elt;
11690 /* Expand vec_set builtin. */
11691 static rtx
11692 altivec_expand_vec_set_builtin (tree exp)
11694 enum machine_mode tmode, mode1;
11695 tree arg0, arg1, arg2;
11696 int elt;
11697 rtx op0, op1;
11699 arg0 = CALL_EXPR_ARG (exp, 0);
11700 arg1 = CALL_EXPR_ARG (exp, 1);
11701 arg2 = CALL_EXPR_ARG (exp, 2);
11703 tmode = TYPE_MODE (TREE_TYPE (arg0));
11704 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11705 gcc_assert (VECTOR_MODE_P (tmode));
11707 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
11708 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
11709 elt = get_element_number (TREE_TYPE (arg0), arg2);
11711 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
11712 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
11714 op0 = force_reg (tmode, op0);
11715 op1 = force_reg (mode1, op1);
11717 rs6000_expand_vector_set (op0, op1, elt);
11719 return op0;
11722 /* Expand vec_ext builtin. */
11723 static rtx
11724 altivec_expand_vec_ext_builtin (tree exp, rtx target)
11726 enum machine_mode tmode, mode0;
11727 tree arg0, arg1;
11728 int elt;
11729 rtx op0;
11731 arg0 = CALL_EXPR_ARG (exp, 0);
11732 arg1 = CALL_EXPR_ARG (exp, 1);
11734 op0 = expand_normal (arg0);
11735 elt = get_element_number (TREE_TYPE (arg0), arg1);
11737 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11738 mode0 = TYPE_MODE (TREE_TYPE (arg0));
11739 gcc_assert (VECTOR_MODE_P (mode0));
11741 op0 = force_reg (mode0, op0);
11743 if (optimize || !target || !register_operand (target, tmode))
11744 target = gen_reg_rtx (tmode);
11746 rs6000_expand_vector_extract (target, op0, elt);
11748 return target;
11751 /* Expand the builtin in EXP and store the result in TARGET. Store
11752 true in *EXPANDEDP if we found a builtin to expand. */
11753 static rtx
11754 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
11756 const struct builtin_description *d;
11757 const struct builtin_description_predicates *dp;
11758 size_t i;
11759 enum insn_code icode;
11760 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11761 tree arg0;
11762 rtx op0, pat;
11763 enum machine_mode tmode, mode0;
11764 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11766 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11767 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11768 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
11769 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
11771 *expandedp = true;
11772 error ("unresolved overload for Altivec builtin %qF", fndecl);
11773 return const0_rtx;
11776 target = altivec_expand_ld_builtin (exp, target, expandedp);
11777 if (*expandedp)
11778 return target;
11780 target = altivec_expand_st_builtin (exp, target, expandedp);
11781 if (*expandedp)
11782 return target;
11784 target = altivec_expand_dst_builtin (exp, target, expandedp);
11785 if (*expandedp)
11786 return target;
11788 *expandedp = true;
11790 switch (fcode)
11792 case ALTIVEC_BUILTIN_STVX:
11793 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v4si, exp);
11794 case ALTIVEC_BUILTIN_STVEBX:
11795 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
11796 case ALTIVEC_BUILTIN_STVEHX:
11797 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
11798 case ALTIVEC_BUILTIN_STVEWX:
11799 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
11800 case ALTIVEC_BUILTIN_STVXL:
11801 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
11803 case ALTIVEC_BUILTIN_STVLX:
11804 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
11805 case ALTIVEC_BUILTIN_STVLXL:
11806 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
11807 case ALTIVEC_BUILTIN_STVRX:
11808 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
11809 case ALTIVEC_BUILTIN_STVRXL:
11810 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
11812 case VSX_BUILTIN_STXVD2X_V2DF:
11813 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2df, exp);
11814 case VSX_BUILTIN_STXVD2X_V2DI:
11815 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2di, exp);
11816 case VSX_BUILTIN_STXVW4X_V4SF:
11817 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4sf, exp);
11818 case VSX_BUILTIN_STXVW4X_V4SI:
11819 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4si, exp);
11820 case VSX_BUILTIN_STXVW4X_V8HI:
11821 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v8hi, exp);
11822 case VSX_BUILTIN_STXVW4X_V16QI:
11823 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v16qi, exp);
11825 case ALTIVEC_BUILTIN_MFVSCR:
11826 icode = CODE_FOR_altivec_mfvscr;
11827 tmode = insn_data[icode].operand[0].mode;
11829 if (target == 0
11830 || GET_MODE (target) != tmode
11831 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11832 target = gen_reg_rtx (tmode);
11834 pat = GEN_FCN (icode) (target);
11835 if (! pat)
11836 return 0;
11837 emit_insn (pat);
11838 return target;
11840 case ALTIVEC_BUILTIN_MTVSCR:
11841 icode = CODE_FOR_altivec_mtvscr;
11842 arg0 = CALL_EXPR_ARG (exp, 0);
11843 op0 = expand_normal (arg0);
11844 mode0 = insn_data[icode].operand[0].mode;
11846 /* If we got invalid arguments bail out before generating bad rtl. */
11847 if (arg0 == error_mark_node)
11848 return const0_rtx;
11850 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11851 op0 = copy_to_mode_reg (mode0, op0);
11853 pat = GEN_FCN (icode) (op0);
11854 if (pat)
11855 emit_insn (pat);
11856 return NULL_RTX;
11858 case ALTIVEC_BUILTIN_DSSALL:
11859 emit_insn (gen_altivec_dssall ());
11860 return NULL_RTX;
11862 case ALTIVEC_BUILTIN_DSS:
11863 icode = CODE_FOR_altivec_dss;
11864 arg0 = CALL_EXPR_ARG (exp, 0);
11865 STRIP_NOPS (arg0);
11866 op0 = expand_normal (arg0);
11867 mode0 = insn_data[icode].operand[0].mode;
11869 /* If we got invalid arguments bail out before generating bad rtl. */
11870 if (arg0 == error_mark_node)
11871 return const0_rtx;
11873 if (TREE_CODE (arg0) != INTEGER_CST
11874 || TREE_INT_CST_LOW (arg0) & ~0x3)
11876 error ("argument to dss must be a 2-bit unsigned literal");
11877 return const0_rtx;
11880 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11881 op0 = copy_to_mode_reg (mode0, op0);
11883 emit_insn (gen_altivec_dss (op0));
11884 return NULL_RTX;
11886 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
11887 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
11888 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
11889 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
11890 case VSX_BUILTIN_VEC_INIT_V2DF:
11891 case VSX_BUILTIN_VEC_INIT_V2DI:
11892 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
11894 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
11895 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
11896 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
11897 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
11898 case VSX_BUILTIN_VEC_SET_V2DF:
11899 case VSX_BUILTIN_VEC_SET_V2DI:
11900 return altivec_expand_vec_set_builtin (exp);
11902 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
11903 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
11904 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
11905 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
11906 case VSX_BUILTIN_VEC_EXT_V2DF:
11907 case VSX_BUILTIN_VEC_EXT_V2DI:
11908 return altivec_expand_vec_ext_builtin (exp, target);
11910 default:
11911 break;
11912 /* Fall through. */
11915 /* Expand abs* operations. */
11916 d = bdesc_abs;
11917 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11918 if (d->code == fcode)
11919 return altivec_expand_abs_builtin (d->icode, exp, target);
11921 /* Expand the AltiVec predicates. */
11922 dp = bdesc_altivec_preds;
11923 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11924 if (dp->code == fcode)
11925 return altivec_expand_predicate_builtin (dp->icode, exp, target);
11927 /* LV* are funky. We initialized them differently. */
11928 switch (fcode)
11930 case ALTIVEC_BUILTIN_LVSL:
11931 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
11932 exp, target, false);
11933 case ALTIVEC_BUILTIN_LVSR:
11934 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
11935 exp, target, false);
11936 case ALTIVEC_BUILTIN_LVEBX:
11937 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
11938 exp, target, false);
11939 case ALTIVEC_BUILTIN_LVEHX:
11940 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
11941 exp, target, false);
11942 case ALTIVEC_BUILTIN_LVEWX:
11943 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
11944 exp, target, false);
11945 case ALTIVEC_BUILTIN_LVXL:
11946 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
11947 exp, target, false);
11948 case ALTIVEC_BUILTIN_LVX:
11949 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v4si,
11950 exp, target, false);
11951 case ALTIVEC_BUILTIN_LVLX:
11952 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
11953 exp, target, true);
11954 case ALTIVEC_BUILTIN_LVLXL:
11955 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
11956 exp, target, true);
11957 case ALTIVEC_BUILTIN_LVRX:
11958 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
11959 exp, target, true);
11960 case ALTIVEC_BUILTIN_LVRXL:
11961 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
11962 exp, target, true);
11963 case VSX_BUILTIN_LXVD2X_V2DF:
11964 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2df,
11965 exp, target, false);
11966 case VSX_BUILTIN_LXVD2X_V2DI:
11967 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2di,
11968 exp, target, false);
11969 case VSX_BUILTIN_LXVW4X_V4SF:
11970 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4sf,
11971 exp, target, false);
11972 case VSX_BUILTIN_LXVW4X_V4SI:
11973 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4si,
11974 exp, target, false);
11975 case VSX_BUILTIN_LXVW4X_V8HI:
11976 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v8hi,
11977 exp, target, false);
11978 case VSX_BUILTIN_LXVW4X_V16QI:
11979 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v16qi,
11980 exp, target, false);
11981 break;
11982 default:
11983 break;
11984 /* Fall through. */
11987 *expandedp = false;
11988 return NULL_RTX;
11991 /* Expand the builtin in EXP and store the result in TARGET. Store
11992 true in *EXPANDEDP if we found a builtin to expand. */
11993 static rtx
11994 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
11996 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11997 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11998 const struct builtin_description *d;
11999 size_t i;
12001 *expandedp = true;
12003 switch (fcode)
12005 case PAIRED_BUILTIN_STX:
12006 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
12007 case PAIRED_BUILTIN_LX:
12008 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
12009 default:
12010 break;
12011 /* Fall through. */
12014 /* Expand the paired predicates. */
12015 d = bdesc_paired_preds;
12016 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
12017 if (d->code == fcode)
12018 return paired_expand_predicate_builtin (d->icode, exp, target);
12020 *expandedp = false;
12021 return NULL_RTX;
12024 /* Binops that need to be initialized manually, but can be expanded
12025 automagically by rs6000_expand_binop_builtin. */
12026 static struct builtin_description bdesc_2arg_spe[] =
12028 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
12029 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
12030 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
12031 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
12032 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
12033 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
12034 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
12035 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
12036 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
12037 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
12038 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
12039 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
12040 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
12041 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
12042 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
12043 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
12044 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
12045 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
12046 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
12047 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
12048 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
12049 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
12052 /* Expand the builtin in EXP and store the result in TARGET. Store
12053 true in *EXPANDEDP if we found a builtin to expand.
12055 This expands the SPE builtins that are not simple unary and binary
12056 operations. */
12057 static rtx
12058 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
12060 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
12061 tree arg1, arg0;
12062 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
12063 enum insn_code icode;
12064 enum machine_mode tmode, mode0;
12065 rtx pat, op0;
12066 struct builtin_description *d;
12067 size_t i;
12069 *expandedp = true;
12071 /* Syntax check for a 5-bit unsigned immediate. */
12072 switch (fcode)
12074 case SPE_BUILTIN_EVSTDD:
12075 case SPE_BUILTIN_EVSTDH:
12076 case SPE_BUILTIN_EVSTDW:
12077 case SPE_BUILTIN_EVSTWHE:
12078 case SPE_BUILTIN_EVSTWHO:
12079 case SPE_BUILTIN_EVSTWWE:
12080 case SPE_BUILTIN_EVSTWWO:
12081 arg1 = CALL_EXPR_ARG (exp, 2);
12082 if (TREE_CODE (arg1) != INTEGER_CST
12083 || TREE_INT_CST_LOW (arg1) & ~0x1f)
12085 error ("argument 2 must be a 5-bit unsigned literal");
12086 return const0_rtx;
12088 break;
12089 default:
12090 break;
12093 /* The evsplat*i instructions are not quite generic. */
12094 switch (fcode)
12096 case SPE_BUILTIN_EVSPLATFI:
12097 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
12098 exp, target);
12099 case SPE_BUILTIN_EVSPLATI:
12100 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
12101 exp, target);
12102 default:
12103 break;
12106 d = (struct builtin_description *) bdesc_2arg_spe;
12107 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
12108 if (d->code == fcode)
12109 return rs6000_expand_binop_builtin (d->icode, exp, target);
12111 d = (struct builtin_description *) bdesc_spe_predicates;
12112 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
12113 if (d->code == fcode)
12114 return spe_expand_predicate_builtin (d->icode, exp, target);
12116 d = (struct builtin_description *) bdesc_spe_evsel;
12117 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
12118 if (d->code == fcode)
12119 return spe_expand_evsel_builtin (d->icode, exp, target);
12121 switch (fcode)
12123 case SPE_BUILTIN_EVSTDDX:
12124 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
12125 case SPE_BUILTIN_EVSTDHX:
12126 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
12127 case SPE_BUILTIN_EVSTDWX:
12128 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
12129 case SPE_BUILTIN_EVSTWHEX:
12130 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
12131 case SPE_BUILTIN_EVSTWHOX:
12132 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
12133 case SPE_BUILTIN_EVSTWWEX:
12134 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
12135 case SPE_BUILTIN_EVSTWWOX:
12136 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
12137 case SPE_BUILTIN_EVSTDD:
12138 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
12139 case SPE_BUILTIN_EVSTDH:
12140 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
12141 case SPE_BUILTIN_EVSTDW:
12142 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
12143 case SPE_BUILTIN_EVSTWHE:
12144 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
12145 case SPE_BUILTIN_EVSTWHO:
12146 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
12147 case SPE_BUILTIN_EVSTWWE:
12148 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
12149 case SPE_BUILTIN_EVSTWWO:
12150 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
12151 case SPE_BUILTIN_MFSPEFSCR:
12152 icode = CODE_FOR_spe_mfspefscr;
12153 tmode = insn_data[icode].operand[0].mode;
12155 if (target == 0
12156 || GET_MODE (target) != tmode
12157 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
12158 target = gen_reg_rtx (tmode);
12160 pat = GEN_FCN (icode) (target);
12161 if (! pat)
12162 return 0;
12163 emit_insn (pat);
12164 return target;
12165 case SPE_BUILTIN_MTSPEFSCR:
12166 icode = CODE_FOR_spe_mtspefscr;
12167 arg0 = CALL_EXPR_ARG (exp, 0);
12168 op0 = expand_normal (arg0);
12169 mode0 = insn_data[icode].operand[0].mode;
12171 if (arg0 == error_mark_node)
12172 return const0_rtx;
12174 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
12175 op0 = copy_to_mode_reg (mode0, op0);
12177 pat = GEN_FCN (icode) (op0);
12178 if (pat)
12179 emit_insn (pat);
12180 return NULL_RTX;
12181 default:
12182 break;
12185 *expandedp = false;
12186 return NULL_RTX;
12189 static rtx
12190 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
12192 rtx pat, scratch, tmp;
12193 tree form = CALL_EXPR_ARG (exp, 0);
12194 tree arg0 = CALL_EXPR_ARG (exp, 1);
12195 tree arg1 = CALL_EXPR_ARG (exp, 2);
12196 rtx op0 = expand_normal (arg0);
12197 rtx op1 = expand_normal (arg1);
12198 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
12199 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
12200 int form_int;
12201 enum rtx_code code;
12203 if (TREE_CODE (form) != INTEGER_CST)
12205 error ("argument 1 of __builtin_paired_predicate must be a constant");
12206 return const0_rtx;
12208 else
12209 form_int = TREE_INT_CST_LOW (form);
12211 gcc_assert (mode0 == mode1);
12213 if (arg0 == error_mark_node || arg1 == error_mark_node)
12214 return const0_rtx;
12216 if (target == 0
12217 || GET_MODE (target) != SImode
12218 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
12219 target = gen_reg_rtx (SImode);
12220 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
12221 op0 = copy_to_mode_reg (mode0, op0);
12222 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
12223 op1 = copy_to_mode_reg (mode1, op1);
12225 scratch = gen_reg_rtx (CCFPmode);
12227 pat = GEN_FCN (icode) (scratch, op0, op1);
12228 if (!pat)
12229 return const0_rtx;
12231 emit_insn (pat);
12233 switch (form_int)
12235 /* LT bit. */
12236 case 0:
12237 code = LT;
12238 break;
12239 /* GT bit. */
12240 case 1:
12241 code = GT;
12242 break;
12243 /* EQ bit. */
12244 case 2:
12245 code = EQ;
12246 break;
12247 /* UN bit. */
12248 case 3:
12249 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
12250 return target;
12251 default:
12252 error ("argument 1 of __builtin_paired_predicate is out of range");
12253 return const0_rtx;
12256 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
12257 emit_move_insn (target, tmp);
12258 return target;
12261 static rtx
12262 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
12264 rtx pat, scratch, tmp;
12265 tree form = CALL_EXPR_ARG (exp, 0);
12266 tree arg0 = CALL_EXPR_ARG (exp, 1);
12267 tree arg1 = CALL_EXPR_ARG (exp, 2);
12268 rtx op0 = expand_normal (arg0);
12269 rtx op1 = expand_normal (arg1);
12270 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
12271 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
12272 int form_int;
12273 enum rtx_code code;
12275 if (TREE_CODE (form) != INTEGER_CST)
12277 error ("argument 1 of __builtin_spe_predicate must be a constant");
12278 return const0_rtx;
12280 else
12281 form_int = TREE_INT_CST_LOW (form);
12283 gcc_assert (mode0 == mode1);
12285 if (arg0 == error_mark_node || arg1 == error_mark_node)
12286 return const0_rtx;
12288 if (target == 0
12289 || GET_MODE (target) != SImode
12290 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
12291 target = gen_reg_rtx (SImode);
12293 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
12294 op0 = copy_to_mode_reg (mode0, op0);
12295 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
12296 op1 = copy_to_mode_reg (mode1, op1);
12298 scratch = gen_reg_rtx (CCmode);
12300 pat = GEN_FCN (icode) (scratch, op0, op1);
12301 if (! pat)
12302 return const0_rtx;
12303 emit_insn (pat);
12305 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
12306 _lower_. We use one compare, but look in different bits of the
12307 CR for each variant.
12309 There are 2 elements in each SPE simd type (upper/lower). The CR
12310 bits are set as follows:
12312 BIT0 | BIT 1 | BIT 2 | BIT 3
12313 U | L | (U | L) | (U & L)
12315 So, for an "all" relationship, BIT 3 would be set.
12316 For an "any" relationship, BIT 2 would be set. Etc.
12318 Following traditional nomenclature, these bits map to:
12320 BIT0 | BIT 1 | BIT 2 | BIT 3
12321 LT | GT | EQ | OV
12323 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
12326 switch (form_int)
12328 /* All variant. OV bit. */
12329 case 0:
12330 /* We need to get to the OV bit, which is the ORDERED bit. We
12331 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
12332 that's ugly and will make validate_condition_mode die.
12333 So let's just use another pattern. */
12334 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
12335 return target;
12336 /* Any variant. EQ bit. */
12337 case 1:
12338 code = EQ;
12339 break;
12340 /* Upper variant. LT bit. */
12341 case 2:
12342 code = LT;
12343 break;
12344 /* Lower variant. GT bit. */
12345 case 3:
12346 code = GT;
12347 break;
12348 default:
12349 error ("argument 1 of __builtin_spe_predicate is out of range");
12350 return const0_rtx;
12353 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
12354 emit_move_insn (target, tmp);
12356 return target;
12359 /* The evsel builtins look like this:
12361 e = __builtin_spe_evsel_OP (a, b, c, d);
12363 and work like this:
12365 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
12366 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
12369 static rtx
12370 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
12372 rtx pat, scratch;
12373 tree arg0 = CALL_EXPR_ARG (exp, 0);
12374 tree arg1 = CALL_EXPR_ARG (exp, 1);
12375 tree arg2 = CALL_EXPR_ARG (exp, 2);
12376 tree arg3 = CALL_EXPR_ARG (exp, 3);
12377 rtx op0 = expand_normal (arg0);
12378 rtx op1 = expand_normal (arg1);
12379 rtx op2 = expand_normal (arg2);
12380 rtx op3 = expand_normal (arg3);
12381 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
12382 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
12384 gcc_assert (mode0 == mode1);
12386 if (arg0 == error_mark_node || arg1 == error_mark_node
12387 || arg2 == error_mark_node || arg3 == error_mark_node)
12388 return const0_rtx;
12390 if (target == 0
12391 || GET_MODE (target) != mode0
12392 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
12393 target = gen_reg_rtx (mode0);
12395 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
12396 op0 = copy_to_mode_reg (mode0, op0);
12397 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
12398 op1 = copy_to_mode_reg (mode0, op1);
12399 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
12400 op2 = copy_to_mode_reg (mode0, op2);
12401 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
12402 op3 = copy_to_mode_reg (mode0, op3);
12404 /* Generate the compare. */
12405 scratch = gen_reg_rtx (CCmode);
12406 pat = GEN_FCN (icode) (scratch, op0, op1);
12407 if (! pat)
12408 return const0_rtx;
12409 emit_insn (pat);
12411 if (mode0 == V2SImode)
12412 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
12413 else
12414 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
12416 return target;
12419 /* Expand an expression EXP that calls a built-in function,
12420 with result going to TARGET if that's convenient
12421 (and in mode MODE if that's convenient).
12422 SUBTARGET may be used as the target for computing one of EXP's operands.
12423 IGNORE is nonzero if the value is to be ignored. */
12425 static rtx
12426 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
12427 enum machine_mode mode ATTRIBUTE_UNUSED,
12428 int ignore ATTRIBUTE_UNUSED)
12430 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
12431 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
12432 const struct builtin_description *d;
12433 size_t i;
12434 rtx ret;
12435 bool success;
12437 switch (fcode)
12439 case RS6000_BUILTIN_RECIP:
12440 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
12442 case RS6000_BUILTIN_RECIPF:
12443 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
12445 case RS6000_BUILTIN_RSQRTF:
12446 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
12448 case RS6000_BUILTIN_RSQRT:
12449 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2, exp, target);
12451 case RS6000_BUILTIN_BSWAP_HI:
12452 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
12454 case POWER7_BUILTIN_BPERMD:
12455 return rs6000_expand_binop_builtin (((TARGET_64BIT)
12456 ? CODE_FOR_bpermd_di
12457 : CODE_FOR_bpermd_si), exp, target);
12459 case ALTIVEC_BUILTIN_MASK_FOR_LOAD:
12460 case ALTIVEC_BUILTIN_MASK_FOR_STORE:
12462 int icode = (int) CODE_FOR_altivec_lvsr;
12463 enum machine_mode tmode = insn_data[icode].operand[0].mode;
12464 enum machine_mode mode = insn_data[icode].operand[1].mode;
12465 tree arg;
12466 rtx op, addr, pat;
12468 gcc_assert (TARGET_ALTIVEC);
12470 arg = CALL_EXPR_ARG (exp, 0);
12471 gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg)));
12472 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
12473 addr = memory_address (mode, op);
12474 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
12475 op = addr;
12476 else
12478 /* For the load case need to negate the address. */
12479 op = gen_reg_rtx (GET_MODE (addr));
12480 emit_insn (gen_rtx_SET (VOIDmode, op,
12481 gen_rtx_NEG (GET_MODE (addr), addr)));
12483 op = gen_rtx_MEM (mode, op);
12485 if (target == 0
12486 || GET_MODE (target) != tmode
12487 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
12488 target = gen_reg_rtx (tmode);
12490 /*pat = gen_altivec_lvsr (target, op);*/
12491 pat = GEN_FCN (icode) (target, op);
12492 if (!pat)
12493 return 0;
12494 emit_insn (pat);
12496 return target;
12499 case ALTIVEC_BUILTIN_VCFUX:
12500 case ALTIVEC_BUILTIN_VCFSX:
12501 case ALTIVEC_BUILTIN_VCTUXS:
12502 case ALTIVEC_BUILTIN_VCTSXS:
12503 /* FIXME: There's got to be a nicer way to handle this case than
12504 constructing a new CALL_EXPR. */
12505 if (call_expr_nargs (exp) == 1)
12507 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
12508 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
12510 break;
12512 default:
12513 break;
12516 if (TARGET_ALTIVEC)
12518 ret = altivec_expand_builtin (exp, target, &success);
12520 if (success)
12521 return ret;
12523 if (TARGET_SPE)
12525 ret = spe_expand_builtin (exp, target, &success);
12527 if (success)
12528 return ret;
12530 if (TARGET_PAIRED_FLOAT)
12532 ret = paired_expand_builtin (exp, target, &success);
12534 if (success)
12535 return ret;
12538 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
12540 /* Handle simple unary operations. */
12541 d = (struct builtin_description *) bdesc_1arg;
12542 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
12543 if (d->code == fcode)
12544 return rs6000_expand_unop_builtin (d->icode, exp, target);
12546 /* Handle simple binary operations. */
12547 d = (struct builtin_description *) bdesc_2arg;
12548 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
12549 if (d->code == fcode)
12550 return rs6000_expand_binop_builtin (d->icode, exp, target);
12552 /* Handle simple ternary operations. */
12553 d = bdesc_3arg;
12554 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
12555 if (d->code == fcode)
12556 return rs6000_expand_ternop_builtin (d->icode, exp, target);
12558 gcc_unreachable ();
12561 static void
12562 rs6000_init_builtins (void)
12564 tree tdecl;
12565 tree ftype;
12567 V2SI_type_node = build_vector_type (intSI_type_node, 2);
12568 V2SF_type_node = build_vector_type (float_type_node, 2);
12569 V2DI_type_node = build_vector_type (intDI_type_node, 2);
12570 V2DF_type_node = build_vector_type (double_type_node, 2);
12571 V4HI_type_node = build_vector_type (intHI_type_node, 4);
12572 V4SI_type_node = build_vector_type (intSI_type_node, 4);
12573 V4SF_type_node = build_vector_type (float_type_node, 4);
12574 V8HI_type_node = build_vector_type (intHI_type_node, 8);
12575 V16QI_type_node = build_vector_type (intQI_type_node, 16);
12577 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
12578 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
12579 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
12580 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
12582 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
12583 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
12584 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
12585 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
12587 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
12588 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
12589 'vector unsigned short'. */
12591 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
12592 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12593 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
12594 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
12595 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12597 long_integer_type_internal_node = long_integer_type_node;
12598 long_unsigned_type_internal_node = long_unsigned_type_node;
12599 long_long_integer_type_internal_node = long_long_integer_type_node;
12600 long_long_unsigned_type_internal_node = long_long_unsigned_type_node;
12601 intQI_type_internal_node = intQI_type_node;
12602 uintQI_type_internal_node = unsigned_intQI_type_node;
12603 intHI_type_internal_node = intHI_type_node;
12604 uintHI_type_internal_node = unsigned_intHI_type_node;
12605 intSI_type_internal_node = intSI_type_node;
12606 uintSI_type_internal_node = unsigned_intSI_type_node;
12607 intDI_type_internal_node = intDI_type_node;
12608 uintDI_type_internal_node = unsigned_intDI_type_node;
12609 float_type_internal_node = float_type_node;
12610 double_type_internal_node = double_type_node;
12611 void_type_internal_node = void_type_node;
12613 /* Initialize the modes for builtin_function_type, mapping a machine mode to
12614 tree type node. */
12615 builtin_mode_to_type[QImode][0] = integer_type_node;
12616 builtin_mode_to_type[HImode][0] = integer_type_node;
12617 builtin_mode_to_type[SImode][0] = intSI_type_node;
12618 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
12619 builtin_mode_to_type[DImode][0] = intDI_type_node;
12620 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
12621 builtin_mode_to_type[SFmode][0] = float_type_node;
12622 builtin_mode_to_type[DFmode][0] = double_type_node;
12623 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
12624 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
12625 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
12626 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
12627 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
12628 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
12629 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
12630 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
12631 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
12632 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
12633 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
12634 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
12635 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
12637 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12638 get_identifier ("__bool char"),
12639 bool_char_type_node);
12640 TYPE_NAME (bool_char_type_node) = tdecl;
12641 (*lang_hooks.decls.pushdecl) (tdecl);
12642 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12643 get_identifier ("__bool short"),
12644 bool_short_type_node);
12645 TYPE_NAME (bool_short_type_node) = tdecl;
12646 (*lang_hooks.decls.pushdecl) (tdecl);
12647 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12648 get_identifier ("__bool int"),
12649 bool_int_type_node);
12650 TYPE_NAME (bool_int_type_node) = tdecl;
12651 (*lang_hooks.decls.pushdecl) (tdecl);
12652 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
12653 pixel_type_node);
12654 TYPE_NAME (pixel_type_node) = tdecl;
12655 (*lang_hooks.decls.pushdecl) (tdecl);
12657 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
12658 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
12659 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
12660 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
12661 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
12663 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12664 get_identifier ("__vector unsigned char"),
12665 unsigned_V16QI_type_node);
12666 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
12667 (*lang_hooks.decls.pushdecl) (tdecl);
12668 tdecl = build_decl (BUILTINS_LOCATION,
12669 TYPE_DECL, get_identifier ("__vector signed char"),
12670 V16QI_type_node);
12671 TYPE_NAME (V16QI_type_node) = tdecl;
12672 (*lang_hooks.decls.pushdecl) (tdecl);
12673 tdecl = build_decl (BUILTINS_LOCATION,
12674 TYPE_DECL, get_identifier ("__vector __bool char"),
12675 bool_V16QI_type_node);
12676 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
12677 (*lang_hooks.decls.pushdecl) (tdecl);
12679 tdecl = build_decl (BUILTINS_LOCATION,
12680 TYPE_DECL, get_identifier ("__vector unsigned short"),
12681 unsigned_V8HI_type_node);
12682 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
12683 (*lang_hooks.decls.pushdecl) (tdecl);
12684 tdecl = build_decl (BUILTINS_LOCATION,
12685 TYPE_DECL, get_identifier ("__vector signed short"),
12686 V8HI_type_node);
12687 TYPE_NAME (V8HI_type_node) = tdecl;
12688 (*lang_hooks.decls.pushdecl) (tdecl);
12689 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12690 get_identifier ("__vector __bool short"),
12691 bool_V8HI_type_node);
12692 TYPE_NAME (bool_V8HI_type_node) = tdecl;
12693 (*lang_hooks.decls.pushdecl) (tdecl);
12695 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12696 get_identifier ("__vector unsigned int"),
12697 unsigned_V4SI_type_node);
12698 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
12699 (*lang_hooks.decls.pushdecl) (tdecl);
12700 tdecl = build_decl (BUILTINS_LOCATION,
12701 TYPE_DECL, get_identifier ("__vector signed int"),
12702 V4SI_type_node);
12703 TYPE_NAME (V4SI_type_node) = tdecl;
12704 (*lang_hooks.decls.pushdecl) (tdecl);
12705 tdecl = build_decl (BUILTINS_LOCATION,
12706 TYPE_DECL, get_identifier ("__vector __bool int"),
12707 bool_V4SI_type_node);
12708 TYPE_NAME (bool_V4SI_type_node) = tdecl;
12709 (*lang_hooks.decls.pushdecl) (tdecl);
12711 tdecl = build_decl (BUILTINS_LOCATION,
12712 TYPE_DECL, get_identifier ("__vector float"),
12713 V4SF_type_node);
12714 TYPE_NAME (V4SF_type_node) = tdecl;
12715 (*lang_hooks.decls.pushdecl) (tdecl);
12716 tdecl = build_decl (BUILTINS_LOCATION,
12717 TYPE_DECL, get_identifier ("__vector __pixel"),
12718 pixel_V8HI_type_node);
12719 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
12720 (*lang_hooks.decls.pushdecl) (tdecl);
12722 if (TARGET_VSX)
12724 tdecl = build_decl (BUILTINS_LOCATION,
12725 TYPE_DECL, get_identifier ("__vector double"),
12726 V2DF_type_node);
12727 TYPE_NAME (V2DF_type_node) = tdecl;
12728 (*lang_hooks.decls.pushdecl) (tdecl);
12730 tdecl = build_decl (BUILTINS_LOCATION,
12731 TYPE_DECL, get_identifier ("__vector long"),
12732 V2DI_type_node);
12733 TYPE_NAME (V2DI_type_node) = tdecl;
12734 (*lang_hooks.decls.pushdecl) (tdecl);
12736 tdecl = build_decl (BUILTINS_LOCATION,
12737 TYPE_DECL, get_identifier ("__vector unsigned long"),
12738 unsigned_V2DI_type_node);
12739 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
12740 (*lang_hooks.decls.pushdecl) (tdecl);
12742 tdecl = build_decl (BUILTINS_LOCATION,
12743 TYPE_DECL, get_identifier ("__vector __bool long"),
12744 bool_V2DI_type_node);
12745 TYPE_NAME (bool_V2DI_type_node) = tdecl;
12746 (*lang_hooks.decls.pushdecl) (tdecl);
12749 if (TARGET_PAIRED_FLOAT)
12750 paired_init_builtins ();
12751 if (TARGET_SPE)
12752 spe_init_builtins ();
12753 if (TARGET_ALTIVEC)
12754 altivec_init_builtins ();
12755 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
12756 rs6000_common_init_builtins ();
12757 if (TARGET_FRE)
12759 ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
12760 RS6000_BUILTIN_RECIP,
12761 "__builtin_recipdiv");
12762 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
12763 RS6000_BUILTIN_RECIP);
12765 if (TARGET_FRES)
12767 ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
12768 RS6000_BUILTIN_RECIPF,
12769 "__builtin_recipdivf");
12770 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
12771 RS6000_BUILTIN_RECIPF);
12773 if (TARGET_FRSQRTE)
12775 ftype = builtin_function_type (DFmode, DFmode, VOIDmode, VOIDmode,
12776 RS6000_BUILTIN_RSQRT,
12777 "__builtin_rsqrt");
12778 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrt", ftype,
12779 RS6000_BUILTIN_RSQRT);
12781 if (TARGET_FRSQRTES)
12783 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
12784 RS6000_BUILTIN_RSQRTF,
12785 "__builtin_rsqrtf");
12786 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
12787 RS6000_BUILTIN_RSQRTF);
12789 if (TARGET_POPCNTD)
12791 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
12792 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
12793 POWER7_BUILTIN_BPERMD,
12794 "__builtin_bpermd");
12795 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
12796 POWER7_BUILTIN_BPERMD);
12798 if (TARGET_POWERPC)
12800 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
12801 tree ftype = build_function_type_list (unsigned_intHI_type_node,
12802 unsigned_intHI_type_node,
12803 NULL_TREE);
12804 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
12805 RS6000_BUILTIN_BSWAP_HI);
12808 #if TARGET_XCOFF
12809 /* AIX libm provides clog as __clog. */
12810 if (built_in_decls [BUILT_IN_CLOG])
12811 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
12812 #endif
12814 #ifdef SUBTARGET_INIT_BUILTINS
12815 SUBTARGET_INIT_BUILTINS;
12816 #endif
12819 /* Returns the rs6000 builtin decl for CODE. */
12821 static tree
12822 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
12824 if (code >= RS6000_BUILTIN_COUNT)
12825 return error_mark_node;
12827 return rs6000_builtin_decls[code];
12830 /* Search through a set of builtins and enable the mask bits.
12831 DESC is an array of builtins.
12832 SIZE is the total number of builtins.
12833 START is the builtin enum at which to start.
12834 END is the builtin enum at which to end. */
12835 static void
12836 enable_mask_for_builtins (struct builtin_description *desc, int size,
12837 enum rs6000_builtins start,
12838 enum rs6000_builtins end)
12840 int i;
12842 for (i = 0; i < size; ++i)
12843 if (desc[i].code == start)
12844 break;
12846 if (i == size)
12847 return;
12849 for (; i < size; ++i)
12851 /* Flip all the bits on. */
12852 desc[i].mask = target_flags;
12853 if (desc[i].code == end)
12854 break;
12858 static void
12859 spe_init_builtins (void)
12861 tree endlink = void_list_node;
12862 tree puint_type_node = build_pointer_type (unsigned_type_node);
12863 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
12864 struct builtin_description *d;
12865 size_t i;
12867 tree v2si_ftype_4_v2si
12868 = build_function_type
12869 (opaque_V2SI_type_node,
12870 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12871 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12872 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12873 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12874 endlink)))));
12876 tree v2sf_ftype_4_v2sf
12877 = build_function_type
12878 (opaque_V2SF_type_node,
12879 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12880 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12881 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12882 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12883 endlink)))));
12885 tree int_ftype_int_v2si_v2si
12886 = build_function_type
12887 (integer_type_node,
12888 tree_cons (NULL_TREE, integer_type_node,
12889 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12890 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12891 endlink))));
12893 tree int_ftype_int_v2sf_v2sf
12894 = build_function_type
12895 (integer_type_node,
12896 tree_cons (NULL_TREE, integer_type_node,
12897 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12898 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12899 endlink))));
12901 tree void_ftype_v2si_puint_int
12902 = build_function_type (void_type_node,
12903 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12904 tree_cons (NULL_TREE, puint_type_node,
12905 tree_cons (NULL_TREE,
12906 integer_type_node,
12907 endlink))));
12909 tree void_ftype_v2si_puint_char
12910 = build_function_type (void_type_node,
12911 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12912 tree_cons (NULL_TREE, puint_type_node,
12913 tree_cons (NULL_TREE,
12914 char_type_node,
12915 endlink))));
12917 tree void_ftype_v2si_pv2si_int
12918 = build_function_type (void_type_node,
12919 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12920 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12921 tree_cons (NULL_TREE,
12922 integer_type_node,
12923 endlink))));
12925 tree void_ftype_v2si_pv2si_char
12926 = build_function_type (void_type_node,
12927 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12928 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12929 tree_cons (NULL_TREE,
12930 char_type_node,
12931 endlink))));
12933 tree void_ftype_int
12934 = build_function_type (void_type_node,
12935 tree_cons (NULL_TREE, integer_type_node, endlink));
12937 tree int_ftype_void
12938 = build_function_type (integer_type_node, endlink);
12940 tree v2si_ftype_pv2si_int
12941 = build_function_type (opaque_V2SI_type_node,
12942 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12943 tree_cons (NULL_TREE, integer_type_node,
12944 endlink)));
12946 tree v2si_ftype_puint_int
12947 = build_function_type (opaque_V2SI_type_node,
12948 tree_cons (NULL_TREE, puint_type_node,
12949 tree_cons (NULL_TREE, integer_type_node,
12950 endlink)));
12952 tree v2si_ftype_pushort_int
12953 = build_function_type (opaque_V2SI_type_node,
12954 tree_cons (NULL_TREE, pushort_type_node,
12955 tree_cons (NULL_TREE, integer_type_node,
12956 endlink)));
12958 tree v2si_ftype_signed_char
12959 = build_function_type (opaque_V2SI_type_node,
12960 tree_cons (NULL_TREE, signed_char_type_node,
12961 endlink));
12963 /* The initialization of the simple binary and unary builtins is
12964 done in rs6000_common_init_builtins, but we have to enable the
12965 mask bits here manually because we have run out of `target_flags'
12966 bits. We really need to redesign this mask business. */
12968 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
12969 ARRAY_SIZE (bdesc_2arg),
12970 SPE_BUILTIN_EVADDW,
12971 SPE_BUILTIN_EVXOR);
12972 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
12973 ARRAY_SIZE (bdesc_1arg),
12974 SPE_BUILTIN_EVABS,
12975 SPE_BUILTIN_EVSUBFUSIAAW);
12976 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
12977 ARRAY_SIZE (bdesc_spe_predicates),
12978 SPE_BUILTIN_EVCMPEQ,
12979 SPE_BUILTIN_EVFSTSTLT);
12980 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
12981 ARRAY_SIZE (bdesc_spe_evsel),
12982 SPE_BUILTIN_EVSEL_CMPGTS,
12983 SPE_BUILTIN_EVSEL_FSTSTEQ);
12985 (*lang_hooks.decls.pushdecl)
12986 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
12987 get_identifier ("__ev64_opaque__"),
12988 opaque_V2SI_type_node));
12990 /* Initialize irregular SPE builtins. */
12992 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
12993 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
12994 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
12995 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
12996 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
12997 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
12998 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
12999 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
13000 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
13001 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
13002 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
13003 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
13004 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
13005 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
13006 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
13007 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
13008 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
13009 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
13011 /* Loads. */
13012 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
13013 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
13014 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
13015 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
13016 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
13017 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
13018 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
13019 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
13020 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
13021 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
13022 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
13023 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
13024 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
13025 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
13026 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
13027 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
13028 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
13029 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
13030 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
13031 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
13032 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
13033 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
13035 /* Predicates. */
13036 d = (struct builtin_description *) bdesc_spe_predicates;
13037 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
13039 tree type;
13041 switch (insn_data[d->icode].operand[1].mode)
13043 case V2SImode:
13044 type = int_ftype_int_v2si_v2si;
13045 break;
13046 case V2SFmode:
13047 type = int_ftype_int_v2sf_v2sf;
13048 break;
13049 default:
13050 gcc_unreachable ();
13053 def_builtin (d->mask, d->name, type, d->code);
13056 /* Evsel predicates. */
13057 d = (struct builtin_description *) bdesc_spe_evsel;
13058 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
13060 tree type;
13062 switch (insn_data[d->icode].operand[1].mode)
13064 case V2SImode:
13065 type = v2si_ftype_4_v2si;
13066 break;
13067 case V2SFmode:
13068 type = v2sf_ftype_4_v2sf;
13069 break;
13070 default:
13071 gcc_unreachable ();
13074 def_builtin (d->mask, d->name, type, d->code);
13078 static void
13079 paired_init_builtins (void)
13081 const struct builtin_description *d;
13082 size_t i;
13083 tree endlink = void_list_node;
13085 tree int_ftype_int_v2sf_v2sf
13086 = build_function_type
13087 (integer_type_node,
13088 tree_cons (NULL_TREE, integer_type_node,
13089 tree_cons (NULL_TREE, V2SF_type_node,
13090 tree_cons (NULL_TREE, V2SF_type_node,
13091 endlink))));
13092 tree pcfloat_type_node =
13093 build_pointer_type (build_qualified_type
13094 (float_type_node, TYPE_QUAL_CONST));
13096 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
13097 long_integer_type_node,
13098 pcfloat_type_node,
13099 NULL_TREE);
13100 tree void_ftype_v2sf_long_pcfloat =
13101 build_function_type_list (void_type_node,
13102 V2SF_type_node,
13103 long_integer_type_node,
13104 pcfloat_type_node,
13105 NULL_TREE);
13108 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
13109 PAIRED_BUILTIN_LX);
13112 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
13113 PAIRED_BUILTIN_STX);
13115 /* Predicates. */
13116 d = bdesc_paired_preds;
13117 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
13119 tree type;
13121 switch (insn_data[d->icode].operand[1].mode)
13123 case V2SFmode:
13124 type = int_ftype_int_v2sf_v2sf;
13125 break;
13126 default:
13127 gcc_unreachable ();
13130 def_builtin (d->mask, d->name, type, d->code);
13134 static void
13135 altivec_init_builtins (void)
13137 const struct builtin_description *d;
13138 const struct builtin_description_predicates *dp;
13139 size_t i;
13140 tree ftype;
13142 tree pvoid_type_node = build_pointer_type (void_type_node);
13144 tree pcvoid_type_node
13145 = build_pointer_type (build_qualified_type (void_type_node,
13146 TYPE_QUAL_CONST));
13148 tree int_ftype_opaque
13149 = build_function_type_list (integer_type_node,
13150 opaque_V4SI_type_node, NULL_TREE);
13151 tree opaque_ftype_opaque
13152 = build_function_type (integer_type_node,
13153 NULL_TREE);
13154 tree opaque_ftype_opaque_int
13155 = build_function_type_list (opaque_V4SI_type_node,
13156 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
13157 tree opaque_ftype_opaque_opaque_int
13158 = build_function_type_list (opaque_V4SI_type_node,
13159 opaque_V4SI_type_node, opaque_V4SI_type_node,
13160 integer_type_node, NULL_TREE);
13161 tree int_ftype_int_opaque_opaque
13162 = build_function_type_list (integer_type_node,
13163 integer_type_node, opaque_V4SI_type_node,
13164 opaque_V4SI_type_node, NULL_TREE);
13165 tree int_ftype_int_v4si_v4si
13166 = build_function_type_list (integer_type_node,
13167 integer_type_node, V4SI_type_node,
13168 V4SI_type_node, NULL_TREE);
13169 tree void_ftype_v4si
13170 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
13171 tree v8hi_ftype_void
13172 = build_function_type (V8HI_type_node, void_list_node);
13173 tree void_ftype_void
13174 = build_function_type (void_type_node, void_list_node);
13175 tree void_ftype_int
13176 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
13178 tree opaque_ftype_long_pcvoid
13179 = build_function_type_list (opaque_V4SI_type_node,
13180 long_integer_type_node, pcvoid_type_node,
13181 NULL_TREE);
13182 tree v16qi_ftype_long_pcvoid
13183 = build_function_type_list (V16QI_type_node,
13184 long_integer_type_node, pcvoid_type_node,
13185 NULL_TREE);
13186 tree v8hi_ftype_long_pcvoid
13187 = build_function_type_list (V8HI_type_node,
13188 long_integer_type_node, pcvoid_type_node,
13189 NULL_TREE);
13190 tree v4si_ftype_long_pcvoid
13191 = build_function_type_list (V4SI_type_node,
13192 long_integer_type_node, pcvoid_type_node,
13193 NULL_TREE);
13194 tree v4sf_ftype_long_pcvoid
13195 = build_function_type_list (V4SF_type_node,
13196 long_integer_type_node, pcvoid_type_node,
13197 NULL_TREE);
13198 tree v2df_ftype_long_pcvoid
13199 = build_function_type_list (V2DF_type_node,
13200 long_integer_type_node, pcvoid_type_node,
13201 NULL_TREE);
13202 tree v2di_ftype_long_pcvoid
13203 = build_function_type_list (V2DI_type_node,
13204 long_integer_type_node, pcvoid_type_node,
13205 NULL_TREE);
13207 tree void_ftype_opaque_long_pvoid
13208 = build_function_type_list (void_type_node,
13209 opaque_V4SI_type_node, long_integer_type_node,
13210 pvoid_type_node, NULL_TREE);
13211 tree void_ftype_v4si_long_pvoid
13212 = build_function_type_list (void_type_node,
13213 V4SI_type_node, long_integer_type_node,
13214 pvoid_type_node, NULL_TREE);
13215 tree void_ftype_v16qi_long_pvoid
13216 = build_function_type_list (void_type_node,
13217 V16QI_type_node, long_integer_type_node,
13218 pvoid_type_node, NULL_TREE);
13219 tree void_ftype_v8hi_long_pvoid
13220 = build_function_type_list (void_type_node,
13221 V8HI_type_node, long_integer_type_node,
13222 pvoid_type_node, NULL_TREE);
13223 tree void_ftype_v4sf_long_pvoid
13224 = build_function_type_list (void_type_node,
13225 V4SF_type_node, long_integer_type_node,
13226 pvoid_type_node, NULL_TREE);
13227 tree void_ftype_v2df_long_pvoid
13228 = build_function_type_list (void_type_node,
13229 V2DF_type_node, long_integer_type_node,
13230 pvoid_type_node, NULL_TREE);
13231 tree void_ftype_v2di_long_pvoid
13232 = build_function_type_list (void_type_node,
13233 V2DI_type_node, long_integer_type_node,
13234 pvoid_type_node, NULL_TREE);
13235 tree int_ftype_int_v8hi_v8hi
13236 = build_function_type_list (integer_type_node,
13237 integer_type_node, V8HI_type_node,
13238 V8HI_type_node, NULL_TREE);
13239 tree int_ftype_int_v16qi_v16qi
13240 = build_function_type_list (integer_type_node,
13241 integer_type_node, V16QI_type_node,
13242 V16QI_type_node, NULL_TREE);
13243 tree int_ftype_int_v4sf_v4sf
13244 = build_function_type_list (integer_type_node,
13245 integer_type_node, V4SF_type_node,
13246 V4SF_type_node, NULL_TREE);
13247 tree int_ftype_int_v2df_v2df
13248 = build_function_type_list (integer_type_node,
13249 integer_type_node, V2DF_type_node,
13250 V2DF_type_node, NULL_TREE);
13251 tree v4si_ftype_v4si
13252 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
13253 tree v8hi_ftype_v8hi
13254 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
13255 tree v16qi_ftype_v16qi
13256 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
13257 tree v4sf_ftype_v4sf
13258 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
13259 tree v2df_ftype_v2df
13260 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
13261 tree void_ftype_pcvoid_int_int
13262 = build_function_type_list (void_type_node,
13263 pcvoid_type_node, integer_type_node,
13264 integer_type_node, NULL_TREE);
13266 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
13267 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
13268 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
13269 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
13270 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
13271 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
13272 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
13273 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
13274 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
13275 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
13276 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
13277 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
13278 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
13279 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
13280 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
13281 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
13282 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
13283 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
13284 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
13285 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
13286 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
13287 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
13288 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
13289 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
13290 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
13291 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
13292 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
13293 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
13294 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
13295 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
13297 def_builtin (MASK_VSX, "__builtin_vsx_lxvd2x_v2df", v2df_ftype_long_pcvoid,
13298 VSX_BUILTIN_LXVD2X_V2DF);
13299 def_builtin (MASK_VSX, "__builtin_vsx_lxvd2x_v2di", v2di_ftype_long_pcvoid,
13300 VSX_BUILTIN_LXVD2X_V2DI);
13301 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v4sf", v4sf_ftype_long_pcvoid,
13302 VSX_BUILTIN_LXVW4X_V4SF);
13303 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v4si", v4si_ftype_long_pcvoid,
13304 VSX_BUILTIN_LXVW4X_V4SI);
13305 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v8hi",
13306 v8hi_ftype_long_pcvoid, VSX_BUILTIN_LXVW4X_V8HI);
13307 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v16qi",
13308 v16qi_ftype_long_pcvoid, VSX_BUILTIN_LXVW4X_V16QI);
13309 def_builtin (MASK_VSX, "__builtin_vsx_stxvd2x_v2df",
13310 void_ftype_v2df_long_pvoid, VSX_BUILTIN_STXVD2X_V2DF);
13311 def_builtin (MASK_VSX, "__builtin_vsx_stxvd2x_v2di",
13312 void_ftype_v2di_long_pvoid, VSX_BUILTIN_STXVD2X_V2DI);
13313 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v4sf",
13314 void_ftype_v4sf_long_pvoid, VSX_BUILTIN_STXVW4X_V4SF);
13315 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v4si",
13316 void_ftype_v4si_long_pvoid, VSX_BUILTIN_STXVW4X_V4SI);
13317 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v8hi",
13318 void_ftype_v8hi_long_pvoid, VSX_BUILTIN_STXVW4X_V8HI);
13319 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v16qi",
13320 void_ftype_v16qi_long_pvoid, VSX_BUILTIN_STXVW4X_V16QI);
13321 def_builtin (MASK_VSX, "__builtin_vec_vsx_ld", opaque_ftype_long_pcvoid,
13322 VSX_BUILTIN_VEC_LD);
13323 def_builtin (MASK_VSX, "__builtin_vec_vsx_st", void_ftype_opaque_long_pvoid,
13324 VSX_BUILTIN_VEC_ST);
13326 if (rs6000_cpu == PROCESSOR_CELL)
13328 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
13329 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
13330 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
13331 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
13333 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
13334 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
13335 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
13336 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
13338 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
13339 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
13340 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
13341 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
13343 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
13344 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
13345 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
13346 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
13348 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
13349 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
13350 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
13352 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
13353 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
13354 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
13355 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
13356 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
13357 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
13358 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
13359 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
13360 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
13361 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
13362 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
13363 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
13365 /* Add the DST variants. */
13366 d = bdesc_dst;
13367 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
13368 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
13370 /* Initialize the predicates. */
13371 dp = bdesc_altivec_preds;
13372 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
13374 enum machine_mode mode1;
13375 tree type;
13376 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13377 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13378 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
13379 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
13381 if (is_overloaded)
13382 mode1 = VOIDmode;
13383 else
13384 mode1 = insn_data[dp->icode].operand[1].mode;
13386 switch (mode1)
13388 case VOIDmode:
13389 type = int_ftype_int_opaque_opaque;
13390 break;
13391 case V4SImode:
13392 type = int_ftype_int_v4si_v4si;
13393 break;
13394 case V8HImode:
13395 type = int_ftype_int_v8hi_v8hi;
13396 break;
13397 case V16QImode:
13398 type = int_ftype_int_v16qi_v16qi;
13399 break;
13400 case V4SFmode:
13401 type = int_ftype_int_v4sf_v4sf;
13402 break;
13403 case V2DFmode:
13404 type = int_ftype_int_v2df_v2df;
13405 break;
13406 default:
13407 gcc_unreachable ();
13410 def_builtin (dp->mask, dp->name, type, dp->code);
13413 /* Initialize the abs* operators. */
13414 d = bdesc_abs;
13415 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
13417 enum machine_mode mode0;
13418 tree type;
13420 mode0 = insn_data[d->icode].operand[0].mode;
13422 switch (mode0)
13424 case V4SImode:
13425 type = v4si_ftype_v4si;
13426 break;
13427 case V8HImode:
13428 type = v8hi_ftype_v8hi;
13429 break;
13430 case V16QImode:
13431 type = v16qi_ftype_v16qi;
13432 break;
13433 case V4SFmode:
13434 type = v4sf_ftype_v4sf;
13435 break;
13436 case V2DFmode:
13437 type = v2df_ftype_v2df;
13438 break;
13439 default:
13440 gcc_unreachable ();
13443 def_builtin (d->mask, d->name, type, d->code);
13446 if (TARGET_ALTIVEC)
13448 tree decl;
13450 /* Initialize target builtin that implements
13451 targetm.vectorize.builtin_mask_for_load. */
13453 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
13454 v16qi_ftype_long_pcvoid,
13455 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
13456 BUILT_IN_MD, NULL, NULL_TREE);
13457 TREE_READONLY (decl) = 1;
13458 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
13459 altivec_builtin_mask_for_load = decl;
13462 /* Access to the vec_init patterns. */
13463 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
13464 integer_type_node, integer_type_node,
13465 integer_type_node, NULL_TREE);
13466 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
13467 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
13469 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
13470 short_integer_type_node,
13471 short_integer_type_node,
13472 short_integer_type_node,
13473 short_integer_type_node,
13474 short_integer_type_node,
13475 short_integer_type_node,
13476 short_integer_type_node, NULL_TREE);
13477 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
13478 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
13480 ftype = build_function_type_list (V16QI_type_node, char_type_node,
13481 char_type_node, char_type_node,
13482 char_type_node, char_type_node,
13483 char_type_node, char_type_node,
13484 char_type_node, char_type_node,
13485 char_type_node, char_type_node,
13486 char_type_node, char_type_node,
13487 char_type_node, char_type_node,
13488 char_type_node, NULL_TREE);
13489 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
13490 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
13492 ftype = build_function_type_list (V4SF_type_node, float_type_node,
13493 float_type_node, float_type_node,
13494 float_type_node, NULL_TREE);
13495 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
13496 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
13498 if (TARGET_VSX)
13500 ftype = build_function_type_list (V2DF_type_node, double_type_node,
13501 double_type_node, NULL_TREE);
13502 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
13503 VSX_BUILTIN_VEC_INIT_V2DF);
13505 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
13506 intDI_type_node, NULL_TREE);
13507 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
13508 VSX_BUILTIN_VEC_INIT_V2DI);
13511 /* Access to the vec_set patterns. */
13512 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
13513 intSI_type_node,
13514 integer_type_node, NULL_TREE);
13515 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
13516 ALTIVEC_BUILTIN_VEC_SET_V4SI);
13518 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
13519 intHI_type_node,
13520 integer_type_node, NULL_TREE);
13521 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
13522 ALTIVEC_BUILTIN_VEC_SET_V8HI);
13524 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
13525 intQI_type_node,
13526 integer_type_node, NULL_TREE);
13527 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
13528 ALTIVEC_BUILTIN_VEC_SET_V16QI);
13530 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
13531 float_type_node,
13532 integer_type_node, NULL_TREE);
13533 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
13534 ALTIVEC_BUILTIN_VEC_SET_V4SF);
13536 if (TARGET_VSX)
13538 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
13539 double_type_node,
13540 integer_type_node, NULL_TREE);
13541 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
13542 VSX_BUILTIN_VEC_SET_V2DF);
13544 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
13545 intDI_type_node,
13546 integer_type_node, NULL_TREE);
13547 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
13548 VSX_BUILTIN_VEC_SET_V2DI);
13551 /* Access to the vec_extract patterns. */
13552 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
13553 integer_type_node, NULL_TREE);
13554 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
13555 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
13557 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
13558 integer_type_node, NULL_TREE);
13559 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
13560 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
13562 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
13563 integer_type_node, NULL_TREE);
13564 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
13565 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
13567 ftype = build_function_type_list (float_type_node, V4SF_type_node,
13568 integer_type_node, NULL_TREE);
13569 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
13570 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
13572 if (TARGET_VSX)
13574 ftype = build_function_type_list (double_type_node, V2DF_type_node,
13575 integer_type_node, NULL_TREE);
13576 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
13577 VSX_BUILTIN_VEC_EXT_V2DF);
13579 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
13580 integer_type_node, NULL_TREE);
13581 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
13582 VSX_BUILTIN_VEC_EXT_V2DI);
13586 /* Hash function for builtin functions with up to 3 arguments and a return
13587 type. */
13588 static unsigned
13589 builtin_hash_function (const void *hash_entry)
13591 unsigned ret = 0;
13592 int i;
13593 const struct builtin_hash_struct *bh =
13594 (const struct builtin_hash_struct *) hash_entry;
13596 for (i = 0; i < 4; i++)
13598 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
13599 ret = (ret * 2) + bh->uns_p[i];
13602 return ret;
13605 /* Compare builtin hash entries H1 and H2 for equivalence. */
13606 static int
13607 builtin_hash_eq (const void *h1, const void *h2)
13609 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
13610 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
13612 return ((p1->mode[0] == p2->mode[0])
13613 && (p1->mode[1] == p2->mode[1])
13614 && (p1->mode[2] == p2->mode[2])
13615 && (p1->mode[3] == p2->mode[3])
13616 && (p1->uns_p[0] == p2->uns_p[0])
13617 && (p1->uns_p[1] == p2->uns_p[1])
13618 && (p1->uns_p[2] == p2->uns_p[2])
13619 && (p1->uns_p[3] == p2->uns_p[3]));
13622 /* Map types for builtin functions with an explicit return type and up to 3
13623 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
13624 of the argument. */
13625 static tree
13626 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
13627 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
13628 enum rs6000_builtins builtin, const char *name)
13630 struct builtin_hash_struct h;
13631 struct builtin_hash_struct *h2;
13632 void **found;
13633 int num_args = 3;
13634 int i;
13635 tree ret_type = NULL_TREE;
13636 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
13637 tree args;
13639 /* Create builtin_hash_table. */
13640 if (builtin_hash_table == NULL)
13641 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
13642 builtin_hash_eq, NULL);
13644 h.type = NULL_TREE;
13645 h.mode[0] = mode_ret;
13646 h.mode[1] = mode_arg0;
13647 h.mode[2] = mode_arg1;
13648 h.mode[3] = mode_arg2;
13649 h.uns_p[0] = 0;
13650 h.uns_p[1] = 0;
13651 h.uns_p[2] = 0;
13652 h.uns_p[3] = 0;
13654 /* If the builtin is a type that produces unsigned results or takes unsigned
13655 arguments, and it is returned as a decl for the vectorizer (such as
13656 widening multiplies, permute), make sure the arguments and return value
13657 are type correct. */
13658 switch (builtin)
13660 /* unsigned 2 argument functions. */
13661 case ALTIVEC_BUILTIN_VMULEUB_UNS:
13662 case ALTIVEC_BUILTIN_VMULEUH_UNS:
13663 case ALTIVEC_BUILTIN_VMULOUB_UNS:
13664 case ALTIVEC_BUILTIN_VMULOUH_UNS:
13665 h.uns_p[0] = 1;
13666 h.uns_p[1] = 1;
13667 h.uns_p[2] = 1;
13668 break;
13670 /* unsigned 3 argument functions. */
13671 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
13672 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
13673 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
13674 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
13675 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
13676 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
13677 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
13678 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
13679 case VSX_BUILTIN_VPERM_16QI_UNS:
13680 case VSX_BUILTIN_VPERM_8HI_UNS:
13681 case VSX_BUILTIN_VPERM_4SI_UNS:
13682 case VSX_BUILTIN_VPERM_2DI_UNS:
13683 case VSX_BUILTIN_XXSEL_16QI_UNS:
13684 case VSX_BUILTIN_XXSEL_8HI_UNS:
13685 case VSX_BUILTIN_XXSEL_4SI_UNS:
13686 case VSX_BUILTIN_XXSEL_2DI_UNS:
13687 h.uns_p[0] = 1;
13688 h.uns_p[1] = 1;
13689 h.uns_p[2] = 1;
13690 h.uns_p[3] = 1;
13691 break;
13693 /* signed permute functions with unsigned char mask. */
13694 case ALTIVEC_BUILTIN_VPERM_16QI:
13695 case ALTIVEC_BUILTIN_VPERM_8HI:
13696 case ALTIVEC_BUILTIN_VPERM_4SI:
13697 case ALTIVEC_BUILTIN_VPERM_4SF:
13698 case ALTIVEC_BUILTIN_VPERM_2DI:
13699 case ALTIVEC_BUILTIN_VPERM_2DF:
13700 case VSX_BUILTIN_VPERM_16QI:
13701 case VSX_BUILTIN_VPERM_8HI:
13702 case VSX_BUILTIN_VPERM_4SI:
13703 case VSX_BUILTIN_VPERM_4SF:
13704 case VSX_BUILTIN_VPERM_2DI:
13705 case VSX_BUILTIN_VPERM_2DF:
13706 h.uns_p[3] = 1;
13707 break;
13709 /* unsigned args, signed return. */
13710 case VSX_BUILTIN_XVCVUXDDP_UNS:
13711 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
13712 h.uns_p[1] = 1;
13713 break;
13715 /* signed args, unsigned return. */
13716 case VSX_BUILTIN_XVCVDPUXDS_UNS:
13717 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
13718 h.uns_p[0] = 1;
13719 break;
13721 default:
13722 break;
13725 /* Figure out how many args are present. */
13726 while (num_args > 0 && h.mode[num_args] == VOIDmode)
13727 num_args--;
13729 if (num_args == 0)
13730 fatal_error ("internal error: builtin function %s had no type", name);
13732 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
13733 if (!ret_type && h.uns_p[0])
13734 ret_type = builtin_mode_to_type[h.mode[0]][0];
13736 if (!ret_type)
13737 fatal_error ("internal error: builtin function %s had an unexpected "
13738 "return type %s", name, GET_MODE_NAME (h.mode[0]));
13740 for (i = 0; i < num_args; i++)
13742 int m = (int) h.mode[i+1];
13743 int uns_p = h.uns_p[i+1];
13745 arg_type[i] = builtin_mode_to_type[m][uns_p];
13746 if (!arg_type[i] && uns_p)
13747 arg_type[i] = builtin_mode_to_type[m][0];
13749 if (!arg_type[i])
13750 fatal_error ("internal error: builtin function %s, argument %d "
13751 "had unexpected argument type %s", name, i,
13752 GET_MODE_NAME (m));
13755 found = htab_find_slot (builtin_hash_table, &h, INSERT);
13756 if (*found == NULL)
13758 h2 = ggc_alloc_builtin_hash_struct ();
13759 *h2 = h;
13760 *found = (void *)h2;
13761 args = void_list_node;
13763 for (i = num_args - 1; i >= 0; i--)
13764 args = tree_cons (NULL_TREE, arg_type[i], args);
13766 h2->type = build_function_type (ret_type, args);
13769 return ((struct builtin_hash_struct *)(*found))->type;
13772 static void
13773 rs6000_common_init_builtins (void)
13775 const struct builtin_description *d;
13776 size_t i;
13778 tree opaque_ftype_opaque = NULL_TREE;
13779 tree opaque_ftype_opaque_opaque = NULL_TREE;
13780 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
13781 tree v2si_ftype_qi = NULL_TREE;
13782 tree v2si_ftype_v2si_qi = NULL_TREE;
13783 tree v2si_ftype_int_qi = NULL_TREE;
13785 if (!TARGET_PAIRED_FLOAT)
13787 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
13788 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
13791 /* Add the ternary operators. */
13792 d = bdesc_3arg;
13793 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
13795 tree type;
13796 int mask = d->mask;
13798 if ((mask != 0 && (mask & target_flags) == 0)
13799 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13800 continue;
13802 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13803 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13804 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13805 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13807 if (! (type = opaque_ftype_opaque_opaque_opaque))
13808 type = opaque_ftype_opaque_opaque_opaque
13809 = build_function_type_list (opaque_V4SI_type_node,
13810 opaque_V4SI_type_node,
13811 opaque_V4SI_type_node,
13812 opaque_V4SI_type_node,
13813 NULL_TREE);
13815 else
13817 enum insn_code icode = d->icode;
13818 if (d->name == 0 || icode == CODE_FOR_nothing)
13819 continue;
13821 type = builtin_function_type (insn_data[icode].operand[0].mode,
13822 insn_data[icode].operand[1].mode,
13823 insn_data[icode].operand[2].mode,
13824 insn_data[icode].operand[3].mode,
13825 d->code, d->name);
13828 def_builtin (d->mask, d->name, type, d->code);
13831 /* Add the binary operators. */
13832 d = bdesc_2arg;
13833 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
13835 enum machine_mode mode0, mode1, mode2;
13836 tree type;
13837 int mask = d->mask;
13839 if ((mask != 0 && (mask & target_flags) == 0)
13840 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13841 continue;
13843 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13844 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13845 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13846 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13848 if (! (type = opaque_ftype_opaque_opaque))
13849 type = opaque_ftype_opaque_opaque
13850 = build_function_type_list (opaque_V4SI_type_node,
13851 opaque_V4SI_type_node,
13852 opaque_V4SI_type_node,
13853 NULL_TREE);
13855 else
13857 enum insn_code icode = d->icode;
13858 if (d->name == 0 || icode == CODE_FOR_nothing)
13859 continue;
13861 mode0 = insn_data[icode].operand[0].mode;
13862 mode1 = insn_data[icode].operand[1].mode;
13863 mode2 = insn_data[icode].operand[2].mode;
13865 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
13867 if (! (type = v2si_ftype_v2si_qi))
13868 type = v2si_ftype_v2si_qi
13869 = build_function_type_list (opaque_V2SI_type_node,
13870 opaque_V2SI_type_node,
13871 char_type_node,
13872 NULL_TREE);
13875 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
13876 && mode2 == QImode)
13878 if (! (type = v2si_ftype_int_qi))
13879 type = v2si_ftype_int_qi
13880 = build_function_type_list (opaque_V2SI_type_node,
13881 integer_type_node,
13882 char_type_node,
13883 NULL_TREE);
13886 else
13887 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
13888 d->code, d->name);
13891 def_builtin (d->mask, d->name, type, d->code);
13894 /* Add the simple unary operators. */
13895 d = (struct builtin_description *) bdesc_1arg;
13896 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
13898 enum machine_mode mode0, mode1;
13899 tree type;
13900 int mask = d->mask;
13902 if ((mask != 0 && (mask & target_flags) == 0)
13903 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13904 continue;
13906 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13907 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13908 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13909 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13911 if (! (type = opaque_ftype_opaque))
13912 type = opaque_ftype_opaque
13913 = build_function_type_list (opaque_V4SI_type_node,
13914 opaque_V4SI_type_node,
13915 NULL_TREE);
13917 else
13919 enum insn_code icode = d->icode;
13920 if (d->name == 0 || icode == CODE_FOR_nothing)
13921 continue;
13923 mode0 = insn_data[icode].operand[0].mode;
13924 mode1 = insn_data[icode].operand[1].mode;
13926 if (mode0 == V2SImode && mode1 == QImode)
13928 if (! (type = v2si_ftype_qi))
13929 type = v2si_ftype_qi
13930 = build_function_type_list (opaque_V2SI_type_node,
13931 char_type_node,
13932 NULL_TREE);
13935 else
13936 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
13937 d->code, d->name);
13940 def_builtin (d->mask, d->name, type, d->code);
13944 static void
13945 rs6000_init_libfuncs (void)
13947 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
13948 && !TARGET_POWER2 && !TARGET_POWERPC)
13950 /* AIX library routines for float->int conversion. */
13951 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
13952 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
13953 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
13954 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
13957 if (!TARGET_IEEEQUAD)
13958 /* AIX/Darwin/64-bit Linux quad floating point routines. */
13959 if (!TARGET_XL_COMPAT)
13961 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
13962 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
13963 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
13964 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
13966 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
13968 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
13969 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
13970 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
13971 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
13972 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
13973 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
13974 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
13976 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
13977 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
13978 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
13979 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
13980 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
13981 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
13982 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
13983 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
13986 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
13987 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
13989 else
13991 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
13992 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
13993 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
13994 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
13996 else
13998 /* 32-bit SVR4 quad floating point routines. */
14000 set_optab_libfunc (add_optab, TFmode, "_q_add");
14001 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
14002 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
14003 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
14004 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
14005 if (TARGET_PPC_GPOPT || TARGET_POWER2)
14006 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
14008 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
14009 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
14010 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
14011 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
14012 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
14013 set_optab_libfunc (le_optab, TFmode, "_q_fle");
14015 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
14016 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
14017 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
14018 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
14019 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
14020 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
14021 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
14022 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
14027 /* Expand a block clear operation, and return 1 if successful. Return 0
14028 if we should let the compiler generate normal code.
14030 operands[0] is the destination
14031 operands[1] is the length
14032 operands[3] is the alignment */
14035 expand_block_clear (rtx operands[])
14037 rtx orig_dest = operands[0];
14038 rtx bytes_rtx = operands[1];
14039 rtx align_rtx = operands[3];
14040 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
14041 HOST_WIDE_INT align;
14042 HOST_WIDE_INT bytes;
14043 int offset;
14044 int clear_bytes;
14045 int clear_step;
14047 /* If this is not a fixed size move, just call memcpy */
14048 if (! constp)
14049 return 0;
14051 /* This must be a fixed size alignment */
14052 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
14053 align = INTVAL (align_rtx) * BITS_PER_UNIT;
14055 /* Anything to clear? */
14056 bytes = INTVAL (bytes_rtx);
14057 if (bytes <= 0)
14058 return 1;
14060 /* Use the builtin memset after a point, to avoid huge code bloat.
14061 When optimize_size, avoid any significant code bloat; calling
14062 memset is about 4 instructions, so allow for one instruction to
14063 load zero and three to do clearing. */
14064 if (TARGET_ALTIVEC && align >= 128)
14065 clear_step = 16;
14066 else if (TARGET_POWERPC64 && align >= 32)
14067 clear_step = 8;
14068 else if (TARGET_SPE && align >= 64)
14069 clear_step = 8;
14070 else
14071 clear_step = 4;
14073 if (optimize_size && bytes > 3 * clear_step)
14074 return 0;
14075 if (! optimize_size && bytes > 8 * clear_step)
14076 return 0;
14078 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
14080 enum machine_mode mode = BLKmode;
14081 rtx dest;
14083 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
14085 clear_bytes = 16;
14086 mode = V4SImode;
14088 else if (bytes >= 8 && TARGET_SPE && align >= 64)
14090 clear_bytes = 8;
14091 mode = V2SImode;
14093 else if (bytes >= 8 && TARGET_POWERPC64
14094 /* 64-bit loads and stores require word-aligned
14095 displacements. */
14096 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
14098 clear_bytes = 8;
14099 mode = DImode;
14101 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
14102 { /* move 4 bytes */
14103 clear_bytes = 4;
14104 mode = SImode;
14106 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
14107 { /* move 2 bytes */
14108 clear_bytes = 2;
14109 mode = HImode;
14111 else /* move 1 byte at a time */
14113 clear_bytes = 1;
14114 mode = QImode;
14117 dest = adjust_address (orig_dest, mode, offset);
14119 emit_move_insn (dest, CONST0_RTX (mode));
14122 return 1;
14126 /* Expand a block move operation, and return 1 if successful. Return 0
14127 if we should let the compiler generate normal code.
14129 operands[0] is the destination
14130 operands[1] is the source
14131 operands[2] is the length
14132 operands[3] is the alignment */
14134 #define MAX_MOVE_REG 4
14137 expand_block_move (rtx operands[])
14139 rtx orig_dest = operands[0];
14140 rtx orig_src = operands[1];
14141 rtx bytes_rtx = operands[2];
14142 rtx align_rtx = operands[3];
14143 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
14144 int align;
14145 int bytes;
14146 int offset;
14147 int move_bytes;
14148 rtx stores[MAX_MOVE_REG];
14149 int num_reg = 0;
14151 /* If this is not a fixed size move, just call memcpy */
14152 if (! constp)
14153 return 0;
14155 /* This must be a fixed size alignment */
14156 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
14157 align = INTVAL (align_rtx) * BITS_PER_UNIT;
14159 /* Anything to move? */
14160 bytes = INTVAL (bytes_rtx);
14161 if (bytes <= 0)
14162 return 1;
14164 if (bytes > rs6000_block_move_inline_limit)
14165 return 0;
14167 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
14169 union {
14170 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
14171 rtx (*mov) (rtx, rtx);
14172 } gen_func;
14173 enum machine_mode mode = BLKmode;
14174 rtx src, dest;
14176 /* Altivec first, since it will be faster than a string move
14177 when it applies, and usually not significantly larger. */
14178 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
14180 move_bytes = 16;
14181 mode = V4SImode;
14182 gen_func.mov = gen_movv4si;
14184 else if (TARGET_SPE && bytes >= 8 && align >= 64)
14186 move_bytes = 8;
14187 mode = V2SImode;
14188 gen_func.mov = gen_movv2si;
14190 else if (TARGET_STRING
14191 && bytes > 24 /* move up to 32 bytes at a time */
14192 && ! fixed_regs[5]
14193 && ! fixed_regs[6]
14194 && ! fixed_regs[7]
14195 && ! fixed_regs[8]
14196 && ! fixed_regs[9]
14197 && ! fixed_regs[10]
14198 && ! fixed_regs[11]
14199 && ! fixed_regs[12])
14201 move_bytes = (bytes > 32) ? 32 : bytes;
14202 gen_func.movmemsi = gen_movmemsi_8reg;
14204 else if (TARGET_STRING
14205 && bytes > 16 /* move up to 24 bytes at a time */
14206 && ! fixed_regs[5]
14207 && ! fixed_regs[6]
14208 && ! fixed_regs[7]
14209 && ! fixed_regs[8]
14210 && ! fixed_regs[9]
14211 && ! fixed_regs[10])
14213 move_bytes = (bytes > 24) ? 24 : bytes;
14214 gen_func.movmemsi = gen_movmemsi_6reg;
14216 else if (TARGET_STRING
14217 && bytes > 8 /* move up to 16 bytes at a time */
14218 && ! fixed_regs[5]
14219 && ! fixed_regs[6]
14220 && ! fixed_regs[7]
14221 && ! fixed_regs[8])
14223 move_bytes = (bytes > 16) ? 16 : bytes;
14224 gen_func.movmemsi = gen_movmemsi_4reg;
14226 else if (bytes >= 8 && TARGET_POWERPC64
14227 /* 64-bit loads and stores require word-aligned
14228 displacements. */
14229 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
14231 move_bytes = 8;
14232 mode = DImode;
14233 gen_func.mov = gen_movdi;
14235 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
14236 { /* move up to 8 bytes at a time */
14237 move_bytes = (bytes > 8) ? 8 : bytes;
14238 gen_func.movmemsi = gen_movmemsi_2reg;
14240 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
14241 { /* move 4 bytes */
14242 move_bytes = 4;
14243 mode = SImode;
14244 gen_func.mov = gen_movsi;
14246 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
14247 { /* move 2 bytes */
14248 move_bytes = 2;
14249 mode = HImode;
14250 gen_func.mov = gen_movhi;
14252 else if (TARGET_STRING && bytes > 1)
14253 { /* move up to 4 bytes at a time */
14254 move_bytes = (bytes > 4) ? 4 : bytes;
14255 gen_func.movmemsi = gen_movmemsi_1reg;
14257 else /* move 1 byte at a time */
14259 move_bytes = 1;
14260 mode = QImode;
14261 gen_func.mov = gen_movqi;
14264 src = adjust_address (orig_src, mode, offset);
14265 dest = adjust_address (orig_dest, mode, offset);
14267 if (mode != BLKmode)
14269 rtx tmp_reg = gen_reg_rtx (mode);
14271 emit_insn ((*gen_func.mov) (tmp_reg, src));
14272 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
14275 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
14277 int i;
14278 for (i = 0; i < num_reg; i++)
14279 emit_insn (stores[i]);
14280 num_reg = 0;
14283 if (mode == BLKmode)
14285 /* Move the address into scratch registers. The movmemsi
14286 patterns require zero offset. */
14287 if (!REG_P (XEXP (src, 0)))
14289 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
14290 src = replace_equiv_address (src, src_reg);
14292 set_mem_size (src, GEN_INT (move_bytes));
14294 if (!REG_P (XEXP (dest, 0)))
14296 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
14297 dest = replace_equiv_address (dest, dest_reg);
14299 set_mem_size (dest, GEN_INT (move_bytes));
14301 emit_insn ((*gen_func.movmemsi) (dest, src,
14302 GEN_INT (move_bytes & 31),
14303 align_rtx));
14307 return 1;
14311 /* Return a string to perform a load_multiple operation.
14312 operands[0] is the vector.
14313 operands[1] is the source address.
14314 operands[2] is the first destination register. */
14316 const char *
14317 rs6000_output_load_multiple (rtx operands[3])
14319 /* We have to handle the case where the pseudo used to contain the address
14320 is assigned to one of the output registers. */
14321 int i, j;
14322 int words = XVECLEN (operands[0], 0);
14323 rtx xop[10];
14325 if (XVECLEN (operands[0], 0) == 1)
14326 return "{l|lwz} %2,0(%1)";
14328 for (i = 0; i < words; i++)
14329 if (refers_to_regno_p (REGNO (operands[2]) + i,
14330 REGNO (operands[2]) + i + 1, operands[1], 0))
14332 if (i == words-1)
14334 xop[0] = GEN_INT (4 * (words-1));
14335 xop[1] = operands[1];
14336 xop[2] = operands[2];
14337 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
14338 return "";
14340 else if (i == 0)
14342 xop[0] = GEN_INT (4 * (words-1));
14343 xop[1] = operands[1];
14344 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
14345 output_asm_insn ("{cal %1,4(%1)|addi %1,%1,4}\n\t{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,-4(%1)", xop);
14346 return "";
14348 else
14350 for (j = 0; j < words; j++)
14351 if (j != i)
14353 xop[0] = GEN_INT (j * 4);
14354 xop[1] = operands[1];
14355 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
14356 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
14358 xop[0] = GEN_INT (i * 4);
14359 xop[1] = operands[1];
14360 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
14361 return "";
14365 return "{lsi|lswi} %2,%1,%N0";
14369 /* A validation routine: say whether CODE, a condition code, and MODE
14370 match. The other alternatives either don't make sense or should
14371 never be generated. */
14373 void
14374 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
14376 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
14377 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
14378 && GET_MODE_CLASS (mode) == MODE_CC);
14380 /* These don't make sense. */
14381 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
14382 || mode != CCUNSmode);
14384 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
14385 || mode == CCUNSmode);
14387 gcc_assert (mode == CCFPmode
14388 || (code != ORDERED && code != UNORDERED
14389 && code != UNEQ && code != LTGT
14390 && code != UNGT && code != UNLT
14391 && code != UNGE && code != UNLE));
14393 /* These should never be generated except for
14394 flag_finite_math_only. */
14395 gcc_assert (mode != CCFPmode
14396 || flag_finite_math_only
14397 || (code != LE && code != GE
14398 && code != UNEQ && code != LTGT
14399 && code != UNGT && code != UNLT));
14401 /* These are invalid; the information is not there. */
14402 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
14406 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
14407 mask required to convert the result of a rotate insn into a shift
14408 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
14411 includes_lshift_p (rtx shiftop, rtx andop)
14413 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
14415 shift_mask <<= INTVAL (shiftop);
14417 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
14420 /* Similar, but for right shift. */
14423 includes_rshift_p (rtx shiftop, rtx andop)
14425 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
14427 shift_mask >>= INTVAL (shiftop);
14429 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
14432 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
14433 to perform a left shift. It must have exactly SHIFTOP least
14434 significant 0's, then one or more 1's, then zero or more 0's. */
14437 includes_rldic_lshift_p (rtx shiftop, rtx andop)
14439 if (GET_CODE (andop) == CONST_INT)
14441 HOST_WIDE_INT c, lsb, shift_mask;
14443 c = INTVAL (andop);
14444 if (c == 0 || c == ~0)
14445 return 0;
14447 shift_mask = ~0;
14448 shift_mask <<= INTVAL (shiftop);
14450 /* Find the least significant one bit. */
14451 lsb = c & -c;
14453 /* It must coincide with the LSB of the shift mask. */
14454 if (-lsb != shift_mask)
14455 return 0;
14457 /* Invert to look for the next transition (if any). */
14458 c = ~c;
14460 /* Remove the low group of ones (originally low group of zeros). */
14461 c &= -lsb;
14463 /* Again find the lsb, and check we have all 1's above. */
14464 lsb = c & -c;
14465 return c == -lsb;
14467 else if (GET_CODE (andop) == CONST_DOUBLE
14468 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
14470 HOST_WIDE_INT low, high, lsb;
14471 HOST_WIDE_INT shift_mask_low, shift_mask_high;
14473 low = CONST_DOUBLE_LOW (andop);
14474 if (HOST_BITS_PER_WIDE_INT < 64)
14475 high = CONST_DOUBLE_HIGH (andop);
14477 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
14478 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
14479 return 0;
14481 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
14483 shift_mask_high = ~0;
14484 if (INTVAL (shiftop) > 32)
14485 shift_mask_high <<= INTVAL (shiftop) - 32;
14487 lsb = high & -high;
14489 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
14490 return 0;
14492 high = ~high;
14493 high &= -lsb;
14495 lsb = high & -high;
14496 return high == -lsb;
14499 shift_mask_low = ~0;
14500 shift_mask_low <<= INTVAL (shiftop);
14502 lsb = low & -low;
14504 if (-lsb != shift_mask_low)
14505 return 0;
14507 if (HOST_BITS_PER_WIDE_INT < 64)
14508 high = ~high;
14509 low = ~low;
14510 low &= -lsb;
14512 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
14514 lsb = high & -high;
14515 return high == -lsb;
14518 lsb = low & -low;
14519 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
14521 else
14522 return 0;
14525 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
14526 to perform a left shift. It must have SHIFTOP or more least
14527 significant 0's, with the remainder of the word 1's. */
14530 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
14532 if (GET_CODE (andop) == CONST_INT)
14534 HOST_WIDE_INT c, lsb, shift_mask;
14536 shift_mask = ~0;
14537 shift_mask <<= INTVAL (shiftop);
14538 c = INTVAL (andop);
14540 /* Find the least significant one bit. */
14541 lsb = c & -c;
14543 /* It must be covered by the shift mask.
14544 This test also rejects c == 0. */
14545 if ((lsb & shift_mask) == 0)
14546 return 0;
14548 /* Check we have all 1's above the transition, and reject all 1's. */
14549 return c == -lsb && lsb != 1;
14551 else if (GET_CODE (andop) == CONST_DOUBLE
14552 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
14554 HOST_WIDE_INT low, lsb, shift_mask_low;
14556 low = CONST_DOUBLE_LOW (andop);
14558 if (HOST_BITS_PER_WIDE_INT < 64)
14560 HOST_WIDE_INT high, shift_mask_high;
14562 high = CONST_DOUBLE_HIGH (andop);
14564 if (low == 0)
14566 shift_mask_high = ~0;
14567 if (INTVAL (shiftop) > 32)
14568 shift_mask_high <<= INTVAL (shiftop) - 32;
14570 lsb = high & -high;
14572 if ((lsb & shift_mask_high) == 0)
14573 return 0;
14575 return high == -lsb;
14577 if (high != ~0)
14578 return 0;
14581 shift_mask_low = ~0;
14582 shift_mask_low <<= INTVAL (shiftop);
14584 lsb = low & -low;
14586 if ((lsb & shift_mask_low) == 0)
14587 return 0;
14589 return low == -lsb && lsb != 1;
14591 else
14592 return 0;
14595 /* Return 1 if operands will generate a valid arguments to rlwimi
14596 instruction for insert with right shift in 64-bit mode. The mask may
14597 not start on the first bit or stop on the last bit because wrap-around
14598 effects of instruction do not correspond to semantics of RTL insn. */
14601 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
14603 if (INTVAL (startop) > 32
14604 && INTVAL (startop) < 64
14605 && INTVAL (sizeop) > 1
14606 && INTVAL (sizeop) + INTVAL (startop) < 64
14607 && INTVAL (shiftop) > 0
14608 && INTVAL (sizeop) + INTVAL (shiftop) < 32
14609 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
14610 return 1;
14612 return 0;
14615 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
14616 for lfq and stfq insns iff the registers are hard registers. */
14619 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
14621 /* We might have been passed a SUBREG. */
14622 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
14623 return 0;
14625 /* We might have been passed non floating point registers. */
14626 if (!FP_REGNO_P (REGNO (reg1))
14627 || !FP_REGNO_P (REGNO (reg2)))
14628 return 0;
14630 return (REGNO (reg1) == REGNO (reg2) - 1);
14633 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
14634 addr1 and addr2 must be in consecutive memory locations
14635 (addr2 == addr1 + 8). */
14638 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
14640 rtx addr1, addr2;
14641 unsigned int reg1, reg2;
14642 int offset1, offset2;
14644 /* The mems cannot be volatile. */
14645 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
14646 return 0;
14648 addr1 = XEXP (mem1, 0);
14649 addr2 = XEXP (mem2, 0);
14651 /* Extract an offset (if used) from the first addr. */
14652 if (GET_CODE (addr1) == PLUS)
14654 /* If not a REG, return zero. */
14655 if (GET_CODE (XEXP (addr1, 0)) != REG)
14656 return 0;
14657 else
14659 reg1 = REGNO (XEXP (addr1, 0));
14660 /* The offset must be constant! */
14661 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
14662 return 0;
14663 offset1 = INTVAL (XEXP (addr1, 1));
14666 else if (GET_CODE (addr1) != REG)
14667 return 0;
14668 else
14670 reg1 = REGNO (addr1);
14671 /* This was a simple (mem (reg)) expression. Offset is 0. */
14672 offset1 = 0;
14675 /* And now for the second addr. */
14676 if (GET_CODE (addr2) == PLUS)
14678 /* If not a REG, return zero. */
14679 if (GET_CODE (XEXP (addr2, 0)) != REG)
14680 return 0;
14681 else
14683 reg2 = REGNO (XEXP (addr2, 0));
14684 /* The offset must be constant. */
14685 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
14686 return 0;
14687 offset2 = INTVAL (XEXP (addr2, 1));
14690 else if (GET_CODE (addr2) != REG)
14691 return 0;
14692 else
14694 reg2 = REGNO (addr2);
14695 /* This was a simple (mem (reg)) expression. Offset is 0. */
14696 offset2 = 0;
14699 /* Both of these must have the same base register. */
14700 if (reg1 != reg2)
14701 return 0;
14703 /* The offset for the second addr must be 8 more than the first addr. */
14704 if (offset2 != offset1 + 8)
14705 return 0;
14707 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
14708 instructions. */
14709 return 1;
14714 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
14716 static bool eliminated = false;
14717 rtx ret;
14719 if (mode != SDmode)
14720 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
14721 else
14723 rtx mem = cfun->machine->sdmode_stack_slot;
14724 gcc_assert (mem != NULL_RTX);
14726 if (!eliminated)
14728 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
14729 cfun->machine->sdmode_stack_slot = mem;
14730 eliminated = true;
14732 ret = mem;
14735 if (TARGET_DEBUG_ADDR)
14737 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
14738 GET_MODE_NAME (mode));
14739 if (!ret)
14740 fprintf (stderr, "\tNULL_RTX\n");
14741 else
14742 debug_rtx (ret);
14745 return ret;
14748 static tree
14749 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
14751 /* Don't walk into types. */
14752 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
14754 *walk_subtrees = 0;
14755 return NULL_TREE;
14758 switch (TREE_CODE (*tp))
14760 case VAR_DECL:
14761 case PARM_DECL:
14762 case FIELD_DECL:
14763 case RESULT_DECL:
14764 case SSA_NAME:
14765 case REAL_CST:
14766 case MEM_REF:
14767 case VIEW_CONVERT_EXPR:
14768 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
14769 return *tp;
14770 break;
14771 default:
14772 break;
14775 return NULL_TREE;
14778 enum reload_reg_type {
14779 GPR_REGISTER_TYPE,
14780 VECTOR_REGISTER_TYPE,
14781 OTHER_REGISTER_TYPE
14784 static enum reload_reg_type
14785 rs6000_reload_register_type (enum reg_class rclass)
14787 switch (rclass)
14789 case GENERAL_REGS:
14790 case BASE_REGS:
14791 return GPR_REGISTER_TYPE;
14793 case FLOAT_REGS:
14794 case ALTIVEC_REGS:
14795 case VSX_REGS:
14796 return VECTOR_REGISTER_TYPE;
14798 default:
14799 return OTHER_REGISTER_TYPE;
14803 /* Inform reload about cases where moving X with a mode MODE to a register in
14804 RCLASS requires an extra scratch or immediate register. Return the class
14805 needed for the immediate register.
14807 For VSX and Altivec, we may need a register to convert sp+offset into
14808 reg+sp. */
14810 static reg_class_t
14811 rs6000_secondary_reload (bool in_p,
14812 rtx x,
14813 reg_class_t rclass_i,
14814 enum machine_mode mode,
14815 secondary_reload_info *sri)
14817 enum reg_class rclass = (enum reg_class) rclass_i;
14818 reg_class_t ret = ALL_REGS;
14819 enum insn_code icode;
14820 bool default_p = false;
14822 sri->icode = CODE_FOR_nothing;
14824 /* Convert vector loads and stores into gprs to use an additional base
14825 register. */
14826 icode = rs6000_vector_reload[mode][in_p != false];
14827 if (icode != CODE_FOR_nothing)
14829 ret = NO_REGS;
14830 sri->icode = CODE_FOR_nothing;
14831 sri->extra_cost = 0;
14833 if (GET_CODE (x) == MEM)
14835 rtx addr = XEXP (x, 0);
14837 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
14838 an extra register in that case, but it would need an extra
14839 register if the addressing is reg+reg or (reg+reg)&(-16). */
14840 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
14842 if (!legitimate_indirect_address_p (addr, false)
14843 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14845 sri->icode = icode;
14846 /* account for splitting the loads, and converting the
14847 address from reg+reg to reg. */
14848 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
14849 + ((GET_CODE (addr) == AND) ? 1 : 0));
14852 /* Loads to and stores from vector registers can only do reg+reg
14853 addressing. Altivec registers can also do (reg+reg)&(-16). */
14854 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
14855 || rclass == FLOAT_REGS || rclass == NO_REGS)
14857 if (!VECTOR_MEM_ALTIVEC_P (mode)
14858 && GET_CODE (addr) == AND
14859 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14860 && INTVAL (XEXP (addr, 1)) == -16
14861 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
14862 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
14864 sri->icode = icode;
14865 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
14866 ? 2 : 1);
14868 else if (!legitimate_indirect_address_p (addr, false)
14869 && (rclass == NO_REGS
14870 || !legitimate_indexed_address_p (addr, false)))
14872 sri->icode = icode;
14873 sri->extra_cost = 1;
14875 else
14876 icode = CODE_FOR_nothing;
14878 /* Any other loads, including to pseudo registers which haven't been
14879 assigned to a register yet, default to require a scratch
14880 register. */
14881 else
14883 sri->icode = icode;
14884 sri->extra_cost = 2;
14887 else if (REG_P (x))
14889 int regno = true_regnum (x);
14891 icode = CODE_FOR_nothing;
14892 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
14893 default_p = true;
14894 else
14896 enum reg_class xclass = REGNO_REG_CLASS (regno);
14897 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
14898 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
14900 /* If memory is needed, use default_secondary_reload to create the
14901 stack slot. */
14902 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
14903 default_p = true;
14904 else
14905 ret = NO_REGS;
14908 else
14909 default_p = true;
14911 else
14912 default_p = true;
14914 if (default_p)
14915 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
14917 gcc_assert (ret != ALL_REGS);
14919 if (TARGET_DEBUG_ADDR)
14921 fprintf (stderr,
14922 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
14923 "mode = %s",
14924 reg_class_names[ret],
14925 in_p ? "true" : "false",
14926 reg_class_names[rclass],
14927 GET_MODE_NAME (mode));
14929 if (default_p)
14930 fprintf (stderr, ", default secondary reload");
14932 if (sri->icode != CODE_FOR_nothing)
14933 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
14934 insn_data[sri->icode].name, sri->extra_cost);
14935 else
14936 fprintf (stderr, "\n");
14938 debug_rtx (x);
14941 return ret;
14944 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
14945 to SP+reg addressing. */
14947 void
14948 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
14950 int regno = true_regnum (reg);
14951 enum machine_mode mode = GET_MODE (reg);
14952 enum reg_class rclass;
14953 rtx addr;
14954 rtx and_op2 = NULL_RTX;
14955 rtx addr_op1;
14956 rtx addr_op2;
14957 rtx scratch_or_premodify = scratch;
14958 rtx and_rtx;
14959 rtx cc_clobber;
14961 if (TARGET_DEBUG_ADDR)
14963 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
14964 store_p ? "store" : "load");
14965 fprintf (stderr, "reg:\n");
14966 debug_rtx (reg);
14967 fprintf (stderr, "mem:\n");
14968 debug_rtx (mem);
14969 fprintf (stderr, "scratch:\n");
14970 debug_rtx (scratch);
14973 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
14974 gcc_assert (GET_CODE (mem) == MEM);
14975 rclass = REGNO_REG_CLASS (regno);
14976 addr = XEXP (mem, 0);
14978 switch (rclass)
14980 /* GPRs can handle reg + small constant, all other addresses need to use
14981 the scratch register. */
14982 case GENERAL_REGS:
14983 case BASE_REGS:
14984 if (GET_CODE (addr) == AND)
14986 and_op2 = XEXP (addr, 1);
14987 addr = XEXP (addr, 0);
14990 if (GET_CODE (addr) == PRE_MODIFY)
14992 scratch_or_premodify = XEXP (addr, 0);
14993 gcc_assert (REG_P (scratch_or_premodify));
14994 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14995 addr = XEXP (addr, 1);
14998 if (GET_CODE (addr) == PLUS
14999 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
15000 || and_op2 != NULL_RTX))
15002 addr_op1 = XEXP (addr, 0);
15003 addr_op2 = XEXP (addr, 1);
15004 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
15006 if (!REG_P (addr_op2)
15007 && (GET_CODE (addr_op2) != CONST_INT
15008 || !satisfies_constraint_I (addr_op2)))
15010 if (TARGET_DEBUG_ADDR)
15012 fprintf (stderr,
15013 "\nMove plus addr to register %s, mode = %s: ",
15014 rs6000_reg_names[REGNO (scratch)],
15015 GET_MODE_NAME (mode));
15016 debug_rtx (addr_op2);
15018 rs6000_emit_move (scratch, addr_op2, Pmode);
15019 addr_op2 = scratch;
15022 emit_insn (gen_rtx_SET (VOIDmode,
15023 scratch_or_premodify,
15024 gen_rtx_PLUS (Pmode,
15025 addr_op1,
15026 addr_op2)));
15028 addr = scratch_or_premodify;
15029 scratch_or_premodify = scratch;
15031 else if (!legitimate_indirect_address_p (addr, false)
15032 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
15034 if (TARGET_DEBUG_ADDR)
15036 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
15037 rs6000_reg_names[REGNO (scratch_or_premodify)],
15038 GET_MODE_NAME (mode));
15039 debug_rtx (addr);
15041 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
15042 addr = scratch_or_premodify;
15043 scratch_or_premodify = scratch;
15045 break;
15047 /* Float/Altivec registers can only handle reg+reg addressing. Move
15048 other addresses into a scratch register. */
15049 case FLOAT_REGS:
15050 case VSX_REGS:
15051 case ALTIVEC_REGS:
15053 /* With float regs, we need to handle the AND ourselves, since we can't
15054 use the Altivec instruction with an implicit AND -16. Allow scalar
15055 loads to float registers to use reg+offset even if VSX. */
15056 if (GET_CODE (addr) == AND
15057 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
15058 || GET_CODE (XEXP (addr, 1)) != CONST_INT
15059 || INTVAL (XEXP (addr, 1)) != -16
15060 || !VECTOR_MEM_ALTIVEC_P (mode)))
15062 and_op2 = XEXP (addr, 1);
15063 addr = XEXP (addr, 0);
15066 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
15067 as the address later. */
15068 if (GET_CODE (addr) == PRE_MODIFY
15069 && (!VECTOR_MEM_VSX_P (mode)
15070 || and_op2 != NULL_RTX
15071 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
15073 scratch_or_premodify = XEXP (addr, 0);
15074 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
15075 false));
15076 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
15077 addr = XEXP (addr, 1);
15080 if (legitimate_indirect_address_p (addr, false) /* reg */
15081 || legitimate_indexed_address_p (addr, false) /* reg+reg */
15082 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
15083 || (GET_CODE (addr) == AND /* Altivec memory */
15084 && GET_CODE (XEXP (addr, 1)) == CONST_INT
15085 && INTVAL (XEXP (addr, 1)) == -16
15086 && VECTOR_MEM_ALTIVEC_P (mode))
15087 || (rclass == FLOAT_REGS /* legacy float mem */
15088 && GET_MODE_SIZE (mode) == 8
15089 && and_op2 == NULL_RTX
15090 && scratch_or_premodify == scratch
15091 && rs6000_legitimate_offset_address_p (mode, addr, false)))
15094 else if (GET_CODE (addr) == PLUS)
15096 addr_op1 = XEXP (addr, 0);
15097 addr_op2 = XEXP (addr, 1);
15098 gcc_assert (REG_P (addr_op1));
15100 if (TARGET_DEBUG_ADDR)
15102 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
15103 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
15104 debug_rtx (addr_op2);
15106 rs6000_emit_move (scratch, addr_op2, Pmode);
15107 emit_insn (gen_rtx_SET (VOIDmode,
15108 scratch_or_premodify,
15109 gen_rtx_PLUS (Pmode,
15110 addr_op1,
15111 scratch)));
15112 addr = scratch_or_premodify;
15113 scratch_or_premodify = scratch;
15116 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
15117 || GET_CODE (addr) == CONST_INT || REG_P (addr))
15119 if (TARGET_DEBUG_ADDR)
15121 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
15122 rs6000_reg_names[REGNO (scratch_or_premodify)],
15123 GET_MODE_NAME (mode));
15124 debug_rtx (addr);
15127 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
15128 addr = scratch_or_premodify;
15129 scratch_or_premodify = scratch;
15132 else
15133 gcc_unreachable ();
15135 break;
15137 default:
15138 gcc_unreachable ();
15141 /* If the original address involved a pre-modify that we couldn't use the VSX
15142 memory instruction with update, and we haven't taken care of already,
15143 store the address in the pre-modify register and use that as the
15144 address. */
15145 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
15147 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
15148 addr = scratch_or_premodify;
15151 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
15152 memory instruction, recreate the AND now, including the clobber which is
15153 generated by the general ANDSI3/ANDDI3 patterns for the
15154 andi. instruction. */
15155 if (and_op2 != NULL_RTX)
15157 if (! legitimate_indirect_address_p (addr, false))
15159 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
15160 addr = scratch;
15163 if (TARGET_DEBUG_ADDR)
15165 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
15166 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
15167 debug_rtx (and_op2);
15170 and_rtx = gen_rtx_SET (VOIDmode,
15171 scratch,
15172 gen_rtx_AND (Pmode,
15173 addr,
15174 and_op2));
15176 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
15177 emit_insn (gen_rtx_PARALLEL (VOIDmode,
15178 gen_rtvec (2, and_rtx, cc_clobber)));
15179 addr = scratch;
15182 /* Adjust the address if it changed. */
15183 if (addr != XEXP (mem, 0))
15185 mem = change_address (mem, mode, addr);
15186 if (TARGET_DEBUG_ADDR)
15187 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
15190 /* Now create the move. */
15191 if (store_p)
15192 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
15193 else
15194 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
15196 return;
15199 /* Target hook to return the cover classes for Integrated Register Allocator.
15200 Cover classes is a set of non-intersected register classes covering all hard
15201 registers used for register allocation purpose. Any move between two
15202 registers of a cover class should be cheaper than load or store of the
15203 registers. The value is array of register classes with LIM_REG_CLASSES used
15204 as the end marker.
15206 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
15207 account for the Altivec and Floating registers being subsets of the VSX
15208 register set under VSX, but distinct register sets on pre-VSX machines. */
15210 static const reg_class_t *
15211 rs6000_ira_cover_classes (void)
15213 static const reg_class_t cover_pre_vsx[] = IRA_COVER_CLASSES_PRE_VSX;
15214 static const reg_class_t cover_vsx[] = IRA_COVER_CLASSES_VSX;
15216 return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
15219 /* Allocate a 64-bit stack slot to be used for copying SDmode
15220 values through if this function has any SDmode references. */
15222 static void
15223 rs6000_alloc_sdmode_stack_slot (void)
15225 tree t;
15226 basic_block bb;
15227 gimple_stmt_iterator gsi;
15229 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
15231 FOR_EACH_BB (bb)
15232 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
15234 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
15235 if (ret)
15237 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
15238 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
15239 SDmode, 0);
15240 return;
15244 /* Check for any SDmode parameters of the function. */
15245 for (t = DECL_ARGUMENTS (cfun->decl); t; t = DECL_CHAIN (t))
15247 if (TREE_TYPE (t) == error_mark_node)
15248 continue;
15250 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
15251 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
15253 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
15254 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
15255 SDmode, 0);
15256 return;
15261 static void
15262 rs6000_instantiate_decls (void)
15264 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
15265 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
15268 /* Given an rtx X being reloaded into a reg required to be
15269 in class CLASS, return the class of reg to actually use.
15270 In general this is just CLASS; but on some machines
15271 in some cases it is preferable to use a more restrictive class.
15273 On the RS/6000, we have to return NO_REGS when we want to reload a
15274 floating-point CONST_DOUBLE to force it to be copied to memory.
15276 We also don't want to reload integer values into floating-point
15277 registers if we can at all help it. In fact, this can
15278 cause reload to die, if it tries to generate a reload of CTR
15279 into a FP register and discovers it doesn't have the memory location
15280 required.
15282 ??? Would it be a good idea to have reload do the converse, that is
15283 try to reload floating modes into FP registers if possible?
15286 static enum reg_class
15287 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
15289 enum machine_mode mode = GET_MODE (x);
15291 if (VECTOR_UNIT_VSX_P (mode)
15292 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
15293 return rclass;
15295 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
15296 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
15297 && easy_vector_constant (x, mode))
15298 return ALTIVEC_REGS;
15300 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
15301 return NO_REGS;
15303 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
15304 return GENERAL_REGS;
15306 /* For VSX, prefer the traditional registers for 64-bit values because we can
15307 use the non-VSX loads. Prefer the Altivec registers if Altivec is
15308 handling the vector operations (i.e. V16QI, V8HI, and V4SI), or if we
15309 prefer Altivec loads.. */
15310 if (rclass == VSX_REGS)
15312 if (GET_MODE_SIZE (mode) <= 8)
15313 return FLOAT_REGS;
15315 if (VECTOR_UNIT_ALTIVEC_P (mode) || VECTOR_MEM_ALTIVEC_P (mode))
15316 return ALTIVEC_REGS;
15318 return rclass;
15321 return rclass;
15324 /* Debug version of rs6000_preferred_reload_class. */
15325 static enum reg_class
15326 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
15328 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
15330 fprintf (stderr,
15331 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
15332 "mode = %s, x:\n",
15333 reg_class_names[ret], reg_class_names[rclass],
15334 GET_MODE_NAME (GET_MODE (x)));
15335 debug_rtx (x);
15337 return ret;
15340 /* If we are copying between FP or AltiVec registers and anything else, we need
15341 a memory location. The exception is when we are targeting ppc64 and the
15342 move to/from fpr to gpr instructions are available. Also, under VSX, you
15343 can copy vector registers from the FP register set to the Altivec register
15344 set and vice versa. */
15346 static bool
15347 rs6000_secondary_memory_needed (enum reg_class class1,
15348 enum reg_class class2,
15349 enum machine_mode mode)
15351 if (class1 == class2)
15352 return false;
15354 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
15355 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
15356 between these classes. But we need memory for other things that can go in
15357 FLOAT_REGS like SFmode. */
15358 if (TARGET_VSX
15359 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
15360 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
15361 || class1 == FLOAT_REGS))
15362 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
15363 && class2 != FLOAT_REGS);
15365 if (class1 == VSX_REGS || class2 == VSX_REGS)
15366 return true;
15368 if (class1 == FLOAT_REGS
15369 && (!TARGET_MFPGPR || !TARGET_POWERPC64
15370 || ((mode != DFmode)
15371 && (mode != DDmode)
15372 && (mode != DImode))))
15373 return true;
15375 if (class2 == FLOAT_REGS
15376 && (!TARGET_MFPGPR || !TARGET_POWERPC64
15377 || ((mode != DFmode)
15378 && (mode != DDmode)
15379 && (mode != DImode))))
15380 return true;
15382 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
15383 return true;
15385 return false;
15388 /* Debug version of rs6000_secondary_memory_needed. */
15389 static bool
15390 rs6000_debug_secondary_memory_needed (enum reg_class class1,
15391 enum reg_class class2,
15392 enum machine_mode mode)
15394 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
15396 fprintf (stderr,
15397 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
15398 "class2 = %s, mode = %s\n",
15399 ret ? "true" : "false", reg_class_names[class1],
15400 reg_class_names[class2], GET_MODE_NAME (mode));
15402 return ret;
15405 /* Return the register class of a scratch register needed to copy IN into
15406 or out of a register in RCLASS in MODE. If it can be done directly,
15407 NO_REGS is returned. */
15409 static enum reg_class
15410 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
15411 rtx in)
15413 int regno;
15415 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
15416 #if TARGET_MACHO
15417 && MACHOPIC_INDIRECT
15418 #endif
15421 /* We cannot copy a symbolic operand directly into anything
15422 other than BASE_REGS for TARGET_ELF. So indicate that a
15423 register from BASE_REGS is needed as an intermediate
15424 register.
15426 On Darwin, pic addresses require a load from memory, which
15427 needs a base register. */
15428 if (rclass != BASE_REGS
15429 && (GET_CODE (in) == SYMBOL_REF
15430 || GET_CODE (in) == HIGH
15431 || GET_CODE (in) == LABEL_REF
15432 || GET_CODE (in) == CONST))
15433 return BASE_REGS;
15436 if (GET_CODE (in) == REG)
15438 regno = REGNO (in);
15439 if (regno >= FIRST_PSEUDO_REGISTER)
15441 regno = true_regnum (in);
15442 if (regno >= FIRST_PSEUDO_REGISTER)
15443 regno = -1;
15446 else if (GET_CODE (in) == SUBREG)
15448 regno = true_regnum (in);
15449 if (regno >= FIRST_PSEUDO_REGISTER)
15450 regno = -1;
15452 else
15453 regno = -1;
15455 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
15456 into anything. */
15457 if (rclass == GENERAL_REGS || rclass == BASE_REGS
15458 || (regno >= 0 && INT_REGNO_P (regno)))
15459 return NO_REGS;
15461 /* Constants, memory, and FP registers can go into FP registers. */
15462 if ((regno == -1 || FP_REGNO_P (regno))
15463 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
15464 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
15466 /* Memory, and FP/altivec registers can go into fp/altivec registers under
15467 VSX. */
15468 if (TARGET_VSX
15469 && (regno == -1 || VSX_REGNO_P (regno))
15470 && VSX_REG_CLASS_P (rclass))
15471 return NO_REGS;
15473 /* Memory, and AltiVec registers can go into AltiVec registers. */
15474 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
15475 && rclass == ALTIVEC_REGS)
15476 return NO_REGS;
15478 /* We can copy among the CR registers. */
15479 if ((rclass == CR_REGS || rclass == CR0_REGS)
15480 && regno >= 0 && CR_REGNO_P (regno))
15481 return NO_REGS;
15483 /* Otherwise, we need GENERAL_REGS. */
15484 return GENERAL_REGS;
15487 /* Debug version of rs6000_secondary_reload_class. */
15488 static enum reg_class
15489 rs6000_debug_secondary_reload_class (enum reg_class rclass,
15490 enum machine_mode mode, rtx in)
15492 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
15493 fprintf (stderr,
15494 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
15495 "mode = %s, input rtx:\n",
15496 reg_class_names[ret], reg_class_names[rclass],
15497 GET_MODE_NAME (mode));
15498 debug_rtx (in);
15500 return ret;
15503 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
15505 static bool
15506 rs6000_cannot_change_mode_class (enum machine_mode from,
15507 enum machine_mode to,
15508 enum reg_class rclass)
15510 unsigned from_size = GET_MODE_SIZE (from);
15511 unsigned to_size = GET_MODE_SIZE (to);
15513 if (from_size != to_size)
15515 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
15516 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
15517 && reg_classes_intersect_p (xclass, rclass));
15520 if (TARGET_E500_DOUBLE
15521 && ((((to) == DFmode) + ((from) == DFmode)) == 1
15522 || (((to) == TFmode) + ((from) == TFmode)) == 1
15523 || (((to) == DDmode) + ((from) == DDmode)) == 1
15524 || (((to) == TDmode) + ((from) == TDmode)) == 1
15525 || (((to) == DImode) + ((from) == DImode)) == 1))
15526 return true;
15528 /* Since the VSX register set includes traditional floating point registers
15529 and altivec registers, just check for the size being different instead of
15530 trying to check whether the modes are vector modes. Otherwise it won't
15531 allow say DF and DI to change classes. */
15532 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
15533 return (from_size != 8 && from_size != 16);
15535 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
15536 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
15537 return true;
15539 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
15540 && reg_classes_intersect_p (GENERAL_REGS, rclass))
15541 return true;
15543 return false;
15546 /* Debug version of rs6000_cannot_change_mode_class. */
15547 static bool
15548 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
15549 enum machine_mode to,
15550 enum reg_class rclass)
15552 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
15554 fprintf (stderr,
15555 "rs6000_cannot_change_mode_class, return %s, from = %s, "
15556 "to = %s, rclass = %s\n",
15557 ret ? "true" : "false",
15558 GET_MODE_NAME (from), GET_MODE_NAME (to),
15559 reg_class_names[rclass]);
15561 return ret;
15564 /* Given a comparison operation, return the bit number in CCR to test. We
15565 know this is a valid comparison.
15567 SCC_P is 1 if this is for an scc. That means that %D will have been
15568 used instead of %C, so the bits will be in different places.
15570 Return -1 if OP isn't a valid comparison for some reason. */
15573 ccr_bit (rtx op, int scc_p)
15575 enum rtx_code code = GET_CODE (op);
15576 enum machine_mode cc_mode;
15577 int cc_regnum;
15578 int base_bit;
15579 rtx reg;
15581 if (!COMPARISON_P (op))
15582 return -1;
15584 reg = XEXP (op, 0);
15586 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
15588 cc_mode = GET_MODE (reg);
15589 cc_regnum = REGNO (reg);
15590 base_bit = 4 * (cc_regnum - CR0_REGNO);
15592 validate_condition_mode (code, cc_mode);
15594 /* When generating a sCOND operation, only positive conditions are
15595 allowed. */
15596 gcc_assert (!scc_p
15597 || code == EQ || code == GT || code == LT || code == UNORDERED
15598 || code == GTU || code == LTU);
15600 switch (code)
15602 case NE:
15603 return scc_p ? base_bit + 3 : base_bit + 2;
15604 case EQ:
15605 return base_bit + 2;
15606 case GT: case GTU: case UNLE:
15607 return base_bit + 1;
15608 case LT: case LTU: case UNGE:
15609 return base_bit;
15610 case ORDERED: case UNORDERED:
15611 return base_bit + 3;
15613 case GE: case GEU:
15614 /* If scc, we will have done a cror to put the bit in the
15615 unordered position. So test that bit. For integer, this is ! LT
15616 unless this is an scc insn. */
15617 return scc_p ? base_bit + 3 : base_bit;
15619 case LE: case LEU:
15620 return scc_p ? base_bit + 3 : base_bit + 1;
15622 default:
15623 gcc_unreachable ();
15627 /* Return the GOT register. */
15630 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
15632 /* The second flow pass currently (June 1999) can't update
15633 regs_ever_live without disturbing other parts of the compiler, so
15634 update it here to make the prolog/epilogue code happy. */
15635 if (!can_create_pseudo_p ()
15636 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
15637 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
15639 crtl->uses_pic_offset_table = 1;
15641 return pic_offset_table_rtx;
15644 static rs6000_stack_t stack_info;
15646 /* Function to init struct machine_function.
15647 This will be called, via a pointer variable,
15648 from push_function_context. */
15650 static struct machine_function *
15651 rs6000_init_machine_status (void)
15653 stack_info.reload_completed = 0;
15654 return ggc_alloc_cleared_machine_function ();
15657 /* These macros test for integers and extract the low-order bits. */
15658 #define INT_P(X) \
15659 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
15660 && GET_MODE (X) == VOIDmode)
15662 #define INT_LOWPART(X) \
15663 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
15666 extract_MB (rtx op)
15668 int i;
15669 unsigned long val = INT_LOWPART (op);
15671 /* If the high bit is zero, the value is the first 1 bit we find
15672 from the left. */
15673 if ((val & 0x80000000) == 0)
15675 gcc_assert (val & 0xffffffff);
15677 i = 1;
15678 while (((val <<= 1) & 0x80000000) == 0)
15679 ++i;
15680 return i;
15683 /* If the high bit is set and the low bit is not, or the mask is all
15684 1's, the value is zero. */
15685 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
15686 return 0;
15688 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15689 from the right. */
15690 i = 31;
15691 while (((val >>= 1) & 1) != 0)
15692 --i;
15694 return i;
15698 extract_ME (rtx op)
15700 int i;
15701 unsigned long val = INT_LOWPART (op);
15703 /* If the low bit is zero, the value is the first 1 bit we find from
15704 the right. */
15705 if ((val & 1) == 0)
15707 gcc_assert (val & 0xffffffff);
15709 i = 30;
15710 while (((val >>= 1) & 1) == 0)
15711 --i;
15713 return i;
15716 /* If the low bit is set and the high bit is not, or the mask is all
15717 1's, the value is 31. */
15718 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
15719 return 31;
15721 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15722 from the left. */
15723 i = 0;
15724 while (((val <<= 1) & 0x80000000) != 0)
15725 ++i;
15727 return i;
15730 /* Locate some local-dynamic symbol still in use by this function
15731 so that we can print its name in some tls_ld pattern. */
15733 static const char *
15734 rs6000_get_some_local_dynamic_name (void)
15736 rtx insn;
15738 if (cfun->machine->some_ld_name)
15739 return cfun->machine->some_ld_name;
15741 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
15742 if (INSN_P (insn)
15743 && for_each_rtx (&PATTERN (insn),
15744 rs6000_get_some_local_dynamic_name_1, 0))
15745 return cfun->machine->some_ld_name;
15747 gcc_unreachable ();
15750 /* Helper function for rs6000_get_some_local_dynamic_name. */
15752 static int
15753 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
15755 rtx x = *px;
15757 if (GET_CODE (x) == SYMBOL_REF)
15759 const char *str = XSTR (x, 0);
15760 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
15762 cfun->machine->some_ld_name = str;
15763 return 1;
15767 return 0;
15770 /* Write out a function code label. */
15772 void
15773 rs6000_output_function_entry (FILE *file, const char *fname)
15775 if (fname[0] != '.')
15777 switch (DEFAULT_ABI)
15779 default:
15780 gcc_unreachable ();
15782 case ABI_AIX:
15783 if (DOT_SYMBOLS)
15784 putc ('.', file);
15785 else
15786 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
15787 break;
15789 case ABI_V4:
15790 case ABI_DARWIN:
15791 break;
15795 RS6000_OUTPUT_BASENAME (file, fname);
15798 /* Print an operand. Recognize special options, documented below. */
15800 #if TARGET_ELF
15801 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
15802 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
15803 #else
15804 #define SMALL_DATA_RELOC "sda21"
15805 #define SMALL_DATA_REG 0
15806 #endif
15808 void
15809 print_operand (FILE *file, rtx x, int code)
15811 int i;
15812 HOST_WIDE_INT val;
15813 unsigned HOST_WIDE_INT uval;
15815 switch (code)
15817 case '.':
15818 /* Write out an instruction after the call which may be replaced
15819 with glue code by the loader. This depends on the AIX version. */
15820 asm_fprintf (file, RS6000_CALL_GLUE);
15821 return;
15823 /* %a is output_address. */
15825 case 'A':
15826 /* If X is a constant integer whose low-order 5 bits are zero,
15827 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
15828 in the AIX assembler where "sri" with a zero shift count
15829 writes a trash instruction. */
15830 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
15831 putc ('l', file);
15832 else
15833 putc ('r', file);
15834 return;
15836 case 'b':
15837 /* If constant, low-order 16 bits of constant, unsigned.
15838 Otherwise, write normally. */
15839 if (INT_P (x))
15840 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
15841 else
15842 print_operand (file, x, 0);
15843 return;
15845 case 'B':
15846 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
15847 for 64-bit mask direction. */
15848 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
15849 return;
15851 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
15852 output_operand. */
15854 case 'c':
15855 /* X is a CR register. Print the number of the GT bit of the CR. */
15856 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15857 output_operand_lossage ("invalid %%c value");
15858 else
15859 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
15860 return;
15862 case 'D':
15863 /* Like 'J' but get to the GT bit only. */
15864 gcc_assert (GET_CODE (x) == REG);
15866 /* Bit 1 is GT bit. */
15867 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
15869 /* Add one for shift count in rlinm for scc. */
15870 fprintf (file, "%d", i + 1);
15871 return;
15873 case 'E':
15874 /* X is a CR register. Print the number of the EQ bit of the CR */
15875 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15876 output_operand_lossage ("invalid %%E value");
15877 else
15878 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
15879 return;
15881 case 'f':
15882 /* X is a CR register. Print the shift count needed to move it
15883 to the high-order four bits. */
15884 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15885 output_operand_lossage ("invalid %%f value");
15886 else
15887 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
15888 return;
15890 case 'F':
15891 /* Similar, but print the count for the rotate in the opposite
15892 direction. */
15893 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15894 output_operand_lossage ("invalid %%F value");
15895 else
15896 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
15897 return;
15899 case 'G':
15900 /* X is a constant integer. If it is negative, print "m",
15901 otherwise print "z". This is to make an aze or ame insn. */
15902 if (GET_CODE (x) != CONST_INT)
15903 output_operand_lossage ("invalid %%G value");
15904 else if (INTVAL (x) >= 0)
15905 putc ('z', file);
15906 else
15907 putc ('m', file);
15908 return;
15910 case 'h':
15911 /* If constant, output low-order five bits. Otherwise, write
15912 normally. */
15913 if (INT_P (x))
15914 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
15915 else
15916 print_operand (file, x, 0);
15917 return;
15919 case 'H':
15920 /* If constant, output low-order six bits. Otherwise, write
15921 normally. */
15922 if (INT_P (x))
15923 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
15924 else
15925 print_operand (file, x, 0);
15926 return;
15928 case 'I':
15929 /* Print `i' if this is a constant, else nothing. */
15930 if (INT_P (x))
15931 putc ('i', file);
15932 return;
15934 case 'j':
15935 /* Write the bit number in CCR for jump. */
15936 i = ccr_bit (x, 0);
15937 if (i == -1)
15938 output_operand_lossage ("invalid %%j code");
15939 else
15940 fprintf (file, "%d", i);
15941 return;
15943 case 'J':
15944 /* Similar, but add one for shift count in rlinm for scc and pass
15945 scc flag to `ccr_bit'. */
15946 i = ccr_bit (x, 1);
15947 if (i == -1)
15948 output_operand_lossage ("invalid %%J code");
15949 else
15950 /* If we want bit 31, write a shift count of zero, not 32. */
15951 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15952 return;
15954 case 'k':
15955 /* X must be a constant. Write the 1's complement of the
15956 constant. */
15957 if (! INT_P (x))
15958 output_operand_lossage ("invalid %%k value");
15959 else
15960 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
15961 return;
15963 case 'K':
15964 /* X must be a symbolic constant on ELF. Write an
15965 expression suitable for an 'addi' that adds in the low 16
15966 bits of the MEM. */
15967 if (GET_CODE (x) == CONST)
15969 if (GET_CODE (XEXP (x, 0)) != PLUS
15970 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
15971 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
15972 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
15973 output_operand_lossage ("invalid %%K value");
15975 print_operand_address (file, x);
15976 fputs ("@l", file);
15977 return;
15979 /* %l is output_asm_label. */
15981 case 'L':
15982 /* Write second word of DImode or DFmode reference. Works on register
15983 or non-indexed memory only. */
15984 if (GET_CODE (x) == REG)
15985 fputs (reg_names[REGNO (x) + 1], file);
15986 else if (GET_CODE (x) == MEM)
15988 /* Handle possible auto-increment. Since it is pre-increment and
15989 we have already done it, we can just use an offset of word. */
15990 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15991 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15992 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15993 UNITS_PER_WORD));
15994 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15995 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15996 UNITS_PER_WORD));
15997 else
15998 output_address (XEXP (adjust_address_nv (x, SImode,
15999 UNITS_PER_WORD),
16000 0));
16002 if (small_data_operand (x, GET_MODE (x)))
16003 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16004 reg_names[SMALL_DATA_REG]);
16006 return;
16008 case 'm':
16009 /* MB value for a mask operand. */
16010 if (! mask_operand (x, SImode))
16011 output_operand_lossage ("invalid %%m value");
16013 fprintf (file, "%d", extract_MB (x));
16014 return;
16016 case 'M':
16017 /* ME value for a mask operand. */
16018 if (! mask_operand (x, SImode))
16019 output_operand_lossage ("invalid %%M value");
16021 fprintf (file, "%d", extract_ME (x));
16022 return;
16024 /* %n outputs the negative of its operand. */
16026 case 'N':
16027 /* Write the number of elements in the vector times 4. */
16028 if (GET_CODE (x) != PARALLEL)
16029 output_operand_lossage ("invalid %%N value");
16030 else
16031 fprintf (file, "%d", XVECLEN (x, 0) * 4);
16032 return;
16034 case 'O':
16035 /* Similar, but subtract 1 first. */
16036 if (GET_CODE (x) != PARALLEL)
16037 output_operand_lossage ("invalid %%O value");
16038 else
16039 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
16040 return;
16042 case 'p':
16043 /* X is a CONST_INT that is a power of two. Output the logarithm. */
16044 if (! INT_P (x)
16045 || INT_LOWPART (x) < 0
16046 || (i = exact_log2 (INT_LOWPART (x))) < 0)
16047 output_operand_lossage ("invalid %%p value");
16048 else
16049 fprintf (file, "%d", i);
16050 return;
16052 case 'P':
16053 /* The operand must be an indirect memory reference. The result
16054 is the register name. */
16055 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
16056 || REGNO (XEXP (x, 0)) >= 32)
16057 output_operand_lossage ("invalid %%P value");
16058 else
16059 fputs (reg_names[REGNO (XEXP (x, 0))], file);
16060 return;
16062 case 'q':
16063 /* This outputs the logical code corresponding to a boolean
16064 expression. The expression may have one or both operands
16065 negated (if one, only the first one). For condition register
16066 logical operations, it will also treat the negated
16067 CR codes as NOTs, but not handle NOTs of them. */
16069 const char *const *t = 0;
16070 const char *s;
16071 enum rtx_code code = GET_CODE (x);
16072 static const char * const tbl[3][3] = {
16073 { "and", "andc", "nor" },
16074 { "or", "orc", "nand" },
16075 { "xor", "eqv", "xor" } };
16077 if (code == AND)
16078 t = tbl[0];
16079 else if (code == IOR)
16080 t = tbl[1];
16081 else if (code == XOR)
16082 t = tbl[2];
16083 else
16084 output_operand_lossage ("invalid %%q value");
16086 if (GET_CODE (XEXP (x, 0)) != NOT)
16087 s = t[0];
16088 else
16090 if (GET_CODE (XEXP (x, 1)) == NOT)
16091 s = t[2];
16092 else
16093 s = t[1];
16096 fputs (s, file);
16098 return;
16100 case 'Q':
16101 if (TARGET_MFCRF)
16102 fputc (',', file);
16103 /* FALLTHRU */
16104 else
16105 return;
16107 case 'R':
16108 /* X is a CR register. Print the mask for `mtcrf'. */
16109 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
16110 output_operand_lossage ("invalid %%R value");
16111 else
16112 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
16113 return;
16115 case 's':
16116 /* Low 5 bits of 32 - value */
16117 if (! INT_P (x))
16118 output_operand_lossage ("invalid %%s value");
16119 else
16120 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
16121 return;
16123 case 'S':
16124 /* PowerPC64 mask position. All 0's is excluded.
16125 CONST_INT 32-bit mask is considered sign-extended so any
16126 transition must occur within the CONST_INT, not on the boundary. */
16127 if (! mask64_operand (x, DImode))
16128 output_operand_lossage ("invalid %%S value");
16130 uval = INT_LOWPART (x);
16132 if (uval & 1) /* Clear Left */
16134 #if HOST_BITS_PER_WIDE_INT > 64
16135 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
16136 #endif
16137 i = 64;
16139 else /* Clear Right */
16141 uval = ~uval;
16142 #if HOST_BITS_PER_WIDE_INT > 64
16143 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
16144 #endif
16145 i = 63;
16147 while (uval != 0)
16148 --i, uval >>= 1;
16149 gcc_assert (i >= 0);
16150 fprintf (file, "%d", i);
16151 return;
16153 case 't':
16154 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
16155 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
16157 /* Bit 3 is OV bit. */
16158 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
16160 /* If we want bit 31, write a shift count of zero, not 32. */
16161 fprintf (file, "%d", i == 31 ? 0 : i + 1);
16162 return;
16164 case 'T':
16165 /* Print the symbolic name of a branch target register. */
16166 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
16167 && REGNO (x) != CTR_REGNO))
16168 output_operand_lossage ("invalid %%T value");
16169 else if (REGNO (x) == LR_REGNO)
16170 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
16171 else
16172 fputs ("ctr", file);
16173 return;
16175 case 'u':
16176 /* High-order 16 bits of constant for use in unsigned operand. */
16177 if (! INT_P (x))
16178 output_operand_lossage ("invalid %%u value");
16179 else
16180 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
16181 (INT_LOWPART (x) >> 16) & 0xffff);
16182 return;
16184 case 'v':
16185 /* High-order 16 bits of constant for use in signed operand. */
16186 if (! INT_P (x))
16187 output_operand_lossage ("invalid %%v value");
16188 else
16189 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
16190 (INT_LOWPART (x) >> 16) & 0xffff);
16191 return;
16193 case 'U':
16194 /* Print `u' if this has an auto-increment or auto-decrement. */
16195 if (GET_CODE (x) == MEM
16196 && (GET_CODE (XEXP (x, 0)) == PRE_INC
16197 || GET_CODE (XEXP (x, 0)) == PRE_DEC
16198 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
16199 putc ('u', file);
16200 return;
16202 case 'V':
16203 /* Print the trap code for this operand. */
16204 switch (GET_CODE (x))
16206 case EQ:
16207 fputs ("eq", file); /* 4 */
16208 break;
16209 case NE:
16210 fputs ("ne", file); /* 24 */
16211 break;
16212 case LT:
16213 fputs ("lt", file); /* 16 */
16214 break;
16215 case LE:
16216 fputs ("le", file); /* 20 */
16217 break;
16218 case GT:
16219 fputs ("gt", file); /* 8 */
16220 break;
16221 case GE:
16222 fputs ("ge", file); /* 12 */
16223 break;
16224 case LTU:
16225 fputs ("llt", file); /* 2 */
16226 break;
16227 case LEU:
16228 fputs ("lle", file); /* 6 */
16229 break;
16230 case GTU:
16231 fputs ("lgt", file); /* 1 */
16232 break;
16233 case GEU:
16234 fputs ("lge", file); /* 5 */
16235 break;
16236 default:
16237 gcc_unreachable ();
16239 break;
16241 case 'w':
16242 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
16243 normally. */
16244 if (INT_P (x))
16245 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
16246 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
16247 else
16248 print_operand (file, x, 0);
16249 return;
16251 case 'W':
16252 /* MB value for a PowerPC64 rldic operand. */
16253 val = (GET_CODE (x) == CONST_INT
16254 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
16256 if (val < 0)
16257 i = -1;
16258 else
16259 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
16260 if ((val <<= 1) < 0)
16261 break;
16263 #if HOST_BITS_PER_WIDE_INT == 32
16264 if (GET_CODE (x) == CONST_INT && i >= 0)
16265 i += 32; /* zero-extend high-part was all 0's */
16266 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
16268 val = CONST_DOUBLE_LOW (x);
16270 gcc_assert (val);
16271 if (val < 0)
16272 --i;
16273 else
16274 for ( ; i < 64; i++)
16275 if ((val <<= 1) < 0)
16276 break;
16278 #endif
16280 fprintf (file, "%d", i + 1);
16281 return;
16283 case 'x':
16284 /* X is a FPR or Altivec register used in a VSX context. */
16285 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
16286 output_operand_lossage ("invalid %%x value");
16287 else
16289 int reg = REGNO (x);
16290 int vsx_reg = (FP_REGNO_P (reg)
16291 ? reg - 32
16292 : reg - FIRST_ALTIVEC_REGNO + 32);
16294 #ifdef TARGET_REGNAMES
16295 if (TARGET_REGNAMES)
16296 fprintf (file, "%%vs%d", vsx_reg);
16297 else
16298 #endif
16299 fprintf (file, "%d", vsx_reg);
16301 return;
16303 case 'X':
16304 if (GET_CODE (x) == MEM
16305 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
16306 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
16307 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
16308 putc ('x', file);
16309 return;
16311 case 'Y':
16312 /* Like 'L', for third word of TImode */
16313 if (GET_CODE (x) == REG)
16314 fputs (reg_names[REGNO (x) + 2], file);
16315 else if (GET_CODE (x) == MEM)
16317 if (GET_CODE (XEXP (x, 0)) == PRE_INC
16318 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
16319 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
16320 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
16321 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
16322 else
16323 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
16324 if (small_data_operand (x, GET_MODE (x)))
16325 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16326 reg_names[SMALL_DATA_REG]);
16328 return;
16330 case 'z':
16331 /* X is a SYMBOL_REF. Write out the name preceded by a
16332 period and without any trailing data in brackets. Used for function
16333 names. If we are configured for System V (or the embedded ABI) on
16334 the PowerPC, do not emit the period, since those systems do not use
16335 TOCs and the like. */
16336 gcc_assert (GET_CODE (x) == SYMBOL_REF);
16338 /* Mark the decl as referenced so that cgraph will output the
16339 function. */
16340 if (SYMBOL_REF_DECL (x))
16341 mark_decl_referenced (SYMBOL_REF_DECL (x));
16343 /* For macho, check to see if we need a stub. */
16344 if (TARGET_MACHO)
16346 const char *name = XSTR (x, 0);
16347 #if TARGET_MACHO
16348 if (darwin_emit_branch_islands
16349 && MACHOPIC_INDIRECT
16350 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
16351 name = machopic_indirection_name (x, /*stub_p=*/true);
16352 #endif
16353 assemble_name (file, name);
16355 else if (!DOT_SYMBOLS)
16356 assemble_name (file, XSTR (x, 0));
16357 else
16358 rs6000_output_function_entry (file, XSTR (x, 0));
16359 return;
16361 case 'Z':
16362 /* Like 'L', for last word of TImode. */
16363 if (GET_CODE (x) == REG)
16364 fputs (reg_names[REGNO (x) + 3], file);
16365 else if (GET_CODE (x) == MEM)
16367 if (GET_CODE (XEXP (x, 0)) == PRE_INC
16368 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
16369 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
16370 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
16371 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
16372 else
16373 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
16374 if (small_data_operand (x, GET_MODE (x)))
16375 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16376 reg_names[SMALL_DATA_REG]);
16378 return;
16380 /* Print AltiVec or SPE memory operand. */
16381 case 'y':
16383 rtx tmp;
16385 gcc_assert (GET_CODE (x) == MEM);
16387 tmp = XEXP (x, 0);
16389 /* Ugly hack because %y is overloaded. */
16390 if ((TARGET_SPE || TARGET_E500_DOUBLE)
16391 && (GET_MODE_SIZE (GET_MODE (x)) == 8
16392 || GET_MODE (x) == TFmode
16393 || GET_MODE (x) == TImode))
16395 /* Handle [reg]. */
16396 if (GET_CODE (tmp) == REG)
16398 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
16399 break;
16401 /* Handle [reg+UIMM]. */
16402 else if (GET_CODE (tmp) == PLUS &&
16403 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
16405 int x;
16407 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
16409 x = INTVAL (XEXP (tmp, 1));
16410 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
16411 break;
16414 /* Fall through. Must be [reg+reg]. */
16416 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
16417 && GET_CODE (tmp) == AND
16418 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
16419 && INTVAL (XEXP (tmp, 1)) == -16)
16420 tmp = XEXP (tmp, 0);
16421 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
16422 && GET_CODE (tmp) == PRE_MODIFY)
16423 tmp = XEXP (tmp, 1);
16424 if (GET_CODE (tmp) == REG)
16425 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
16426 else
16428 if (!GET_CODE (tmp) == PLUS
16429 || !REG_P (XEXP (tmp, 0))
16430 || !REG_P (XEXP (tmp, 1)))
16432 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
16433 break;
16436 if (REGNO (XEXP (tmp, 0)) == 0)
16437 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
16438 reg_names[ REGNO (XEXP (tmp, 0)) ]);
16439 else
16440 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
16441 reg_names[ REGNO (XEXP (tmp, 1)) ]);
16443 break;
16446 case 0:
16447 if (GET_CODE (x) == REG)
16448 fprintf (file, "%s", reg_names[REGNO (x)]);
16449 else if (GET_CODE (x) == MEM)
16451 /* We need to handle PRE_INC and PRE_DEC here, since we need to
16452 know the width from the mode. */
16453 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
16454 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
16455 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
16456 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
16457 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
16458 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
16459 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
16460 output_address (XEXP (XEXP (x, 0), 1));
16461 else
16462 output_address (XEXP (x, 0));
16464 else
16466 if (toc_relative_expr_p (x))
16467 /* This hack along with a corresponding hack in
16468 rs6000_output_addr_const_extra arranges to output addends
16469 where the assembler expects to find them. eg.
16470 (const (plus (unspec [symbol_ref ("x") tocrel]) 4))
16471 without this hack would be output as "x@toc+4". We
16472 want "x+4@toc". */
16473 output_addr_const (file, tocrel_base);
16474 else
16475 output_addr_const (file, x);
16477 return;
16479 case '&':
16480 assemble_name (file, rs6000_get_some_local_dynamic_name ());
16481 return;
16483 default:
16484 output_operand_lossage ("invalid %%xn code");
16488 /* Print the address of an operand. */
16490 void
16491 print_operand_address (FILE *file, rtx x)
16493 if (GET_CODE (x) == REG)
16494 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
16495 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
16496 || GET_CODE (x) == LABEL_REF)
16498 output_addr_const (file, x);
16499 if (small_data_operand (x, GET_MODE (x)))
16500 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16501 reg_names[SMALL_DATA_REG]);
16502 else
16503 gcc_assert (!TARGET_TOC);
16505 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
16507 gcc_assert (REG_P (XEXP (x, 0)));
16508 if (REGNO (XEXP (x, 0)) == 0)
16509 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
16510 reg_names[ REGNO (XEXP (x, 0)) ]);
16511 else
16512 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
16513 reg_names[ REGNO (XEXP (x, 1)) ]);
16515 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
16516 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
16517 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
16518 #if TARGET_MACHO
16519 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
16520 && CONSTANT_P (XEXP (x, 1)))
16522 fprintf (file, "lo16(");
16523 output_addr_const (file, XEXP (x, 1));
16524 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16526 #endif
16527 else if (legitimate_constant_pool_address_p (x, QImode, true))
16529 /* This hack along with a corresponding hack in
16530 rs6000_output_addr_const_extra arranges to output addends
16531 where the assembler expects to find them. eg.
16532 (lo_sum (reg 9)
16533 . (const (plus (unspec [symbol_ref ("x") tocrel]) 8)))
16534 without this hack would be output as "x@toc+8@l(9)". We
16535 want "x+8@toc@l(9)". */
16536 output_addr_const (file, tocrel_base);
16537 if (GET_CODE (x) == LO_SUM)
16538 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16539 else
16540 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
16542 #if TARGET_ELF
16543 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
16544 && CONSTANT_P (XEXP (x, 1)))
16546 output_addr_const (file, XEXP (x, 1));
16547 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16549 #endif
16550 else
16551 gcc_unreachable ();
16554 /* Implement TARGET_OUTPUT_ADDR_CONST_EXTRA. */
16556 static bool
16557 rs6000_output_addr_const_extra (FILE *file, rtx x)
16559 if (GET_CODE (x) == UNSPEC)
16560 switch (XINT (x, 1))
16562 case UNSPEC_TOCREL:
16563 gcc_assert (GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF);
16564 output_addr_const (file, XVECEXP (x, 0, 0));
16565 if (x == tocrel_base && tocrel_offset != const0_rtx)
16567 if (INTVAL (tocrel_offset) >= 0)
16568 fprintf (file, "+");
16569 output_addr_const (file, tocrel_offset);
16571 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
16573 putc ('-', file);
16574 assemble_name (file, toc_label_name);
16576 else if (TARGET_ELF)
16577 fputs ("@toc", file);
16578 return true;
16580 #if TARGET_MACHO
16581 case UNSPEC_MACHOPIC_OFFSET:
16582 output_addr_const (file, XVECEXP (x, 0, 0));
16583 putc ('-', file);
16584 machopic_output_function_base_name (file);
16585 return true;
16586 #endif
16588 return false;
16591 /* Target hook for assembling integer objects. The PowerPC version has
16592 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
16593 is defined. It also needs to handle DI-mode objects on 64-bit
16594 targets. */
16596 static bool
16597 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
16599 #ifdef RELOCATABLE_NEEDS_FIXUP
16600 /* Special handling for SI values. */
16601 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
16603 static int recurse = 0;
16605 /* For -mrelocatable, we mark all addresses that need to be fixed up
16606 in the .fixup section. */
16607 if (TARGET_RELOCATABLE
16608 && in_section != toc_section
16609 && in_section != text_section
16610 && !unlikely_text_section_p (in_section)
16611 && !recurse
16612 && GET_CODE (x) != CONST_INT
16613 && GET_CODE (x) != CONST_DOUBLE
16614 && CONSTANT_P (x))
16616 char buf[256];
16618 recurse = 1;
16619 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
16620 fixuplabelno++;
16621 ASM_OUTPUT_LABEL (asm_out_file, buf);
16622 fprintf (asm_out_file, "\t.long\t(");
16623 output_addr_const (asm_out_file, x);
16624 fprintf (asm_out_file, ")@fixup\n");
16625 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
16626 ASM_OUTPUT_ALIGN (asm_out_file, 2);
16627 fprintf (asm_out_file, "\t.long\t");
16628 assemble_name (asm_out_file, buf);
16629 fprintf (asm_out_file, "\n\t.previous\n");
16630 recurse = 0;
16631 return true;
16633 /* Remove initial .'s to turn a -mcall-aixdesc function
16634 address into the address of the descriptor, not the function
16635 itself. */
16636 else if (GET_CODE (x) == SYMBOL_REF
16637 && XSTR (x, 0)[0] == '.'
16638 && DEFAULT_ABI == ABI_AIX)
16640 const char *name = XSTR (x, 0);
16641 while (*name == '.')
16642 name++;
16644 fprintf (asm_out_file, "\t.long\t%s\n", name);
16645 return true;
16648 #endif /* RELOCATABLE_NEEDS_FIXUP */
16649 return default_assemble_integer (x, size, aligned_p);
16652 #ifdef HAVE_GAS_HIDDEN
16653 /* Emit an assembler directive to set symbol visibility for DECL to
16654 VISIBILITY_TYPE. */
16656 static void
16657 rs6000_assemble_visibility (tree decl, int vis)
16659 /* Functions need to have their entry point symbol visibility set as
16660 well as their descriptor symbol visibility. */
16661 if (DEFAULT_ABI == ABI_AIX
16662 && DOT_SYMBOLS
16663 && TREE_CODE (decl) == FUNCTION_DECL)
16665 static const char * const visibility_types[] = {
16666 NULL, "internal", "hidden", "protected"
16669 const char *name, *type;
16671 name = ((* targetm.strip_name_encoding)
16672 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
16673 type = visibility_types[vis];
16675 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
16676 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
16678 else
16679 default_assemble_visibility (decl, vis);
16681 #endif
16683 enum rtx_code
16684 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
16686 /* Reversal of FP compares takes care -- an ordered compare
16687 becomes an unordered compare and vice versa. */
16688 if (mode == CCFPmode
16689 && (!flag_finite_math_only
16690 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
16691 || code == UNEQ || code == LTGT))
16692 return reverse_condition_maybe_unordered (code);
16693 else
16694 return reverse_condition (code);
16697 /* Generate a compare for CODE. Return a brand-new rtx that
16698 represents the result of the compare. */
16700 static rtx
16701 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
16703 enum machine_mode comp_mode;
16704 rtx compare_result;
16705 enum rtx_code code = GET_CODE (cmp);
16706 rtx op0 = XEXP (cmp, 0);
16707 rtx op1 = XEXP (cmp, 1);
16709 if (FLOAT_MODE_P (mode))
16710 comp_mode = CCFPmode;
16711 else if (code == GTU || code == LTU
16712 || code == GEU || code == LEU)
16713 comp_mode = CCUNSmode;
16714 else if ((code == EQ || code == NE)
16715 && GET_CODE (op0) == SUBREG
16716 && GET_CODE (op1) == SUBREG
16717 && SUBREG_PROMOTED_UNSIGNED_P (op0)
16718 && SUBREG_PROMOTED_UNSIGNED_P (op1))
16719 /* These are unsigned values, perhaps there will be a later
16720 ordering compare that can be shared with this one.
16721 Unfortunately we cannot detect the signedness of the operands
16722 for non-subregs. */
16723 comp_mode = CCUNSmode;
16724 else
16725 comp_mode = CCmode;
16727 /* First, the compare. */
16728 compare_result = gen_reg_rtx (comp_mode);
16730 /* E500 FP compare instructions on the GPRs. Yuck! */
16731 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
16732 && FLOAT_MODE_P (mode))
16734 rtx cmp, or_result, compare_result2;
16735 enum machine_mode op_mode = GET_MODE (op0);
16737 if (op_mode == VOIDmode)
16738 op_mode = GET_MODE (op1);
16740 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
16741 This explains the following mess. */
16743 switch (code)
16745 case EQ: case UNEQ: case NE: case LTGT:
16746 switch (op_mode)
16748 case SFmode:
16749 cmp = (flag_finite_math_only && !flag_trapping_math)
16750 ? gen_tstsfeq_gpr (compare_result, op0, op1)
16751 : gen_cmpsfeq_gpr (compare_result, op0, op1);
16752 break;
16754 case DFmode:
16755 cmp = (flag_finite_math_only && !flag_trapping_math)
16756 ? gen_tstdfeq_gpr (compare_result, op0, op1)
16757 : gen_cmpdfeq_gpr (compare_result, op0, op1);
16758 break;
16760 case TFmode:
16761 cmp = (flag_finite_math_only && !flag_trapping_math)
16762 ? gen_tsttfeq_gpr (compare_result, op0, op1)
16763 : gen_cmptfeq_gpr (compare_result, op0, op1);
16764 break;
16766 default:
16767 gcc_unreachable ();
16769 break;
16771 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
16772 switch (op_mode)
16774 case SFmode:
16775 cmp = (flag_finite_math_only && !flag_trapping_math)
16776 ? gen_tstsfgt_gpr (compare_result, op0, op1)
16777 : gen_cmpsfgt_gpr (compare_result, op0, op1);
16778 break;
16780 case DFmode:
16781 cmp = (flag_finite_math_only && !flag_trapping_math)
16782 ? gen_tstdfgt_gpr (compare_result, op0, op1)
16783 : gen_cmpdfgt_gpr (compare_result, op0, op1);
16784 break;
16786 case TFmode:
16787 cmp = (flag_finite_math_only && !flag_trapping_math)
16788 ? gen_tsttfgt_gpr (compare_result, op0, op1)
16789 : gen_cmptfgt_gpr (compare_result, op0, op1);
16790 break;
16792 default:
16793 gcc_unreachable ();
16795 break;
16797 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
16798 switch (op_mode)
16800 case SFmode:
16801 cmp = (flag_finite_math_only && !flag_trapping_math)
16802 ? gen_tstsflt_gpr (compare_result, op0, op1)
16803 : gen_cmpsflt_gpr (compare_result, op0, op1);
16804 break;
16806 case DFmode:
16807 cmp = (flag_finite_math_only && !flag_trapping_math)
16808 ? gen_tstdflt_gpr (compare_result, op0, op1)
16809 : gen_cmpdflt_gpr (compare_result, op0, op1);
16810 break;
16812 case TFmode:
16813 cmp = (flag_finite_math_only && !flag_trapping_math)
16814 ? gen_tsttflt_gpr (compare_result, op0, op1)
16815 : gen_cmptflt_gpr (compare_result, op0, op1);
16816 break;
16818 default:
16819 gcc_unreachable ();
16821 break;
16822 default:
16823 gcc_unreachable ();
16826 /* Synthesize LE and GE from LT/GT || EQ. */
16827 if (code == LE || code == GE || code == LEU || code == GEU)
16829 emit_insn (cmp);
16831 switch (code)
16833 case LE: code = LT; break;
16834 case GE: code = GT; break;
16835 case LEU: code = LT; break;
16836 case GEU: code = GT; break;
16837 default: gcc_unreachable ();
16840 compare_result2 = gen_reg_rtx (CCFPmode);
16842 /* Do the EQ. */
16843 switch (op_mode)
16845 case SFmode:
16846 cmp = (flag_finite_math_only && !flag_trapping_math)
16847 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
16848 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
16849 break;
16851 case DFmode:
16852 cmp = (flag_finite_math_only && !flag_trapping_math)
16853 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
16854 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
16855 break;
16857 case TFmode:
16858 cmp = (flag_finite_math_only && !flag_trapping_math)
16859 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
16860 : gen_cmptfeq_gpr (compare_result2, op0, op1);
16861 break;
16863 default:
16864 gcc_unreachable ();
16866 emit_insn (cmp);
16868 /* OR them together. */
16869 or_result = gen_reg_rtx (CCFPmode);
16870 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
16871 compare_result2);
16872 compare_result = or_result;
16873 code = EQ;
16875 else
16877 if (code == NE || code == LTGT)
16878 code = NE;
16879 else
16880 code = EQ;
16883 emit_insn (cmp);
16885 else
16887 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
16888 CLOBBERs to match cmptf_internal2 pattern. */
16889 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
16890 && GET_MODE (op0) == TFmode
16891 && !TARGET_IEEEQUAD
16892 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
16893 emit_insn (gen_rtx_PARALLEL (VOIDmode,
16894 gen_rtvec (10,
16895 gen_rtx_SET (VOIDmode,
16896 compare_result,
16897 gen_rtx_COMPARE (comp_mode, op0, op1)),
16898 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16899 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16900 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16901 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16902 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16903 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16904 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16905 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16906 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (Pmode)))));
16907 else if (GET_CODE (op1) == UNSPEC
16908 && XINT (op1, 1) == UNSPEC_SP_TEST)
16910 rtx op1b = XVECEXP (op1, 0, 0);
16911 comp_mode = CCEQmode;
16912 compare_result = gen_reg_rtx (CCEQmode);
16913 if (TARGET_64BIT)
16914 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
16915 else
16916 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
16918 else
16919 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
16920 gen_rtx_COMPARE (comp_mode, op0, op1)));
16923 /* Some kinds of FP comparisons need an OR operation;
16924 under flag_finite_math_only we don't bother. */
16925 if (FLOAT_MODE_P (mode)
16926 && !flag_finite_math_only
16927 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
16928 && (code == LE || code == GE
16929 || code == UNEQ || code == LTGT
16930 || code == UNGT || code == UNLT))
16932 enum rtx_code or1, or2;
16933 rtx or1_rtx, or2_rtx, compare2_rtx;
16934 rtx or_result = gen_reg_rtx (CCEQmode);
16936 switch (code)
16938 case LE: or1 = LT; or2 = EQ; break;
16939 case GE: or1 = GT; or2 = EQ; break;
16940 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
16941 case LTGT: or1 = LT; or2 = GT; break;
16942 case UNGT: or1 = UNORDERED; or2 = GT; break;
16943 case UNLT: or1 = UNORDERED; or2 = LT; break;
16944 default: gcc_unreachable ();
16946 validate_condition_mode (or1, comp_mode);
16947 validate_condition_mode (or2, comp_mode);
16948 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
16949 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
16950 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
16951 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
16952 const_true_rtx);
16953 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
16955 compare_result = or_result;
16956 code = EQ;
16959 validate_condition_mode (code, GET_MODE (compare_result));
16961 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
16965 /* Emit the RTL for an sISEL pattern. */
16967 void
16968 rs6000_emit_sISEL (enum machine_mode mode ATTRIBUTE_UNUSED, rtx operands[])
16970 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
16973 void
16974 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
16976 rtx condition_rtx;
16977 enum machine_mode op_mode;
16978 enum rtx_code cond_code;
16979 rtx result = operands[0];
16981 if (TARGET_ISEL && (mode == SImode || mode == DImode))
16983 rs6000_emit_sISEL (mode, operands);
16984 return;
16987 condition_rtx = rs6000_generate_compare (operands[1], mode);
16988 cond_code = GET_CODE (condition_rtx);
16990 if (FLOAT_MODE_P (mode)
16991 && !TARGET_FPRS && TARGET_HARD_FLOAT)
16993 rtx t;
16995 PUT_MODE (condition_rtx, SImode);
16996 t = XEXP (condition_rtx, 0);
16998 gcc_assert (cond_code == NE || cond_code == EQ);
17000 if (cond_code == NE)
17001 emit_insn (gen_e500_flip_gt_bit (t, t));
17003 emit_insn (gen_move_from_CR_gt_bit (result, t));
17004 return;
17007 if (cond_code == NE
17008 || cond_code == GE || cond_code == LE
17009 || cond_code == GEU || cond_code == LEU
17010 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
17012 rtx not_result = gen_reg_rtx (CCEQmode);
17013 rtx not_op, rev_cond_rtx;
17014 enum machine_mode cc_mode;
17016 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
17018 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
17019 SImode, XEXP (condition_rtx, 0), const0_rtx);
17020 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
17021 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
17022 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
17025 op_mode = GET_MODE (XEXP (operands[1], 0));
17026 if (op_mode == VOIDmode)
17027 op_mode = GET_MODE (XEXP (operands[1], 1));
17029 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
17031 PUT_MODE (condition_rtx, DImode);
17032 convert_move (result, condition_rtx, 0);
17034 else
17036 PUT_MODE (condition_rtx, SImode);
17037 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
17041 /* Emit a branch of kind CODE to location LOC. */
17043 void
17044 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
17046 rtx condition_rtx, loc_ref;
17048 condition_rtx = rs6000_generate_compare (operands[0], mode);
17049 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
17050 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
17051 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
17052 loc_ref, pc_rtx)));
17055 /* Return the string to output a conditional branch to LABEL, which is
17056 the operand number of the label, or -1 if the branch is really a
17057 conditional return.
17059 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
17060 condition code register and its mode specifies what kind of
17061 comparison we made.
17063 REVERSED is nonzero if we should reverse the sense of the comparison.
17065 INSN is the insn. */
17067 char *
17068 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
17070 static char string[64];
17071 enum rtx_code code = GET_CODE (op);
17072 rtx cc_reg = XEXP (op, 0);
17073 enum machine_mode mode = GET_MODE (cc_reg);
17074 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
17075 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
17076 int really_reversed = reversed ^ need_longbranch;
17077 char *s = string;
17078 const char *ccode;
17079 const char *pred;
17080 rtx note;
17082 validate_condition_mode (code, mode);
17084 /* Work out which way this really branches. We could use
17085 reverse_condition_maybe_unordered here always but this
17086 makes the resulting assembler clearer. */
17087 if (really_reversed)
17089 /* Reversal of FP compares takes care -- an ordered compare
17090 becomes an unordered compare and vice versa. */
17091 if (mode == CCFPmode)
17092 code = reverse_condition_maybe_unordered (code);
17093 else
17094 code = reverse_condition (code);
17097 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
17099 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
17100 to the GT bit. */
17101 switch (code)
17103 case EQ:
17104 /* Opposite of GT. */
17105 code = GT;
17106 break;
17108 case NE:
17109 code = UNLE;
17110 break;
17112 default:
17113 gcc_unreachable ();
17117 switch (code)
17119 /* Not all of these are actually distinct opcodes, but
17120 we distinguish them for clarity of the resulting assembler. */
17121 case NE: case LTGT:
17122 ccode = "ne"; break;
17123 case EQ: case UNEQ:
17124 ccode = "eq"; break;
17125 case GE: case GEU:
17126 ccode = "ge"; break;
17127 case GT: case GTU: case UNGT:
17128 ccode = "gt"; break;
17129 case LE: case LEU:
17130 ccode = "le"; break;
17131 case LT: case LTU: case UNLT:
17132 ccode = "lt"; break;
17133 case UNORDERED: ccode = "un"; break;
17134 case ORDERED: ccode = "nu"; break;
17135 case UNGE: ccode = "nl"; break;
17136 case UNLE: ccode = "ng"; break;
17137 default:
17138 gcc_unreachable ();
17141 /* Maybe we have a guess as to how likely the branch is.
17142 The old mnemonics don't have a way to specify this information. */
17143 pred = "";
17144 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
17145 if (note != NULL_RTX)
17147 /* PROB is the difference from 50%. */
17148 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
17150 /* Only hint for highly probable/improbable branches on newer
17151 cpus as static prediction overrides processor dynamic
17152 prediction. For older cpus we may as well always hint, but
17153 assume not taken for branches that are very close to 50% as a
17154 mispredicted taken branch is more expensive than a
17155 mispredicted not-taken branch. */
17156 if (rs6000_always_hint
17157 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
17158 && br_prob_note_reliable_p (note)))
17160 if (abs (prob) > REG_BR_PROB_BASE / 20
17161 && ((prob > 0) ^ need_longbranch))
17162 pred = "+";
17163 else
17164 pred = "-";
17168 if (label == NULL)
17169 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
17170 else
17171 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
17173 /* We need to escape any '%' characters in the reg_names string.
17174 Assume they'd only be the first character.... */
17175 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
17176 *s++ = '%';
17177 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
17179 if (label != NULL)
17181 /* If the branch distance was too far, we may have to use an
17182 unconditional branch to go the distance. */
17183 if (need_longbranch)
17184 s += sprintf (s, ",$+8\n\tb %s", label);
17185 else
17186 s += sprintf (s, ",%s", label);
17189 return string;
17192 /* Return the string to flip the GT bit on a CR. */
17193 char *
17194 output_e500_flip_gt_bit (rtx dst, rtx src)
17196 static char string[64];
17197 int a, b;
17199 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
17200 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
17202 /* GT bit. */
17203 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
17204 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
17206 sprintf (string, "crnot %d,%d", a, b);
17207 return string;
17210 /* Return insn for VSX or Altivec comparisons. */
17212 static rtx
17213 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
17215 rtx mask;
17216 enum machine_mode mode = GET_MODE (op0);
17218 switch (code)
17220 default:
17221 break;
17223 case GE:
17224 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
17225 return NULL_RTX;
17227 case EQ:
17228 case GT:
17229 case GTU:
17230 mask = gen_reg_rtx (mode);
17231 emit_insn (gen_rtx_SET (VOIDmode,
17232 mask,
17233 gen_rtx_fmt_ee (code, mode, op0, op1)));
17234 return mask;
17237 return NULL_RTX;
17240 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
17241 DMODE is expected destination mode. This is a recursive function. */
17243 static rtx
17244 rs6000_emit_vector_compare (enum rtx_code rcode,
17245 rtx op0, rtx op1,
17246 enum machine_mode dmode)
17248 rtx mask;
17249 bool swap_operands = false;
17250 bool try_again = false;
17252 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
17253 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
17255 /* See if the comparison works as is. */
17256 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
17257 if (mask)
17258 return mask;
17260 switch (rcode)
17262 case LT:
17263 rcode = GT;
17264 swap_operands = true;
17265 try_again = true;
17266 break;
17267 case LTU:
17268 rcode = GTU;
17269 swap_operands = true;
17270 try_again = true;
17271 break;
17272 case NE:
17273 case UNLE:
17274 case UNLT:
17275 case UNGE:
17276 case UNGT:
17277 /* Invert condition and try again.
17278 e.g., A != B becomes ~(A==B). */
17280 enum rtx_code rev_code;
17281 enum insn_code nor_code;
17282 rtx mask2;
17284 rev_code = reverse_condition_maybe_unordered (rcode);
17285 if (rev_code == UNKNOWN)
17286 return NULL_RTX;
17288 nor_code = optab_handler (one_cmpl_optab, dmode);
17289 if (nor_code == CODE_FOR_nothing)
17290 return NULL_RTX;
17292 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
17293 if (!mask2)
17294 return NULL_RTX;
17296 mask = gen_reg_rtx (dmode);
17297 emit_insn (GEN_FCN (nor_code) (mask, mask2));
17298 return mask;
17300 break;
17301 case GE:
17302 case GEU:
17303 case LE:
17304 case LEU:
17305 /* Try GT/GTU/LT/LTU OR EQ */
17307 rtx c_rtx, eq_rtx;
17308 enum insn_code ior_code;
17309 enum rtx_code new_code;
17311 switch (rcode)
17313 case GE:
17314 new_code = GT;
17315 break;
17317 case GEU:
17318 new_code = GTU;
17319 break;
17321 case LE:
17322 new_code = LT;
17323 break;
17325 case LEU:
17326 new_code = LTU;
17327 break;
17329 default:
17330 gcc_unreachable ();
17333 ior_code = optab_handler (ior_optab, dmode);
17334 if (ior_code == CODE_FOR_nothing)
17335 return NULL_RTX;
17337 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
17338 if (!c_rtx)
17339 return NULL_RTX;
17341 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
17342 if (!eq_rtx)
17343 return NULL_RTX;
17345 mask = gen_reg_rtx (dmode);
17346 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
17347 return mask;
17349 break;
17350 default:
17351 return NULL_RTX;
17354 if (try_again)
17356 if (swap_operands)
17358 rtx tmp;
17359 tmp = op0;
17360 op0 = op1;
17361 op1 = tmp;
17364 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
17365 if (mask)
17366 return mask;
17369 /* You only get two chances. */
17370 return NULL_RTX;
17373 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
17374 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
17375 operands for the relation operation COND. */
17378 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
17379 rtx cond, rtx cc_op0, rtx cc_op1)
17381 enum machine_mode dest_mode = GET_MODE (dest);
17382 enum rtx_code rcode = GET_CODE (cond);
17383 enum machine_mode cc_mode = CCmode;
17384 rtx mask;
17385 rtx cond2;
17386 rtx tmp;
17387 bool invert_move = false;
17389 if (VECTOR_UNIT_NONE_P (dest_mode))
17390 return 0;
17392 switch (rcode)
17394 /* Swap operands if we can, and fall back to doing the operation as
17395 specified, and doing a NOR to invert the test. */
17396 case NE:
17397 case UNLE:
17398 case UNLT:
17399 case UNGE:
17400 case UNGT:
17401 /* Invert condition and try again.
17402 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
17403 invert_move = true;
17404 rcode = reverse_condition_maybe_unordered (rcode);
17405 if (rcode == UNKNOWN)
17406 return 0;
17407 break;
17409 /* Mark unsigned tests with CCUNSmode. */
17410 case GTU:
17411 case GEU:
17412 case LTU:
17413 case LEU:
17414 cc_mode = CCUNSmode;
17415 break;
17417 default:
17418 break;
17421 /* Get the vector mask for the given relational operations. */
17422 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
17424 if (!mask)
17425 return 0;
17427 if (invert_move)
17429 tmp = op_true;
17430 op_true = op_false;
17431 op_false = tmp;
17434 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
17435 emit_insn (gen_rtx_SET (VOIDmode,
17436 dest,
17437 gen_rtx_IF_THEN_ELSE (dest_mode,
17438 cond2,
17439 op_true,
17440 op_false)));
17441 return 1;
17444 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
17445 operands of the last comparison is nonzero/true, FALSE_COND if it
17446 is zero/false. Return 0 if the hardware has no such operation. */
17449 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
17451 enum rtx_code code = GET_CODE (op);
17452 rtx op0 = XEXP (op, 0);
17453 rtx op1 = XEXP (op, 1);
17454 REAL_VALUE_TYPE c1;
17455 enum machine_mode compare_mode = GET_MODE (op0);
17456 enum machine_mode result_mode = GET_MODE (dest);
17457 rtx temp;
17458 bool is_against_zero;
17460 /* These modes should always match. */
17461 if (GET_MODE (op1) != compare_mode
17462 /* In the isel case however, we can use a compare immediate, so
17463 op1 may be a small constant. */
17464 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
17465 return 0;
17466 if (GET_MODE (true_cond) != result_mode)
17467 return 0;
17468 if (GET_MODE (false_cond) != result_mode)
17469 return 0;
17471 /* First, work out if the hardware can do this at all, or
17472 if it's too slow.... */
17473 if (!FLOAT_MODE_P (compare_mode))
17475 if (TARGET_ISEL)
17476 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
17477 return 0;
17479 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
17480 && SCALAR_FLOAT_MODE_P (compare_mode))
17481 return 0;
17483 is_against_zero = op1 == CONST0_RTX (compare_mode);
17485 /* A floating-point subtract might overflow, underflow, or produce
17486 an inexact result, thus changing the floating-point flags, so it
17487 can't be generated if we care about that. It's safe if one side
17488 of the construct is zero, since then no subtract will be
17489 generated. */
17490 if (SCALAR_FLOAT_MODE_P (compare_mode)
17491 && flag_trapping_math && ! is_against_zero)
17492 return 0;
17494 /* Eliminate half of the comparisons by switching operands, this
17495 makes the remaining code simpler. */
17496 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
17497 || code == LTGT || code == LT || code == UNLE)
17499 code = reverse_condition_maybe_unordered (code);
17500 temp = true_cond;
17501 true_cond = false_cond;
17502 false_cond = temp;
17505 /* UNEQ and LTGT take four instructions for a comparison with zero,
17506 it'll probably be faster to use a branch here too. */
17507 if (code == UNEQ && HONOR_NANS (compare_mode))
17508 return 0;
17510 if (GET_CODE (op1) == CONST_DOUBLE)
17511 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
17513 /* We're going to try to implement comparisons by performing
17514 a subtract, then comparing against zero. Unfortunately,
17515 Inf - Inf is NaN which is not zero, and so if we don't
17516 know that the operand is finite and the comparison
17517 would treat EQ different to UNORDERED, we can't do it. */
17518 if (HONOR_INFINITIES (compare_mode)
17519 && code != GT && code != UNGE
17520 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
17521 /* Constructs of the form (a OP b ? a : b) are safe. */
17522 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
17523 || (! rtx_equal_p (op0, true_cond)
17524 && ! rtx_equal_p (op1, true_cond))))
17525 return 0;
17527 /* At this point we know we can use fsel. */
17529 /* Reduce the comparison to a comparison against zero. */
17530 if (! is_against_zero)
17532 temp = gen_reg_rtx (compare_mode);
17533 emit_insn (gen_rtx_SET (VOIDmode, temp,
17534 gen_rtx_MINUS (compare_mode, op0, op1)));
17535 op0 = temp;
17536 op1 = CONST0_RTX (compare_mode);
17539 /* If we don't care about NaNs we can reduce some of the comparisons
17540 down to faster ones. */
17541 if (! HONOR_NANS (compare_mode))
17542 switch (code)
17544 case GT:
17545 code = LE;
17546 temp = true_cond;
17547 true_cond = false_cond;
17548 false_cond = temp;
17549 break;
17550 case UNGE:
17551 code = GE;
17552 break;
17553 case UNEQ:
17554 code = EQ;
17555 break;
17556 default:
17557 break;
17560 /* Now, reduce everything down to a GE. */
17561 switch (code)
17563 case GE:
17564 break;
17566 case LE:
17567 temp = gen_reg_rtx (compare_mode);
17568 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17569 op0 = temp;
17570 break;
17572 case ORDERED:
17573 temp = gen_reg_rtx (compare_mode);
17574 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
17575 op0 = temp;
17576 break;
17578 case EQ:
17579 temp = gen_reg_rtx (compare_mode);
17580 emit_insn (gen_rtx_SET (VOIDmode, temp,
17581 gen_rtx_NEG (compare_mode,
17582 gen_rtx_ABS (compare_mode, op0))));
17583 op0 = temp;
17584 break;
17586 case UNGE:
17587 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
17588 temp = gen_reg_rtx (result_mode);
17589 emit_insn (gen_rtx_SET (VOIDmode, temp,
17590 gen_rtx_IF_THEN_ELSE (result_mode,
17591 gen_rtx_GE (VOIDmode,
17592 op0, op1),
17593 true_cond, false_cond)));
17594 false_cond = true_cond;
17595 true_cond = temp;
17597 temp = gen_reg_rtx (compare_mode);
17598 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17599 op0 = temp;
17600 break;
17602 case GT:
17603 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
17604 temp = gen_reg_rtx (result_mode);
17605 emit_insn (gen_rtx_SET (VOIDmode, temp,
17606 gen_rtx_IF_THEN_ELSE (result_mode,
17607 gen_rtx_GE (VOIDmode,
17608 op0, op1),
17609 true_cond, false_cond)));
17610 true_cond = false_cond;
17611 false_cond = temp;
17613 temp = gen_reg_rtx (compare_mode);
17614 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17615 op0 = temp;
17616 break;
17618 default:
17619 gcc_unreachable ();
17622 emit_insn (gen_rtx_SET (VOIDmode, dest,
17623 gen_rtx_IF_THEN_ELSE (result_mode,
17624 gen_rtx_GE (VOIDmode,
17625 op0, op1),
17626 true_cond, false_cond)));
17627 return 1;
17630 /* Same as above, but for ints (isel). */
17632 static int
17633 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
17635 rtx condition_rtx, cr;
17636 enum machine_mode mode = GET_MODE (dest);
17637 enum rtx_code cond_code;
17638 rtx (*isel_func) (rtx, rtx, rtx, rtx, rtx);
17639 bool signedp;
17641 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
17642 return 0;
17644 /* We still have to do the compare, because isel doesn't do a
17645 compare, it just looks at the CRx bits set by a previous compare
17646 instruction. */
17647 condition_rtx = rs6000_generate_compare (op, mode);
17648 cond_code = GET_CODE (condition_rtx);
17649 cr = XEXP (condition_rtx, 0);
17650 signedp = GET_MODE (cr) == CCmode;
17652 isel_func = (mode == SImode
17653 ? (signedp ? gen_isel_signed_si : gen_isel_unsigned_si)
17654 : (signedp ? gen_isel_signed_di : gen_isel_unsigned_di));
17656 switch (cond_code)
17658 case LT: case GT: case LTU: case GTU: case EQ:
17659 /* isel handles these directly. */
17660 break;
17662 default:
17663 /* We need to swap the sense of the comparison. */
17665 rtx t = true_cond;
17666 true_cond = false_cond;
17667 false_cond = t;
17668 PUT_CODE (condition_rtx, reverse_condition (cond_code));
17670 break;
17673 false_cond = force_reg (mode, false_cond);
17674 if (true_cond != const0_rtx)
17675 true_cond = force_reg (mode, true_cond);
17677 emit_insn (isel_func (dest, condition_rtx, true_cond, false_cond, cr));
17679 return 1;
17682 const char *
17683 output_isel (rtx *operands)
17685 enum rtx_code code;
17687 code = GET_CODE (operands[1]);
17689 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
17691 gcc_assert (GET_CODE (operands[2]) == REG
17692 && GET_CODE (operands[3]) == REG);
17693 PUT_CODE (operands[1], reverse_condition (code));
17694 return "isel %0,%3,%2,%j1";
17697 return "isel %0,%2,%3,%j1";
17700 void
17701 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
17703 enum machine_mode mode = GET_MODE (op0);
17704 enum rtx_code c;
17705 rtx target;
17707 /* VSX/altivec have direct min/max insns. */
17708 if ((code == SMAX || code == SMIN)
17709 && (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
17710 || (mode == SFmode && VECTOR_UNIT_VSX_P (DFmode))))
17712 emit_insn (gen_rtx_SET (VOIDmode,
17713 dest,
17714 gen_rtx_fmt_ee (code, mode, op0, op1)));
17715 return;
17718 if (code == SMAX || code == SMIN)
17719 c = GE;
17720 else
17721 c = GEU;
17723 if (code == SMAX || code == UMAX)
17724 target = emit_conditional_move (dest, c, op0, op1, mode,
17725 op0, op1, mode, 0);
17726 else
17727 target = emit_conditional_move (dest, c, op0, op1, mode,
17728 op1, op0, mode, 0);
17729 gcc_assert (target);
17730 if (target != dest)
17731 emit_move_insn (dest, target);
17734 /* Emit instructions to perform a load-reserved/store-conditional operation.
17735 The operation performed is an atomic
17736 (set M (CODE:MODE M OP))
17737 If not NULL, BEFORE is atomically set to M before the operation, and
17738 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
17739 If SYNC_P then a memory barrier is emitted before the operation.
17740 Either OP or M may be wrapped in a NOT operation. */
17742 void
17743 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
17744 rtx m, rtx op, rtx before_param, rtx after_param,
17745 bool sync_p)
17747 enum machine_mode used_mode;
17748 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
17749 rtx used_m;
17750 rtvec vec;
17751 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17752 rtx shift = NULL_RTX;
17754 if (sync_p)
17755 emit_insn (gen_lwsync ());
17757 used_m = m;
17759 /* If this is smaller than SImode, we'll have to use SImode with
17760 adjustments. */
17761 if (mode == QImode || mode == HImode)
17763 rtx newop, oldop;
17765 if (MEM_ALIGN (used_m) >= 32)
17767 int ishift = 0;
17768 if (BYTES_BIG_ENDIAN)
17769 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
17771 shift = GEN_INT (ishift);
17772 used_m = change_address (used_m, SImode, 0);
17774 else
17776 rtx addrSI, aligned_addr;
17777 int shift_mask = mode == QImode ? 0x18 : 0x10;
17779 addrSI = gen_lowpart_common (SImode,
17780 force_reg (Pmode, XEXP (used_m, 0)));
17781 addrSI = force_reg (SImode, addrSI);
17782 shift = gen_reg_rtx (SImode);
17784 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17785 GEN_INT (shift_mask)));
17786 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17788 aligned_addr = expand_binop (Pmode, and_optab,
17789 XEXP (used_m, 0),
17790 GEN_INT (-4), NULL_RTX,
17791 1, OPTAB_LIB_WIDEN);
17792 used_m = change_address (used_m, SImode, aligned_addr);
17793 set_mem_align (used_m, 32);
17795 /* It's safe to keep the old alias set of USED_M, because
17796 the operation is atomic and only affects the original
17797 USED_M. */
17798 m = used_m;
17800 if (GET_CODE (op) == NOT)
17802 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
17803 oldop = gen_rtx_NOT (SImode, oldop);
17805 else
17806 oldop = lowpart_subreg (SImode, op, mode);
17808 switch (code)
17810 case IOR:
17811 case XOR:
17812 newop = expand_binop (SImode, and_optab,
17813 oldop, GEN_INT (imask), NULL_RTX,
17814 1, OPTAB_LIB_WIDEN);
17815 emit_insn (gen_ashlsi3 (newop, newop, shift));
17816 break;
17818 case NOT: /* NAND */
17819 newop = expand_binop (SImode, ior_optab,
17820 oldop, GEN_INT (~imask), NULL_RTX,
17821 1, OPTAB_LIB_WIDEN);
17822 emit_insn (gen_rotlsi3 (newop, newop, shift));
17823 break;
17825 case AND:
17826 newop = expand_binop (SImode, ior_optab,
17827 oldop, GEN_INT (~imask), NULL_RTX,
17828 1, OPTAB_LIB_WIDEN);
17829 emit_insn (gen_rotlsi3 (newop, newop, shift));
17830 break;
17832 case PLUS:
17833 case MINUS:
17835 rtx mask;
17837 newop = expand_binop (SImode, and_optab,
17838 oldop, GEN_INT (imask), NULL_RTX,
17839 1, OPTAB_LIB_WIDEN);
17840 emit_insn (gen_ashlsi3 (newop, newop, shift));
17842 mask = gen_reg_rtx (SImode);
17843 emit_move_insn (mask, GEN_INT (imask));
17844 emit_insn (gen_ashlsi3 (mask, mask, shift));
17846 if (code == PLUS)
17847 newop = gen_rtx_PLUS (SImode, m, newop);
17848 else
17849 newop = gen_rtx_MINUS (SImode, m, newop);
17850 newop = gen_rtx_AND (SImode, newop, mask);
17851 newop = gen_rtx_IOR (SImode, newop,
17852 gen_rtx_AND (SImode,
17853 gen_rtx_NOT (SImode, mask),
17854 m));
17855 break;
17858 default:
17859 gcc_unreachable ();
17862 op = newop;
17863 used_mode = SImode;
17864 before = gen_reg_rtx (used_mode);
17865 after = gen_reg_rtx (used_mode);
17867 else
17869 used_mode = mode;
17870 before = before_param;
17871 after = after_param;
17873 if (before == NULL_RTX)
17874 before = gen_reg_rtx (used_mode);
17875 if (after == NULL_RTX)
17876 after = gen_reg_rtx (used_mode);
17879 if ((code == PLUS || code == MINUS)
17880 && used_mode != mode)
17881 the_op = op; /* Computed above. */
17882 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
17883 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
17884 else if (code == NOT)
17885 the_op = gen_rtx_fmt_ee (IOR, used_mode,
17886 gen_rtx_NOT (used_mode, m),
17887 gen_rtx_NOT (used_mode, op));
17888 else
17889 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
17891 set_after = gen_rtx_SET (VOIDmode, after, the_op);
17892 set_before = gen_rtx_SET (VOIDmode, before, used_m);
17893 set_atomic = gen_rtx_SET (VOIDmode, used_m,
17894 gen_rtx_UNSPEC (used_mode,
17895 gen_rtvec (1, the_op),
17896 UNSPEC_SYNC_OP));
17897 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
17899 if ((code == PLUS || code == MINUS) && used_mode != mode)
17900 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
17901 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
17902 else
17903 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
17904 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
17906 /* Shift and mask the return values properly. */
17907 if (used_mode != mode && before_param)
17909 emit_insn (gen_lshrsi3 (before, before, shift));
17910 convert_move (before_param, before, 1);
17913 if (used_mode != mode && after_param)
17915 emit_insn (gen_lshrsi3 (after, after, shift));
17916 convert_move (after_param, after, 1);
17919 /* The previous sequence will end with a branch that's dependent on
17920 the conditional store, so placing an isync will ensure that no
17921 other instructions (especially, no load or store instructions)
17922 can start before the atomic operation completes. */
17923 if (sync_p)
17924 emit_insn (gen_isync ());
17927 /* A subroutine of the atomic operation splitters. Jump to LABEL if
17928 COND is true. Mark the jump as unlikely to be taken. */
17930 static void
17931 emit_unlikely_jump (rtx cond, rtx label)
17933 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
17934 rtx x;
17936 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
17937 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
17938 add_reg_note (x, REG_BR_PROB, very_unlikely);
17941 /* A subroutine of the atomic operation splitters. Emit a load-locked
17942 instruction in MODE. */
17944 static void
17945 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
17947 rtx (*fn) (rtx, rtx) = NULL;
17948 if (mode == SImode)
17949 fn = gen_load_locked_si;
17950 else if (mode == DImode)
17951 fn = gen_load_locked_di;
17952 emit_insn (fn (reg, mem));
17955 /* A subroutine of the atomic operation splitters. Emit a store-conditional
17956 instruction in MODE. */
17958 static void
17959 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
17961 rtx (*fn) (rtx, rtx, rtx) = NULL;
17962 if (mode == SImode)
17963 fn = gen_store_conditional_si;
17964 else if (mode == DImode)
17965 fn = gen_store_conditional_di;
17967 /* Emit sync before stwcx. to address PPC405 Erratum. */
17968 if (PPC405_ERRATUM77)
17969 emit_insn (gen_memory_barrier ());
17971 emit_insn (fn (res, mem, val));
17974 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
17975 to perform. MEM is the memory on which to operate. VAL is the second
17976 operand of the binary operator. BEFORE and AFTER are optional locations to
17977 return the value of MEM either before of after the operation. SCRATCH is
17978 a scratch register. */
17980 void
17981 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
17982 rtx before, rtx after, rtx scratch)
17984 enum machine_mode mode = GET_MODE (mem);
17985 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17987 emit_insn (gen_lwsync ());
17989 label = gen_label_rtx ();
17990 emit_label (label);
17991 label = gen_rtx_LABEL_REF (VOIDmode, label);
17993 if (before == NULL_RTX)
17994 before = scratch;
17995 emit_load_locked (mode, before, mem);
17997 if (code == NOT)
17998 x = gen_rtx_IOR (mode,
17999 gen_rtx_NOT (mode, before),
18000 gen_rtx_NOT (mode, val));
18001 else if (code == AND)
18002 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
18003 else
18004 x = gen_rtx_fmt_ee (code, mode, before, val);
18006 if (after != NULL_RTX)
18007 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
18008 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
18010 emit_store_conditional (mode, cond, mem, scratch);
18012 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18013 emit_unlikely_jump (x, label);
18015 emit_insn (gen_isync ());
18018 /* Expand an atomic compare and swap operation. MEM is the memory on which
18019 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
18020 value to be stored. SCRATCH is a scratch GPR. */
18022 void
18023 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
18024 rtx scratch)
18026 enum machine_mode mode = GET_MODE (mem);
18027 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
18029 emit_insn (gen_lwsync ());
18031 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
18032 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
18033 emit_label (XEXP (label1, 0));
18035 emit_load_locked (mode, retval, mem);
18037 x = gen_rtx_COMPARE (CCmode, retval, oldval);
18038 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
18040 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18041 emit_unlikely_jump (x, label2);
18043 emit_move_insn (scratch, newval);
18044 emit_store_conditional (mode, cond, mem, scratch);
18046 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18047 emit_unlikely_jump (x, label1);
18049 emit_insn (gen_isync ());
18050 emit_label (XEXP (label2, 0));
18053 /* Expand an atomic test and set operation. MEM is the memory on which
18054 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
18056 void
18057 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
18059 enum machine_mode mode = GET_MODE (mem);
18060 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
18062 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
18063 emit_label (XEXP (label, 0));
18065 emit_load_locked (mode, retval, mem);
18066 emit_move_insn (scratch, val);
18067 emit_store_conditional (mode, cond, mem, scratch);
18069 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18070 emit_unlikely_jump (x, label);
18072 emit_insn (gen_isync ());
18075 void
18076 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
18078 enum machine_mode mode = GET_MODE (mem);
18079 rtx addrSI, align, wdst, shift, mask;
18080 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
18081 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
18083 /* Shift amount for subword relative to aligned word. */
18084 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
18085 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
18086 shift = gen_reg_rtx (SImode);
18087 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
18088 GEN_INT (shift_mask)));
18089 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
18091 /* Shift and mask old value into position within word. */
18092 oldval = convert_modes (SImode, mode, oldval, 1);
18093 oldval = expand_binop (SImode, and_optab,
18094 oldval, GEN_INT (imask), NULL_RTX,
18095 1, OPTAB_LIB_WIDEN);
18096 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
18098 /* Shift and mask new value into position within word. */
18099 newval = convert_modes (SImode, mode, newval, 1);
18100 newval = expand_binop (SImode, and_optab,
18101 newval, GEN_INT (imask), NULL_RTX,
18102 1, OPTAB_LIB_WIDEN);
18103 emit_insn (gen_ashlsi3 (newval, newval, shift));
18105 /* Mask for insertion. */
18106 mask = gen_reg_rtx (SImode);
18107 emit_move_insn (mask, GEN_INT (imask));
18108 emit_insn (gen_ashlsi3 (mask, mask, shift));
18110 /* Address of aligned word containing subword. */
18111 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
18112 NULL_RTX, 1, OPTAB_LIB_WIDEN);
18113 mem = change_address (mem, SImode, align);
18114 set_mem_align (mem, 32);
18115 MEM_VOLATILE_P (mem) = 1;
18117 wdst = gen_reg_rtx (SImode);
18118 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
18119 oldval, newval, mem));
18121 /* Shift the result back. */
18122 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
18124 emit_move_insn (dst, gen_lowpart (mode, wdst));
18127 void
18128 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
18129 rtx oldval, rtx newval, rtx mem,
18130 rtx scratch)
18132 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
18134 emit_insn (gen_lwsync ());
18135 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
18136 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
18137 emit_label (XEXP (label1, 0));
18139 emit_load_locked (SImode, scratch, mem);
18141 /* Mask subword within loaded value for comparison with oldval.
18142 Use UNSPEC_AND to avoid clobber.*/
18143 emit_insn (gen_rtx_SET (SImode, dest,
18144 gen_rtx_UNSPEC (SImode,
18145 gen_rtvec (2, scratch, mask),
18146 UNSPEC_AND)));
18148 x = gen_rtx_COMPARE (CCmode, dest, oldval);
18149 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
18151 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18152 emit_unlikely_jump (x, label2);
18154 /* Clear subword within loaded value for insertion of new value. */
18155 emit_insn (gen_rtx_SET (SImode, scratch,
18156 gen_rtx_AND (SImode,
18157 gen_rtx_NOT (SImode, mask), scratch)));
18158 emit_insn (gen_iorsi3 (scratch, scratch, newval));
18159 emit_store_conditional (SImode, cond, mem, scratch);
18161 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18162 emit_unlikely_jump (x, label1);
18164 emit_insn (gen_isync ());
18165 emit_label (XEXP (label2, 0));
18169 /* Emit instructions to move SRC to DST. Called by splitters for
18170 multi-register moves. It will emit at most one instruction for
18171 each register that is accessed; that is, it won't emit li/lis pairs
18172 (or equivalent for 64-bit code). One of SRC or DST must be a hard
18173 register. */
18175 void
18176 rs6000_split_multireg_move (rtx dst, rtx src)
18178 /* The register number of the first register being moved. */
18179 int reg;
18180 /* The mode that is to be moved. */
18181 enum machine_mode mode;
18182 /* The mode that the move is being done in, and its size. */
18183 enum machine_mode reg_mode;
18184 int reg_mode_size;
18185 /* The number of registers that will be moved. */
18186 int nregs;
18188 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
18189 mode = GET_MODE (dst);
18190 nregs = hard_regno_nregs[reg][mode];
18191 if (FP_REGNO_P (reg))
18192 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
18193 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
18194 else if (ALTIVEC_REGNO_P (reg))
18195 reg_mode = V16QImode;
18196 else if (TARGET_E500_DOUBLE && mode == TFmode)
18197 reg_mode = DFmode;
18198 else
18199 reg_mode = word_mode;
18200 reg_mode_size = GET_MODE_SIZE (reg_mode);
18202 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
18204 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
18206 /* Move register range backwards, if we might have destructive
18207 overlap. */
18208 int i;
18209 for (i = nregs - 1; i >= 0; i--)
18210 emit_insn (gen_rtx_SET (VOIDmode,
18211 simplify_gen_subreg (reg_mode, dst, mode,
18212 i * reg_mode_size),
18213 simplify_gen_subreg (reg_mode, src, mode,
18214 i * reg_mode_size)));
18216 else
18218 int i;
18219 int j = -1;
18220 bool used_update = false;
18221 rtx restore_basereg = NULL_RTX;
18223 if (MEM_P (src) && INT_REGNO_P (reg))
18225 rtx breg;
18227 if (GET_CODE (XEXP (src, 0)) == PRE_INC
18228 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
18230 rtx delta_rtx;
18231 breg = XEXP (XEXP (src, 0), 0);
18232 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
18233 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
18234 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
18235 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
18236 src = replace_equiv_address (src, breg);
18238 else if (! rs6000_offsettable_memref_p (src))
18240 if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)
18242 rtx basereg = XEXP (XEXP (src, 0), 0);
18243 if (TARGET_UPDATE)
18245 rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0);
18246 emit_insn (gen_rtx_SET (VOIDmode, ndst,
18247 gen_rtx_MEM (reg_mode, XEXP (src, 0))));
18248 used_update = true;
18250 else
18251 emit_insn (gen_rtx_SET (VOIDmode, basereg,
18252 XEXP (XEXP (src, 0), 1)));
18253 src = replace_equiv_address (src, basereg);
18255 else
18257 rtx basereg = gen_rtx_REG (Pmode, reg);
18258 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
18259 src = replace_equiv_address (src, basereg);
18263 breg = XEXP (src, 0);
18264 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
18265 breg = XEXP (breg, 0);
18267 /* If the base register we are using to address memory is
18268 also a destination reg, then change that register last. */
18269 if (REG_P (breg)
18270 && REGNO (breg) >= REGNO (dst)
18271 && REGNO (breg) < REGNO (dst) + nregs)
18272 j = REGNO (breg) - REGNO (dst);
18274 else if (MEM_P (dst) && INT_REGNO_P (reg))
18276 rtx breg;
18278 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
18279 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
18281 rtx delta_rtx;
18282 breg = XEXP (XEXP (dst, 0), 0);
18283 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
18284 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
18285 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
18287 /* We have to update the breg before doing the store.
18288 Use store with update, if available. */
18290 if (TARGET_UPDATE)
18292 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
18293 emit_insn (TARGET_32BIT
18294 ? (TARGET_POWERPC64
18295 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
18296 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
18297 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
18298 used_update = true;
18300 else
18301 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
18302 dst = replace_equiv_address (dst, breg);
18304 else if (!rs6000_offsettable_memref_p (dst)
18305 && GET_CODE (XEXP (dst, 0)) != LO_SUM)
18307 if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY)
18309 rtx basereg = XEXP (XEXP (dst, 0), 0);
18310 if (TARGET_UPDATE)
18312 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
18313 emit_insn (gen_rtx_SET (VOIDmode,
18314 gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc));
18315 used_update = true;
18317 else
18318 emit_insn (gen_rtx_SET (VOIDmode, basereg,
18319 XEXP (XEXP (dst, 0), 1)));
18320 dst = replace_equiv_address (dst, basereg);
18322 else
18324 rtx basereg = XEXP (XEXP (dst, 0), 0);
18325 rtx offsetreg = XEXP (XEXP (dst, 0), 1);
18326 gcc_assert (GET_CODE (XEXP (dst, 0)) == PLUS
18327 && REG_P (basereg)
18328 && REG_P (offsetreg)
18329 && REGNO (basereg) != REGNO (offsetreg));
18330 if (REGNO (basereg) == 0)
18332 rtx tmp = offsetreg;
18333 offsetreg = basereg;
18334 basereg = tmp;
18336 emit_insn (gen_add3_insn (basereg, basereg, offsetreg));
18337 restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg);
18338 dst = replace_equiv_address (dst, basereg);
18341 else if (GET_CODE (XEXP (dst, 0)) != LO_SUM)
18342 gcc_assert (rs6000_offsettable_memref_p (dst));
18345 for (i = 0; i < nregs; i++)
18347 /* Calculate index to next subword. */
18348 ++j;
18349 if (j == nregs)
18350 j = 0;
18352 /* If compiler already emitted move of first word by
18353 store with update, no need to do anything. */
18354 if (j == 0 && used_update)
18355 continue;
18357 emit_insn (gen_rtx_SET (VOIDmode,
18358 simplify_gen_subreg (reg_mode, dst, mode,
18359 j * reg_mode_size),
18360 simplify_gen_subreg (reg_mode, src, mode,
18361 j * reg_mode_size)));
18363 if (restore_basereg != NULL_RTX)
18364 emit_insn (restore_basereg);
18369 /* This page contains routines that are used to determine what the
18370 function prologue and epilogue code will do and write them out. */
18372 /* Return the first fixed-point register that is required to be
18373 saved. 32 if none. */
18376 first_reg_to_save (void)
18378 int first_reg;
18380 /* Find lowest numbered live register. */
18381 for (first_reg = 13; first_reg <= 31; first_reg++)
18382 if (df_regs_ever_live_p (first_reg)
18383 && (! call_used_regs[first_reg]
18384 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18385 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
18386 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
18387 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
18388 break;
18390 #if TARGET_MACHO
18391 if (flag_pic
18392 && crtl->uses_pic_offset_table
18393 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
18394 return RS6000_PIC_OFFSET_TABLE_REGNUM;
18395 #endif
18397 return first_reg;
18400 /* Similar, for FP regs. */
18403 first_fp_reg_to_save (void)
18405 int first_reg;
18407 /* Find lowest numbered live register. */
18408 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
18409 if (df_regs_ever_live_p (first_reg))
18410 break;
18412 return first_reg;
18415 /* Similar, for AltiVec regs. */
18417 static int
18418 first_altivec_reg_to_save (void)
18420 int i;
18422 /* Stack frame remains as is unless we are in AltiVec ABI. */
18423 if (! TARGET_ALTIVEC_ABI)
18424 return LAST_ALTIVEC_REGNO + 1;
18426 /* On Darwin, the unwind routines are compiled without
18427 TARGET_ALTIVEC, and use save_world to save/restore the
18428 altivec registers when necessary. */
18429 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
18430 && ! TARGET_ALTIVEC)
18431 return FIRST_ALTIVEC_REGNO + 20;
18433 /* Find lowest numbered live register. */
18434 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
18435 if (df_regs_ever_live_p (i))
18436 break;
18438 return i;
18441 /* Return a 32-bit mask of the AltiVec registers we need to set in
18442 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
18443 the 32-bit word is 0. */
18445 static unsigned int
18446 compute_vrsave_mask (void)
18448 unsigned int i, mask = 0;
18450 /* On Darwin, the unwind routines are compiled without
18451 TARGET_ALTIVEC, and use save_world to save/restore the
18452 call-saved altivec registers when necessary. */
18453 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
18454 && ! TARGET_ALTIVEC)
18455 mask |= 0xFFF;
18457 /* First, find out if we use _any_ altivec registers. */
18458 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
18459 if (df_regs_ever_live_p (i))
18460 mask |= ALTIVEC_REG_BIT (i);
18462 if (mask == 0)
18463 return mask;
18465 /* Next, remove the argument registers from the set. These must
18466 be in the VRSAVE mask set by the caller, so we don't need to add
18467 them in again. More importantly, the mask we compute here is
18468 used to generate CLOBBERs in the set_vrsave insn, and we do not
18469 wish the argument registers to die. */
18470 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
18471 mask &= ~ALTIVEC_REG_BIT (i);
18473 /* Similarly, remove the return value from the set. */
18475 bool yes = false;
18476 diddle_return_value (is_altivec_return_reg, &yes);
18477 if (yes)
18478 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
18481 return mask;
18484 /* For a very restricted set of circumstances, we can cut down the
18485 size of prologues/epilogues by calling our own save/restore-the-world
18486 routines. */
18488 static void
18489 compute_save_world_info (rs6000_stack_t *info_ptr)
18491 info_ptr->world_save_p = 1;
18492 info_ptr->world_save_p
18493 = (WORLD_SAVE_P (info_ptr)
18494 && DEFAULT_ABI == ABI_DARWIN
18495 && ! (cfun->calls_setjmp && flag_exceptions)
18496 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
18497 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
18498 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
18499 && info_ptr->cr_save_p);
18501 /* This will not work in conjunction with sibcalls. Make sure there
18502 are none. (This check is expensive, but seldom executed.) */
18503 if (WORLD_SAVE_P (info_ptr))
18505 rtx insn;
18506 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
18507 if ( GET_CODE (insn) == CALL_INSN
18508 && SIBLING_CALL_P (insn))
18510 info_ptr->world_save_p = 0;
18511 break;
18515 if (WORLD_SAVE_P (info_ptr))
18517 /* Even if we're not touching VRsave, make sure there's room on the
18518 stack for it, if it looks like we're calling SAVE_WORLD, which
18519 will attempt to save it. */
18520 info_ptr->vrsave_size = 4;
18522 /* If we are going to save the world, we need to save the link register too. */
18523 info_ptr->lr_save_p = 1;
18525 /* "Save" the VRsave register too if we're saving the world. */
18526 if (info_ptr->vrsave_mask == 0)
18527 info_ptr->vrsave_mask = compute_vrsave_mask ();
18529 /* Because the Darwin register save/restore routines only handle
18530 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
18531 check. */
18532 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
18533 && (info_ptr->first_altivec_reg_save
18534 >= FIRST_SAVED_ALTIVEC_REGNO));
18536 return;
18540 static void
18541 is_altivec_return_reg (rtx reg, void *xyes)
18543 bool *yes = (bool *) xyes;
18544 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
18545 *yes = true;
18549 /* Determine the strategy for savings/restoring registers. */
18551 enum {
18552 SAVRES_MULTIPLE = 0x1,
18553 SAVE_INLINE_FPRS = 0x2,
18554 SAVE_INLINE_GPRS = 0x4,
18555 REST_INLINE_FPRS = 0x8,
18556 REST_INLINE_GPRS = 0x10,
18557 SAVE_NOINLINE_GPRS_SAVES_LR = 0x20,
18558 SAVE_NOINLINE_FPRS_SAVES_LR = 0x40,
18559 REST_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x80
18562 static int
18563 rs6000_savres_strategy (rs6000_stack_t *info,
18564 bool using_static_chain_p)
18566 int strategy = 0;
18568 if (TARGET_MULTIPLE
18569 && !TARGET_POWERPC64
18570 && !(TARGET_SPE_ABI && info->spe_64bit_regs_used)
18571 && info->first_gp_reg_save < 31
18572 && no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true))
18573 strategy |= SAVRES_MULTIPLE;
18575 if (crtl->calls_eh_return
18576 || cfun->machine->ra_need_lr
18577 || info->total_size > 32767)
18578 strategy |= (SAVE_INLINE_FPRS | REST_INLINE_FPRS
18579 | SAVE_INLINE_GPRS | REST_INLINE_GPRS);
18581 if (info->first_fp_reg_save == 64
18582 || FP_SAVE_INLINE (info->first_fp_reg_save)
18583 /* The out-of-line FP routines use double-precision stores;
18584 we can't use those routines if we don't have such stores. */
18585 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
18586 || !no_global_regs_above (info->first_fp_reg_save, /*gpr=*/false))
18587 strategy |= SAVE_INLINE_FPRS | REST_INLINE_FPRS;
18589 if (info->first_gp_reg_save == 32
18590 || GP_SAVE_INLINE (info->first_gp_reg_save)
18591 || !((strategy & SAVRES_MULTIPLE)
18592 || no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true)))
18593 strategy |= SAVE_INLINE_GPRS | REST_INLINE_GPRS;
18595 /* Don't bother to try to save things out-of-line if r11 is occupied
18596 by the static chain. It would require too much fiddling and the
18597 static chain is rarely used anyway. */
18598 if (using_static_chain_p)
18599 strategy |= SAVE_INLINE_FPRS | SAVE_INLINE_GPRS;
18601 /* If we are going to use store multiple, then don't even bother
18602 with the out-of-line routines, since the store-multiple
18603 instruction will always be smaller. */
18604 if ((strategy & SAVRES_MULTIPLE))
18605 strategy |= SAVE_INLINE_GPRS;
18607 /* The situation is more complicated with load multiple. We'd
18608 prefer to use the out-of-line routines for restores, since the
18609 "exit" out-of-line routines can handle the restore of LR and the
18610 frame teardown. However if doesn't make sense to use the
18611 out-of-line routine if that is the only reason we'd need to save
18612 LR, and we can't use the "exit" out-of-line gpr restore if we
18613 have saved some fprs; In those cases it is advantageous to use
18614 load multiple when available. */
18615 if ((strategy & SAVRES_MULTIPLE)
18616 && (!info->lr_save_p
18617 || info->first_fp_reg_save != 64))
18618 strategy |= REST_INLINE_GPRS;
18620 /* We can only use load multiple or the out-of-line routines to
18621 restore if we've used store multiple or out-of-line routines
18622 in the prologue, i.e. if we've saved all the registers from
18623 first_gp_reg_save. Otherwise, we risk loading garbage. */
18624 if ((strategy & (SAVE_INLINE_GPRS | SAVRES_MULTIPLE)) == SAVE_INLINE_GPRS)
18625 strategy |= REST_INLINE_GPRS;
18627 /* Saving CR interferes with the exit routines used on the SPE, so
18628 just punt here. */
18629 if (TARGET_SPE_ABI
18630 && info->spe_64bit_regs_used
18631 && info->cr_save_p)
18632 strategy |= REST_INLINE_GPRS;
18634 #ifdef POWERPC_LINUX
18635 if (TARGET_64BIT)
18637 if (!(strategy & SAVE_INLINE_FPRS))
18638 strategy |= SAVE_NOINLINE_FPRS_SAVES_LR;
18639 else if (!(strategy & SAVE_INLINE_GPRS)
18640 && info->first_fp_reg_save == 64)
18641 strategy |= SAVE_NOINLINE_GPRS_SAVES_LR;
18643 #else
18644 if (TARGET_AIX && !(strategy & REST_INLINE_FPRS))
18645 strategy |= REST_NOINLINE_FPRS_DOESNT_RESTORE_LR;
18646 #endif
18647 return strategy;
18650 /* Calculate the stack information for the current function. This is
18651 complicated by having two separate calling sequences, the AIX calling
18652 sequence and the V.4 calling sequence.
18654 AIX (and Darwin/Mac OS X) stack frames look like:
18655 32-bit 64-bit
18656 SP----> +---------------------------------------+
18657 | back chain to caller | 0 0
18658 +---------------------------------------+
18659 | saved CR | 4 8 (8-11)
18660 +---------------------------------------+
18661 | saved LR | 8 16
18662 +---------------------------------------+
18663 | reserved for compilers | 12 24
18664 +---------------------------------------+
18665 | reserved for binders | 16 32
18666 +---------------------------------------+
18667 | saved TOC pointer | 20 40
18668 +---------------------------------------+
18669 | Parameter save area (P) | 24 48
18670 +---------------------------------------+
18671 | Alloca space (A) | 24+P etc.
18672 +---------------------------------------+
18673 | Local variable space (L) | 24+P+A
18674 +---------------------------------------+
18675 | Float/int conversion temporary (X) | 24+P+A+L
18676 +---------------------------------------+
18677 | Save area for AltiVec registers (W) | 24+P+A+L+X
18678 +---------------------------------------+
18679 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
18680 +---------------------------------------+
18681 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
18682 +---------------------------------------+
18683 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
18684 +---------------------------------------+
18685 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
18686 +---------------------------------------+
18687 old SP->| back chain to caller's caller |
18688 +---------------------------------------+
18690 The required alignment for AIX configurations is two words (i.e., 8
18691 or 16 bytes).
18694 V.4 stack frames look like:
18696 SP----> +---------------------------------------+
18697 | back chain to caller | 0
18698 +---------------------------------------+
18699 | caller's saved LR | 4
18700 +---------------------------------------+
18701 | Parameter save area (P) | 8
18702 +---------------------------------------+
18703 | Alloca space (A) | 8+P
18704 +---------------------------------------+
18705 | Varargs save area (V) | 8+P+A
18706 +---------------------------------------+
18707 | Local variable space (L) | 8+P+A+V
18708 +---------------------------------------+
18709 | Float/int conversion temporary (X) | 8+P+A+V+L
18710 +---------------------------------------+
18711 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
18712 +---------------------------------------+
18713 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
18714 +---------------------------------------+
18715 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
18716 +---------------------------------------+
18717 | SPE: area for 64-bit GP registers |
18718 +---------------------------------------+
18719 | SPE alignment padding |
18720 +---------------------------------------+
18721 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
18722 +---------------------------------------+
18723 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
18724 +---------------------------------------+
18725 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
18726 +---------------------------------------+
18727 old SP->| back chain to caller's caller |
18728 +---------------------------------------+
18730 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
18731 given. (But note below and in sysv4.h that we require only 8 and
18732 may round up the size of our stack frame anyways. The historical
18733 reason is early versions of powerpc-linux which didn't properly
18734 align the stack at program startup. A happy side-effect is that
18735 -mno-eabi libraries can be used with -meabi programs.)
18737 The EABI configuration defaults to the V.4 layout. However,
18738 the stack alignment requirements may differ. If -mno-eabi is not
18739 given, the required stack alignment is 8 bytes; if -mno-eabi is
18740 given, the required alignment is 16 bytes. (But see V.4 comment
18741 above.) */
18743 #ifndef ABI_STACK_BOUNDARY
18744 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
18745 #endif
18747 static rs6000_stack_t *
18748 rs6000_stack_info (void)
18750 #ifdef ENABLE_CHECKING
18751 static rs6000_stack_t info_save;
18752 #endif
18753 rs6000_stack_t *info_ptr = &stack_info;
18754 int reg_size = TARGET_32BIT ? 4 : 8;
18755 int ehrd_size;
18756 int save_align;
18757 int first_gp;
18758 HOST_WIDE_INT non_fixed_size;
18759 bool using_static_chain_p;
18761 #ifdef ENABLE_CHECKING
18762 memcpy (&info_save, &stack_info, sizeof stack_info);
18763 #else
18764 if (reload_completed && info_ptr->reload_completed)
18765 return info_ptr;
18766 #endif
18768 memset (&stack_info, 0, sizeof (stack_info));
18769 info_ptr->reload_completed = reload_completed;
18771 if (TARGET_SPE)
18773 /* Cache value so we don't rescan instruction chain over and over. */
18774 if (cfun->machine->insn_chain_scanned_p == 0)
18775 cfun->machine->insn_chain_scanned_p
18776 = spe_func_has_64bit_regs_p () + 1;
18777 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
18780 /* Select which calling sequence. */
18781 info_ptr->abi = DEFAULT_ABI;
18783 /* Calculate which registers need to be saved & save area size. */
18784 info_ptr->first_gp_reg_save = first_reg_to_save ();
18785 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
18786 even if it currently looks like we won't. Reload may need it to
18787 get at a constant; if so, it will have already created a constant
18788 pool entry for it. */
18789 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
18790 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
18791 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
18792 && crtl->uses_const_pool
18793 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
18794 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
18795 else
18796 first_gp = info_ptr->first_gp_reg_save;
18798 info_ptr->gp_size = reg_size * (32 - first_gp);
18800 /* For the SPE, we have an additional upper 32-bits on each GPR.
18801 Ideally we should save the entire 64-bits only when the upper
18802 half is used in SIMD instructions. Since we only record
18803 registers live (not the size they are used in), this proves
18804 difficult because we'd have to traverse the instruction chain at
18805 the right time, taking reload into account. This is a real pain,
18806 so we opt to save the GPRs in 64-bits always if but one register
18807 gets used in 64-bits. Otherwise, all the registers in the frame
18808 get saved in 32-bits.
18810 So... since when we save all GPRs (except the SP) in 64-bits, the
18811 traditional GP save area will be empty. */
18812 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18813 info_ptr->gp_size = 0;
18815 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
18816 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
18818 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
18819 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
18820 - info_ptr->first_altivec_reg_save);
18822 /* Does this function call anything? */
18823 info_ptr->calls_p = (! current_function_is_leaf
18824 || cfun->machine->ra_needs_full_frame);
18826 /* Determine if we need to save the condition code registers. */
18827 if (df_regs_ever_live_p (CR2_REGNO)
18828 || df_regs_ever_live_p (CR3_REGNO)
18829 || df_regs_ever_live_p (CR4_REGNO))
18831 info_ptr->cr_save_p = 1;
18832 if (DEFAULT_ABI == ABI_V4)
18833 info_ptr->cr_size = reg_size;
18836 /* If the current function calls __builtin_eh_return, then we need
18837 to allocate stack space for registers that will hold data for
18838 the exception handler. */
18839 if (crtl->calls_eh_return)
18841 unsigned int i;
18842 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
18843 continue;
18845 /* SPE saves EH registers in 64-bits. */
18846 ehrd_size = i * (TARGET_SPE_ABI
18847 && info_ptr->spe_64bit_regs_used != 0
18848 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
18850 else
18851 ehrd_size = 0;
18853 /* Determine various sizes. */
18854 info_ptr->reg_size = reg_size;
18855 info_ptr->fixed_size = RS6000_SAVE_AREA;
18856 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
18857 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
18858 TARGET_ALTIVEC ? 16 : 8);
18859 if (FRAME_GROWS_DOWNWARD)
18860 info_ptr->vars_size
18861 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
18862 + info_ptr->parm_size,
18863 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
18864 - (info_ptr->fixed_size + info_ptr->vars_size
18865 + info_ptr->parm_size);
18867 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18868 info_ptr->spe_gp_size = 8 * (32 - first_gp);
18869 else
18870 info_ptr->spe_gp_size = 0;
18872 if (TARGET_ALTIVEC_ABI)
18873 info_ptr->vrsave_mask = compute_vrsave_mask ();
18874 else
18875 info_ptr->vrsave_mask = 0;
18877 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
18878 info_ptr->vrsave_size = 4;
18879 else
18880 info_ptr->vrsave_size = 0;
18882 compute_save_world_info (info_ptr);
18884 /* Calculate the offsets. */
18885 switch (DEFAULT_ABI)
18887 case ABI_NONE:
18888 default:
18889 gcc_unreachable ();
18891 case ABI_AIX:
18892 case ABI_DARWIN:
18893 info_ptr->fp_save_offset = - info_ptr->fp_size;
18894 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18896 if (TARGET_ALTIVEC_ABI)
18898 info_ptr->vrsave_save_offset
18899 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
18901 /* Align stack so vector save area is on a quadword boundary.
18902 The padding goes above the vectors. */
18903 if (info_ptr->altivec_size != 0)
18904 info_ptr->altivec_padding_size
18905 = info_ptr->vrsave_save_offset & 0xF;
18906 else
18907 info_ptr->altivec_padding_size = 0;
18909 info_ptr->altivec_save_offset
18910 = info_ptr->vrsave_save_offset
18911 - info_ptr->altivec_padding_size
18912 - info_ptr->altivec_size;
18913 gcc_assert (info_ptr->altivec_size == 0
18914 || info_ptr->altivec_save_offset % 16 == 0);
18916 /* Adjust for AltiVec case. */
18917 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
18919 else
18920 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
18921 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
18922 info_ptr->lr_save_offset = 2*reg_size;
18923 break;
18925 case ABI_V4:
18926 info_ptr->fp_save_offset = - info_ptr->fp_size;
18927 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18928 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
18930 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18932 /* Align stack so SPE GPR save area is aligned on a
18933 double-word boundary. */
18934 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
18935 info_ptr->spe_padding_size
18936 = 8 - (-info_ptr->cr_save_offset % 8);
18937 else
18938 info_ptr->spe_padding_size = 0;
18940 info_ptr->spe_gp_save_offset
18941 = info_ptr->cr_save_offset
18942 - info_ptr->spe_padding_size
18943 - info_ptr->spe_gp_size;
18945 /* Adjust for SPE case. */
18946 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
18948 else if (TARGET_ALTIVEC_ABI)
18950 info_ptr->vrsave_save_offset
18951 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
18953 /* Align stack so vector save area is on a quadword boundary. */
18954 if (info_ptr->altivec_size != 0)
18955 info_ptr->altivec_padding_size
18956 = 16 - (-info_ptr->vrsave_save_offset % 16);
18957 else
18958 info_ptr->altivec_padding_size = 0;
18960 info_ptr->altivec_save_offset
18961 = info_ptr->vrsave_save_offset
18962 - info_ptr->altivec_padding_size
18963 - info_ptr->altivec_size;
18965 /* Adjust for AltiVec case. */
18966 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
18968 else
18969 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
18970 info_ptr->ehrd_offset -= ehrd_size;
18971 info_ptr->lr_save_offset = reg_size;
18972 break;
18975 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
18976 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
18977 + info_ptr->gp_size
18978 + info_ptr->altivec_size
18979 + info_ptr->altivec_padding_size
18980 + info_ptr->spe_gp_size
18981 + info_ptr->spe_padding_size
18982 + ehrd_size
18983 + info_ptr->cr_size
18984 + info_ptr->vrsave_size,
18985 save_align);
18987 non_fixed_size = (info_ptr->vars_size
18988 + info_ptr->parm_size
18989 + info_ptr->save_size);
18991 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
18992 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
18994 /* Determine if we need to save the link register. */
18995 if (info_ptr->calls_p
18996 || (DEFAULT_ABI == ABI_AIX
18997 && crtl->profile
18998 && !TARGET_PROFILE_KERNEL)
18999 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
19000 #ifdef TARGET_RELOCATABLE
19001 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
19002 #endif
19003 || rs6000_ra_ever_killed ())
19004 info_ptr->lr_save_p = 1;
19006 using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
19007 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
19008 && call_used_regs[STATIC_CHAIN_REGNUM]);
19009 info_ptr->savres_strategy = rs6000_savres_strategy (info_ptr,
19010 using_static_chain_p);
19012 if (!(info_ptr->savres_strategy & SAVE_INLINE_GPRS)
19013 || !(info_ptr->savres_strategy & SAVE_INLINE_FPRS)
19014 || !(info_ptr->savres_strategy & REST_INLINE_GPRS)
19015 || !(info_ptr->savres_strategy & REST_INLINE_FPRS))
19016 info_ptr->lr_save_p = 1;
19018 if (info_ptr->lr_save_p)
19019 df_set_regs_ever_live (LR_REGNO, true);
19021 /* Determine if we need to allocate any stack frame:
19023 For AIX we need to push the stack if a frame pointer is needed
19024 (because the stack might be dynamically adjusted), if we are
19025 debugging, if we make calls, or if the sum of fp_save, gp_save,
19026 and local variables are more than the space needed to save all
19027 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
19028 + 18*8 = 288 (GPR13 reserved).
19030 For V.4 we don't have the stack cushion that AIX uses, but assume
19031 that the debugger can handle stackless frames. */
19033 if (info_ptr->calls_p)
19034 info_ptr->push_p = 1;
19036 else if (DEFAULT_ABI == ABI_V4)
19037 info_ptr->push_p = non_fixed_size != 0;
19039 else if (frame_pointer_needed)
19040 info_ptr->push_p = 1;
19042 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
19043 info_ptr->push_p = 1;
19045 else
19046 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
19048 /* Zero offsets if we're not saving those registers. */
19049 if (info_ptr->fp_size == 0)
19050 info_ptr->fp_save_offset = 0;
19052 if (info_ptr->gp_size == 0)
19053 info_ptr->gp_save_offset = 0;
19055 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
19056 info_ptr->altivec_save_offset = 0;
19058 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
19059 info_ptr->vrsave_save_offset = 0;
19061 if (! TARGET_SPE_ABI
19062 || info_ptr->spe_64bit_regs_used == 0
19063 || info_ptr->spe_gp_size == 0)
19064 info_ptr->spe_gp_save_offset = 0;
19066 if (! info_ptr->lr_save_p)
19067 info_ptr->lr_save_offset = 0;
19069 if (! info_ptr->cr_save_p)
19070 info_ptr->cr_save_offset = 0;
19072 #ifdef ENABLE_CHECKING
19073 gcc_assert (!(reload_completed && info_save.reload_completed)
19074 || memcmp (&info_save, &stack_info, sizeof stack_info) == 0);
19075 #endif
19076 return info_ptr;
19079 /* Return true if the current function uses any GPRs in 64-bit SIMD
19080 mode. */
19082 static bool
19083 spe_func_has_64bit_regs_p (void)
19085 rtx insns, insn;
19087 /* Functions that save and restore all the call-saved registers will
19088 need to save/restore the registers in 64-bits. */
19089 if (crtl->calls_eh_return
19090 || cfun->calls_setjmp
19091 || crtl->has_nonlocal_goto)
19092 return true;
19094 insns = get_insns ();
19096 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
19098 if (INSN_P (insn))
19100 rtx i;
19102 /* FIXME: This should be implemented with attributes...
19104 (set_attr "spe64" "true")....then,
19105 if (get_spe64(insn)) return true;
19107 It's the only reliable way to do the stuff below. */
19109 i = PATTERN (insn);
19110 if (GET_CODE (i) == SET)
19112 enum machine_mode mode = GET_MODE (SET_SRC (i));
19114 if (SPE_VECTOR_MODE (mode))
19115 return true;
19116 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
19117 return true;
19122 return false;
19125 static void
19126 debug_stack_info (rs6000_stack_t *info)
19128 const char *abi_string;
19130 if (! info)
19131 info = rs6000_stack_info ();
19133 fprintf (stderr, "\nStack information for function %s:\n",
19134 ((current_function_decl && DECL_NAME (current_function_decl))
19135 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
19136 : "<unknown>"));
19138 switch (info->abi)
19140 default: abi_string = "Unknown"; break;
19141 case ABI_NONE: abi_string = "NONE"; break;
19142 case ABI_AIX: abi_string = "AIX"; break;
19143 case ABI_DARWIN: abi_string = "Darwin"; break;
19144 case ABI_V4: abi_string = "V.4"; break;
19147 fprintf (stderr, "\tABI = %5s\n", abi_string);
19149 if (TARGET_ALTIVEC_ABI)
19150 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
19152 if (TARGET_SPE_ABI)
19153 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
19155 if (info->first_gp_reg_save != 32)
19156 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
19158 if (info->first_fp_reg_save != 64)
19159 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
19161 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
19162 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
19163 info->first_altivec_reg_save);
19165 if (info->lr_save_p)
19166 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
19168 if (info->cr_save_p)
19169 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
19171 if (info->vrsave_mask)
19172 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
19174 if (info->push_p)
19175 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
19177 if (info->calls_p)
19178 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
19180 if (info->gp_save_offset)
19181 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
19183 if (info->fp_save_offset)
19184 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
19186 if (info->altivec_save_offset)
19187 fprintf (stderr, "\taltivec_save_offset = %5d\n",
19188 info->altivec_save_offset);
19190 if (info->spe_gp_save_offset)
19191 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
19192 info->spe_gp_save_offset);
19194 if (info->vrsave_save_offset)
19195 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
19196 info->vrsave_save_offset);
19198 if (info->lr_save_offset)
19199 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
19201 if (info->cr_save_offset)
19202 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
19204 if (info->varargs_save_offset)
19205 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
19207 if (info->total_size)
19208 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
19209 info->total_size);
19211 if (info->vars_size)
19212 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
19213 info->vars_size);
19215 if (info->parm_size)
19216 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
19218 if (info->fixed_size)
19219 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
19221 if (info->gp_size)
19222 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
19224 if (info->spe_gp_size)
19225 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
19227 if (info->fp_size)
19228 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
19230 if (info->altivec_size)
19231 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
19233 if (info->vrsave_size)
19234 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
19236 if (info->altivec_padding_size)
19237 fprintf (stderr, "\taltivec_padding_size= %5d\n",
19238 info->altivec_padding_size);
19240 if (info->spe_padding_size)
19241 fprintf (stderr, "\tspe_padding_size = %5d\n",
19242 info->spe_padding_size);
19244 if (info->cr_size)
19245 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
19247 if (info->save_size)
19248 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
19250 if (info->reg_size != 4)
19251 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
19253 fprintf (stderr, "\n");
19257 rs6000_return_addr (int count, rtx frame)
19259 /* Currently we don't optimize very well between prolog and body
19260 code and for PIC code the code can be actually quite bad, so
19261 don't try to be too clever here. */
19262 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
19264 cfun->machine->ra_needs_full_frame = 1;
19266 return
19267 gen_rtx_MEM
19268 (Pmode,
19269 memory_address
19270 (Pmode,
19271 plus_constant (copy_to_reg
19272 (gen_rtx_MEM (Pmode,
19273 memory_address (Pmode, frame))),
19274 RETURN_ADDRESS_OFFSET)));
19277 cfun->machine->ra_need_lr = 1;
19278 return get_hard_reg_initial_val (Pmode, LR_REGNO);
19281 /* Say whether a function is a candidate for sibcall handling or not.
19282 We do not allow indirect calls to be optimized into sibling calls.
19283 Also, we can't do it if there are any vector parameters; there's
19284 nowhere to put the VRsave code so it works; note that functions with
19285 vector parameters are required to have a prototype, so the argument
19286 type info must be available here. (The tail recursion case can work
19287 with vector parameters, but there's no way to distinguish here.) */
19288 static bool
19289 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
19291 tree type;
19292 if (decl)
19294 if (TARGET_ALTIVEC_VRSAVE)
19296 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
19297 type; type = TREE_CHAIN (type))
19299 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
19300 return false;
19303 if (DEFAULT_ABI == ABI_DARWIN
19304 || ((*targetm.binds_local_p) (decl)
19305 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
19307 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
19309 if (!lookup_attribute ("longcall", attr_list)
19310 || lookup_attribute ("shortcall", attr_list))
19311 return true;
19314 return false;
19317 /* NULL if INSN insn is valid within a low-overhead loop.
19318 Otherwise return why doloop cannot be applied.
19319 PowerPC uses the COUNT register for branch on table instructions. */
19321 static const char *
19322 rs6000_invalid_within_doloop (const_rtx insn)
19324 if (CALL_P (insn))
19325 return "Function call in the loop.";
19327 if (JUMP_P (insn)
19328 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
19329 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
19330 return "Computed branch in the loop.";
19332 return NULL;
19335 static int
19336 rs6000_ra_ever_killed (void)
19338 rtx top;
19339 rtx reg;
19340 rtx insn;
19342 if (cfun->is_thunk)
19343 return 0;
19345 if (cfun->machine->lr_save_state)
19346 return cfun->machine->lr_save_state - 1;
19348 /* regs_ever_live has LR marked as used if any sibcalls are present,
19349 but this should not force saving and restoring in the
19350 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
19351 clobbers LR, so that is inappropriate. */
19353 /* Also, the prologue can generate a store into LR that
19354 doesn't really count, like this:
19356 move LR->R0
19357 bcl to set PIC register
19358 move LR->R31
19359 move R0->LR
19361 When we're called from the epilogue, we need to avoid counting
19362 this as a store. */
19364 push_topmost_sequence ();
19365 top = get_insns ();
19366 pop_topmost_sequence ();
19367 reg = gen_rtx_REG (Pmode, LR_REGNO);
19369 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
19371 if (INSN_P (insn))
19373 if (CALL_P (insn))
19375 if (!SIBLING_CALL_P (insn))
19376 return 1;
19378 else if (find_regno_note (insn, REG_INC, LR_REGNO))
19379 return 1;
19380 else if (set_of (reg, insn) != NULL_RTX
19381 && !prologue_epilogue_contains (insn))
19382 return 1;
19385 return 0;
19388 /* Emit instructions needed to load the TOC register.
19389 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
19390 a constant pool; or for SVR4 -fpic. */
19392 void
19393 rs6000_emit_load_toc_table (int fromprolog)
19395 rtx dest;
19396 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
19398 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
19400 char buf[30];
19401 rtx lab, tmp1, tmp2, got;
19403 lab = gen_label_rtx ();
19404 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (lab));
19405 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19406 if (flag_pic == 2)
19407 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
19408 else
19409 got = rs6000_got_sym ();
19410 tmp1 = tmp2 = dest;
19411 if (!fromprolog)
19413 tmp1 = gen_reg_rtx (Pmode);
19414 tmp2 = gen_reg_rtx (Pmode);
19416 emit_insn (gen_load_toc_v4_PIC_1 (lab));
19417 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
19418 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
19419 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
19421 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
19423 emit_insn (gen_load_toc_v4_pic_si ());
19424 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
19426 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
19428 char buf[30];
19429 rtx temp0 = (fromprolog
19430 ? gen_rtx_REG (Pmode, 0)
19431 : gen_reg_rtx (Pmode));
19433 if (fromprolog)
19435 rtx symF, symL;
19437 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
19438 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19440 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
19441 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19443 emit_insn (gen_load_toc_v4_PIC_1 (symF));
19444 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
19445 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
19447 else
19449 rtx tocsym, lab;
19451 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
19452 lab = gen_label_rtx ();
19453 emit_insn (gen_load_toc_v4_PIC_1b (tocsym, lab));
19454 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
19455 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
19457 emit_insn (gen_addsi3 (dest, temp0, dest));
19459 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
19461 /* This is for AIX code running in non-PIC ELF32. */
19462 char buf[30];
19463 rtx realsym;
19464 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
19465 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19467 emit_insn (gen_elf_high (dest, realsym));
19468 emit_insn (gen_elf_low (dest, dest, realsym));
19470 else
19472 gcc_assert (DEFAULT_ABI == ABI_AIX);
19474 if (TARGET_32BIT)
19475 emit_insn (gen_load_toc_aix_si (dest));
19476 else
19477 emit_insn (gen_load_toc_aix_di (dest));
19481 /* Emit instructions to restore the link register after determining where
19482 its value has been stored. */
19484 void
19485 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
19487 rs6000_stack_t *info = rs6000_stack_info ();
19488 rtx operands[2];
19490 operands[0] = source;
19491 operands[1] = scratch;
19493 if (info->lr_save_p)
19495 rtx frame_rtx = stack_pointer_rtx;
19496 HOST_WIDE_INT sp_offset = 0;
19497 rtx tmp;
19499 if (frame_pointer_needed
19500 || cfun->calls_alloca
19501 || info->total_size > 32767)
19503 tmp = gen_frame_mem (Pmode, frame_rtx);
19504 emit_move_insn (operands[1], tmp);
19505 frame_rtx = operands[1];
19507 else if (info->push_p)
19508 sp_offset = info->total_size;
19510 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
19511 tmp = gen_frame_mem (Pmode, tmp);
19512 emit_move_insn (tmp, operands[0]);
19514 else
19515 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
19517 /* Freeze lr_save_p. We've just emitted rtl that depends on the
19518 state of lr_save_p so any change from here on would be a bug. In
19519 particular, stop rs6000_ra_ever_killed from considering the SET
19520 of lr we may have added just above. */
19521 cfun->machine->lr_save_state = info->lr_save_p + 1;
19524 static GTY(()) alias_set_type set = -1;
19526 alias_set_type
19527 get_TOC_alias_set (void)
19529 if (set == -1)
19530 set = new_alias_set ();
19531 return set;
19534 /* This returns nonzero if the current function uses the TOC. This is
19535 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
19536 is generated by the ABI_V4 load_toc_* patterns. */
19537 #if TARGET_ELF
19538 static int
19539 uses_TOC (void)
19541 rtx insn;
19543 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
19544 if (INSN_P (insn))
19546 rtx pat = PATTERN (insn);
19547 int i;
19549 if (GET_CODE (pat) == PARALLEL)
19550 for (i = 0; i < XVECLEN (pat, 0); i++)
19552 rtx sub = XVECEXP (pat, 0, i);
19553 if (GET_CODE (sub) == USE)
19555 sub = XEXP (sub, 0);
19556 if (GET_CODE (sub) == UNSPEC
19557 && XINT (sub, 1) == UNSPEC_TOC)
19558 return 1;
19562 return 0;
19564 #endif
19567 create_TOC_reference (rtx symbol, rtx largetoc_reg)
19569 rtx tocrel, tocreg;
19571 if (TARGET_DEBUG_ADDR)
19573 if (GET_CODE (symbol) == SYMBOL_REF)
19574 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
19575 XSTR (symbol, 0));
19576 else
19578 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
19579 GET_RTX_NAME (GET_CODE (symbol)));
19580 debug_rtx (symbol);
19584 if (!can_create_pseudo_p ())
19585 df_set_regs_ever_live (TOC_REGISTER, true);
19587 tocrel = gen_rtx_CONST (Pmode,
19588 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol),
19589 UNSPEC_TOCREL));
19590 tocreg = gen_rtx_REG (Pmode, TOC_REGISTER);
19591 if (TARGET_CMODEL != CMODEL_SMALL)
19593 rtx hi = gen_rtx_PLUS (Pmode, tocreg, gen_rtx_HIGH (Pmode, tocrel));
19594 if (largetoc_reg != NULL)
19596 emit_move_insn (largetoc_reg, hi);
19597 hi = largetoc_reg;
19599 return gen_rtx_LO_SUM (Pmode, hi, copy_rtx (tocrel));
19601 else
19602 return gen_rtx_PLUS (Pmode, tocreg, tocrel);
19605 /* Issue assembly directives that create a reference to the given DWARF
19606 FRAME_TABLE_LABEL from the current function section. */
19607 void
19608 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
19610 fprintf (asm_out_file, "\t.ref %s\n",
19611 TARGET_STRIP_NAME_ENCODING (frame_table_label));
19614 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
19615 and the change to the stack pointer. */
19617 static void
19618 rs6000_emit_stack_tie (void)
19620 rtx mem = gen_frame_mem (BLKmode,
19621 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
19623 emit_insn (gen_stack_tie (mem));
19626 /* Emit the correct code for allocating stack space, as insns.
19627 If COPY_REG, make sure a copy of the old frame is left there.
19628 The generated code may use hard register 0 as a temporary. */
19630 static void
19631 rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg)
19633 rtx insn;
19634 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19635 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
19636 rtx todec = gen_int_mode (-size, Pmode);
19637 rtx par, set, mem;
19639 if (INTVAL (todec) != -size)
19641 warning (0, "stack frame too large");
19642 emit_insn (gen_trap ());
19643 return;
19646 if (crtl->limit_stack)
19648 if (REG_P (stack_limit_rtx)
19649 && REGNO (stack_limit_rtx) > 1
19650 && REGNO (stack_limit_rtx) <= 31)
19652 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
19653 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19654 const0_rtx));
19656 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
19657 && TARGET_32BIT
19658 && DEFAULT_ABI == ABI_V4)
19660 rtx toload = gen_rtx_CONST (VOIDmode,
19661 gen_rtx_PLUS (Pmode,
19662 stack_limit_rtx,
19663 GEN_INT (size)));
19665 emit_insn (gen_elf_high (tmp_reg, toload));
19666 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
19667 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19668 const0_rtx));
19670 else
19671 warning (0, "stack limit expression is not supported");
19674 if (copy_reg)
19675 emit_move_insn (copy_reg, stack_reg);
19677 if (size > 32767)
19679 /* Need a note here so that try_split doesn't get confused. */
19680 if (get_last_insn () == NULL_RTX)
19681 emit_note (NOTE_INSN_DELETED);
19682 insn = emit_move_insn (tmp_reg, todec);
19683 try_split (PATTERN (insn), insn, 0);
19684 todec = tmp_reg;
19687 insn = emit_insn (TARGET_32BIT
19688 ? gen_movsi_update_stack (stack_reg, stack_reg,
19689 todec, stack_reg)
19690 : gen_movdi_di_update_stack (stack_reg, stack_reg,
19691 todec, stack_reg));
19692 /* Since we didn't use gen_frame_mem to generate the MEM, grab
19693 it now and set the alias set/attributes. The above gen_*_update
19694 calls will generate a PARALLEL with the MEM set being the first
19695 operation. */
19696 par = PATTERN (insn);
19697 gcc_assert (GET_CODE (par) == PARALLEL);
19698 set = XVECEXP (par, 0, 0);
19699 gcc_assert (GET_CODE (set) == SET);
19700 mem = SET_DEST (set);
19701 gcc_assert (MEM_P (mem));
19702 MEM_NOTRAP_P (mem) = 1;
19703 set_mem_alias_set (mem, get_frame_alias_set ());
19705 RTX_FRAME_RELATED_P (insn) = 1;
19706 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
19707 gen_rtx_SET (VOIDmode, stack_reg,
19708 gen_rtx_PLUS (Pmode, stack_reg,
19709 GEN_INT (-size))));
19712 #define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
19714 #if PROBE_INTERVAL > 32768
19715 #error Cannot use indexed addressing mode for stack probing
19716 #endif
19718 /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
19719 inclusive. These are offsets from the current stack pointer. */
19721 static void
19722 rs6000_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size)
19724 /* See if we have a constant small number of probes to generate. If so,
19725 that's the easy case. */
19726 if (first + size <= 32768)
19728 HOST_WIDE_INT i;
19730 /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
19731 it exceeds SIZE. If only one probe is needed, this will not
19732 generate any code. Then probe at FIRST + SIZE. */
19733 for (i = PROBE_INTERVAL; i < size; i += PROBE_INTERVAL)
19734 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + i)));
19736 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + size)));
19739 /* Otherwise, do the same as above, but in a loop. Note that we must be
19740 extra careful with variables wrapping around because we might be at
19741 the very top (or the very bottom) of the address space and we have
19742 to be able to handle this case properly; in particular, we use an
19743 equality test for the loop condition. */
19744 else
19746 HOST_WIDE_INT rounded_size;
19747 rtx r12 = gen_rtx_REG (Pmode, 12);
19748 rtx r0 = gen_rtx_REG (Pmode, 0);
19750 /* Sanity check for the addressing mode we're going to use. */
19751 gcc_assert (first <= 32768);
19753 /* Step 1: round SIZE to the previous multiple of the interval. */
19755 rounded_size = size & -PROBE_INTERVAL;
19758 /* Step 2: compute initial and final value of the loop counter. */
19760 /* TEST_ADDR = SP + FIRST. */
19761 emit_insn (gen_rtx_SET (VOIDmode, r12,
19762 plus_constant (stack_pointer_rtx, -first)));
19764 /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE. */
19765 if (rounded_size > 32768)
19767 emit_move_insn (r0, GEN_INT (-rounded_size));
19768 emit_insn (gen_rtx_SET (VOIDmode, r0,
19769 gen_rtx_PLUS (Pmode, r12, r0)));
19771 else
19772 emit_insn (gen_rtx_SET (VOIDmode, r0,
19773 plus_constant (r12, -rounded_size)));
19776 /* Step 3: the loop
19778 while (TEST_ADDR != LAST_ADDR)
19780 TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
19781 probe at TEST_ADDR
19784 probes at FIRST + N * PROBE_INTERVAL for values of N from 1
19785 until it is equal to ROUNDED_SIZE. */
19787 if (TARGET_64BIT)
19788 emit_insn (gen_probe_stack_rangedi (r12, r12, r0));
19789 else
19790 emit_insn (gen_probe_stack_rangesi (r12, r12, r0));
19793 /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
19794 that SIZE is equal to ROUNDED_SIZE. */
19796 if (size != rounded_size)
19797 emit_stack_probe (plus_constant (r12, rounded_size - size));
19801 /* Probe a range of stack addresses from REG1 to REG2 inclusive. These are
19802 absolute addresses. */
19804 const char *
19805 output_probe_stack_range (rtx reg1, rtx reg2)
19807 static int labelno = 0;
19808 char loop_lab[32], end_lab[32];
19809 rtx xops[2];
19811 ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno);
19812 ASM_GENERATE_INTERNAL_LABEL (end_lab, "LPSRE", labelno++);
19814 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
19816 /* Jump to END_LAB if TEST_ADDR == LAST_ADDR. */
19817 xops[0] = reg1;
19818 xops[1] = reg2;
19819 if (TARGET_64BIT)
19820 output_asm_insn ("{cmp|cmpd} 0,%0,%1", xops);
19821 else
19822 output_asm_insn ("{cmp|cmpw} 0,%0,%1", xops);
19824 fputs ("\tbeq 0,", asm_out_file);
19825 assemble_name_raw (asm_out_file, end_lab);
19826 fputc ('\n', asm_out_file);
19828 /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */
19829 xops[1] = GEN_INT (-PROBE_INTERVAL);
19830 output_asm_insn ("{cal %0,%1(%0)|addi %0,%0,%1}", xops);
19832 /* Probe at TEST_ADDR and branch. */
19833 output_asm_insn ("{st|stw} 0,0(%0)", xops);
19834 fprintf (asm_out_file, "\tb ");
19835 assemble_name_raw (asm_out_file, loop_lab);
19836 fputc ('\n', asm_out_file);
19838 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, end_lab);
19840 return "";
19843 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
19844 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
19845 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
19846 deduce these equivalences by itself so it wasn't necessary to hold
19847 its hand so much. */
19849 static void
19850 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
19851 rtx reg2, rtx rreg)
19853 rtx real, temp;
19855 /* copy_rtx will not make unique copies of registers, so we need to
19856 ensure we don't have unwanted sharing here. */
19857 if (reg == reg2)
19858 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19860 if (reg == rreg)
19861 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19863 real = copy_rtx (PATTERN (insn));
19865 if (reg2 != NULL_RTX)
19866 real = replace_rtx (real, reg2, rreg);
19868 real = replace_rtx (real, reg,
19869 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
19870 STACK_POINTER_REGNUM),
19871 GEN_INT (val)));
19873 /* We expect that 'real' is either a SET or a PARALLEL containing
19874 SETs (and possibly other stuff). In a PARALLEL, all the SETs
19875 are important so they all have to be marked RTX_FRAME_RELATED_P. */
19877 if (GET_CODE (real) == SET)
19879 rtx set = real;
19881 temp = simplify_rtx (SET_SRC (set));
19882 if (temp)
19883 SET_SRC (set) = temp;
19884 temp = simplify_rtx (SET_DEST (set));
19885 if (temp)
19886 SET_DEST (set) = temp;
19887 if (GET_CODE (SET_DEST (set)) == MEM)
19889 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19890 if (temp)
19891 XEXP (SET_DEST (set), 0) = temp;
19894 else
19896 int i;
19898 gcc_assert (GET_CODE (real) == PARALLEL);
19899 for (i = 0; i < XVECLEN (real, 0); i++)
19900 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
19902 rtx set = XVECEXP (real, 0, i);
19904 temp = simplify_rtx (SET_SRC (set));
19905 if (temp)
19906 SET_SRC (set) = temp;
19907 temp = simplify_rtx (SET_DEST (set));
19908 if (temp)
19909 SET_DEST (set) = temp;
19910 if (GET_CODE (SET_DEST (set)) == MEM)
19912 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19913 if (temp)
19914 XEXP (SET_DEST (set), 0) = temp;
19916 RTX_FRAME_RELATED_P (set) = 1;
19920 RTX_FRAME_RELATED_P (insn) = 1;
19921 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
19924 /* Returns an insn that has a vrsave set operation with the
19925 appropriate CLOBBERs. */
19927 static rtx
19928 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
19930 int nclobs, i;
19931 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
19932 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19934 clobs[0]
19935 = gen_rtx_SET (VOIDmode,
19936 vrsave,
19937 gen_rtx_UNSPEC_VOLATILE (SImode,
19938 gen_rtvec (2, reg, vrsave),
19939 UNSPECV_SET_VRSAVE));
19941 nclobs = 1;
19943 /* We need to clobber the registers in the mask so the scheduler
19944 does not move sets to VRSAVE before sets of AltiVec registers.
19946 However, if the function receives nonlocal gotos, reload will set
19947 all call saved registers live. We will end up with:
19949 (set (reg 999) (mem))
19950 (parallel [ (set (reg vrsave) (unspec blah))
19951 (clobber (reg 999))])
19953 The clobber will cause the store into reg 999 to be dead, and
19954 flow will attempt to delete an epilogue insn. In this case, we
19955 need an unspec use/set of the register. */
19957 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
19958 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19960 if (!epiloguep || call_used_regs [i])
19961 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
19962 gen_rtx_REG (V4SImode, i));
19963 else
19965 rtx reg = gen_rtx_REG (V4SImode, i);
19967 clobs[nclobs++]
19968 = gen_rtx_SET (VOIDmode,
19969 reg,
19970 gen_rtx_UNSPEC (V4SImode,
19971 gen_rtvec (1, reg), 27));
19975 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
19977 for (i = 0; i < nclobs; ++i)
19978 XVECEXP (insn, 0, i) = clobs[i];
19980 return insn;
19983 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
19984 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
19986 static void
19987 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
19988 unsigned int regno, int offset, HOST_WIDE_INT total_size)
19990 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
19991 rtx replacea, replaceb;
19993 int_rtx = GEN_INT (offset);
19995 /* Some cases that need register indexed addressing. */
19996 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
19997 || (TARGET_VSX && VSX_VECTOR_MODE (mode))
19998 || (TARGET_E500_DOUBLE && mode == DFmode)
19999 || (TARGET_SPE_ABI
20000 && SPE_VECTOR_MODE (mode)
20001 && !SPE_CONST_OFFSET_OK (offset)))
20003 /* Whomever calls us must make sure r11 is available in the
20004 flow path of instructions in the prologue. */
20005 offset_rtx = gen_rtx_REG (Pmode, 11);
20006 emit_move_insn (offset_rtx, int_rtx);
20008 replacea = offset_rtx;
20009 replaceb = int_rtx;
20011 else
20013 offset_rtx = int_rtx;
20014 replacea = NULL_RTX;
20015 replaceb = NULL_RTX;
20018 reg = gen_rtx_REG (mode, regno);
20019 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
20020 mem = gen_frame_mem (mode, addr);
20022 insn = emit_move_insn (mem, reg);
20024 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
20027 /* Emit an offset memory reference suitable for a frame store, while
20028 converting to a valid addressing mode. */
20030 static rtx
20031 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
20033 rtx int_rtx, offset_rtx;
20035 int_rtx = GEN_INT (offset);
20037 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
20038 || (TARGET_E500_DOUBLE && mode == DFmode))
20040 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
20041 emit_move_insn (offset_rtx, int_rtx);
20043 else
20044 offset_rtx = int_rtx;
20046 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
20049 /* Look for user-defined global regs. We should not save and restore these,
20050 and cannot use stmw/lmw if there are any in its range. */
20052 static bool
20053 no_global_regs_above (int first, bool gpr)
20055 int i;
20056 int last = gpr ? 32 : 64;
20057 for (i = first; i < last; i++)
20058 if (global_regs[i])
20059 return false;
20060 return true;
20063 #ifndef TARGET_FIX_AND_CONTINUE
20064 #define TARGET_FIX_AND_CONTINUE 0
20065 #endif
20067 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
20068 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
20069 #define LAST_SAVRES_REGISTER 31
20070 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
20072 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
20074 /* Temporary holding space for an out-of-line register save/restore
20075 routine name. */
20076 static char savres_routine_name[30];
20078 /* Return the name for an out-of-line register save/restore routine.
20079 We are saving/restoring GPRs if GPR is true. */
20081 static char *
20082 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
20083 bool savep, bool gpr, bool lr)
20085 const char *prefix = "";
20086 const char *suffix = "";
20088 /* Different targets are supposed to define
20089 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
20090 routine name could be defined with:
20092 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
20094 This is a nice idea in practice, but in reality, things are
20095 complicated in several ways:
20097 - ELF targets have save/restore routines for GPRs.
20099 - SPE targets use different prefixes for 32/64-bit registers, and
20100 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
20102 - PPC64 ELF targets have routines for save/restore of GPRs that
20103 differ in what they do with the link register, so having a set
20104 prefix doesn't work. (We only use one of the save routines at
20105 the moment, though.)
20107 - PPC32 elf targets have "exit" versions of the restore routines
20108 that restore the link register and can save some extra space.
20109 These require an extra suffix. (There are also "tail" versions
20110 of the restore routines and "GOT" versions of the save routines,
20111 but we don't generate those at present. Same problems apply,
20112 though.)
20114 We deal with all this by synthesizing our own prefix/suffix and
20115 using that for the simple sprintf call shown above. */
20116 if (TARGET_SPE)
20118 /* No floating point saves on the SPE. */
20119 gcc_assert (gpr);
20121 if (savep)
20122 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
20123 else
20124 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
20126 if (lr)
20127 suffix = "_x";
20129 else if (DEFAULT_ABI == ABI_V4)
20131 if (TARGET_64BIT)
20132 goto aix_names;
20134 if (gpr)
20135 prefix = savep ? "_savegpr_" : "_restgpr_";
20136 else
20137 prefix = savep ? "_savefpr_" : "_restfpr_";
20139 if (lr)
20140 suffix = "_x";
20142 else if (DEFAULT_ABI == ABI_AIX)
20144 #ifndef POWERPC_LINUX
20145 /* No out-of-line save/restore routines for GPRs on AIX. */
20146 gcc_assert (!TARGET_AIX || !gpr);
20147 #endif
20149 aix_names:
20150 if (gpr)
20151 prefix = (savep
20152 ? (lr ? "_savegpr0_" : "_savegpr1_")
20153 : (lr ? "_restgpr0_" : "_restgpr1_"));
20154 #ifdef POWERPC_LINUX
20155 else if (lr)
20156 prefix = (savep ? "_savefpr_" : "_restfpr_");
20157 #endif
20158 else
20160 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
20161 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
20164 else if (DEFAULT_ABI == ABI_DARWIN)
20165 sorry ("out-of-line save/restore routines not supported on Darwin");
20167 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
20169 return savres_routine_name;
20172 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
20173 We are saving/restoring GPRs if GPR is true. */
20175 static rtx
20176 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
20177 bool gpr, bool lr)
20179 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
20180 rtx sym;
20181 int select = ((savep ? 1 : 0) << 2
20182 | ((TARGET_SPE_ABI
20183 /* On the SPE, we never have any FPRs, but we do have
20184 32/64-bit versions of the routines. */
20185 ? (info->spe_64bit_regs_used ? 1 : 0)
20186 : (gpr ? 1 : 0)) << 1)
20187 | (lr ? 1: 0));
20189 /* Don't generate bogus routine names. */
20190 gcc_assert (FIRST_SAVRES_REGISTER <= regno
20191 && regno <= LAST_SAVRES_REGISTER);
20193 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
20195 if (sym == NULL)
20197 char *name;
20199 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
20201 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
20202 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
20203 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
20206 return sym;
20209 /* Emit a sequence of insns, including a stack tie if needed, for
20210 resetting the stack pointer. If SAVRES is true, then don't reset the
20211 stack pointer, but move the base of the frame into r11 for use by
20212 out-of-line register restore routines. */
20214 static rtx
20215 rs6000_emit_stack_reset (rs6000_stack_t *info,
20216 rtx sp_reg_rtx, rtx frame_reg_rtx,
20217 int sp_offset, bool savres)
20219 /* This blockage is needed so that sched doesn't decide to move
20220 the sp change before the register restores. */
20221 if (frame_reg_rtx != sp_reg_rtx
20222 || (TARGET_SPE_ABI
20223 && info->spe_64bit_regs_used != 0
20224 && info->first_gp_reg_save != 32))
20225 rs6000_emit_stack_tie ();
20227 if (frame_reg_rtx != sp_reg_rtx)
20229 if (sp_offset != 0)
20231 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
20232 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
20233 GEN_INT (sp_offset)));
20235 else if (!savres)
20236 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
20238 else if (sp_offset != 0)
20240 /* If we are restoring registers out-of-line, we will be using the
20241 "exit" variants of the restore routines, which will reset the
20242 stack for us. But we do need to point r11 into the right place
20243 for those routines. */
20244 rtx dest_reg = (savres
20245 ? gen_rtx_REG (Pmode, 11)
20246 : sp_reg_rtx);
20248 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
20249 GEN_INT (sp_offset)));
20250 if (!savres)
20251 return insn;
20253 return NULL_RTX;
20256 /* Construct a parallel rtx describing the effect of a call to an
20257 out-of-line register save/restore routine. */
20259 static rtx
20260 rs6000_make_savres_rtx (rs6000_stack_t *info,
20261 rtx frame_reg_rtx, int save_area_offset,
20262 enum machine_mode reg_mode,
20263 bool savep, bool gpr, bool lr)
20265 int i;
20266 int offset, start_reg, end_reg, n_regs;
20267 int reg_size = GET_MODE_SIZE (reg_mode);
20268 rtx sym;
20269 rtvec p;
20271 offset = 0;
20272 start_reg = (gpr
20273 ? info->first_gp_reg_save
20274 : info->first_fp_reg_save);
20275 end_reg = gpr ? 32 : 64;
20276 n_regs = end_reg - start_reg;
20277 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
20279 if (!savep && lr)
20280 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
20282 RTVEC_ELT (p, offset++)
20283 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
20285 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
20286 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
20287 RTVEC_ELT (p, offset++)
20288 = gen_rtx_USE (VOIDmode,
20289 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
20290 : gpr && !lr ? 12
20291 : 1));
20293 for (i = 0; i < end_reg - start_reg; i++)
20295 rtx addr, reg, mem;
20296 reg = gen_rtx_REG (reg_mode, start_reg + i);
20297 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20298 GEN_INT (save_area_offset + reg_size*i));
20299 mem = gen_frame_mem (reg_mode, addr);
20301 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
20302 savep ? mem : reg,
20303 savep ? reg : mem);
20306 if (savep && lr)
20308 rtx addr, reg, mem;
20309 reg = gen_rtx_REG (Pmode, 0);
20310 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20311 GEN_INT (info->lr_save_offset));
20312 mem = gen_frame_mem (Pmode, addr);
20313 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
20316 return gen_rtx_PARALLEL (VOIDmode, p);
20319 /* Determine whether the gp REG is really used. */
20321 static bool
20322 rs6000_reg_live_or_pic_offset_p (int reg)
20324 /* If the function calls eh_return, claim used all the registers that would
20325 be checked for liveness otherwise. This is required for the PIC offset
20326 register with -mminimal-toc on AIX, as it is advertised as "fixed" for
20327 register allocation purposes in this case. */
20329 return (((crtl->calls_eh_return || df_regs_ever_live_p (reg))
20330 && (!call_used_regs[reg]
20331 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
20332 && !TARGET_SINGLE_PIC_BASE
20333 && TARGET_TOC && TARGET_MINIMAL_TOC)))
20334 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
20335 && !TARGET_SINGLE_PIC_BASE
20336 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
20337 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
20340 /* Emit function prologue as insns. */
20342 void
20343 rs6000_emit_prologue (void)
20345 rs6000_stack_t *info = rs6000_stack_info ();
20346 enum machine_mode reg_mode = Pmode;
20347 int reg_size = TARGET_32BIT ? 4 : 8;
20348 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
20349 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
20350 rtx frame_reg_rtx = sp_reg_rtx;
20351 rtx cr_save_rtx = NULL_RTX;
20352 rtx insn;
20353 int strategy;
20354 int saving_FPRs_inline;
20355 int saving_GPRs_inline;
20356 int using_store_multiple;
20357 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
20358 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
20359 && call_used_regs[STATIC_CHAIN_REGNUM]);
20360 HOST_WIDE_INT sp_offset = 0;
20362 if (flag_stack_usage)
20363 current_function_static_stack_size = info->total_size;
20365 if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK && info->total_size)
20366 rs6000_emit_probe_stack_range (STACK_CHECK_PROTECT, info->total_size);
20368 if (TARGET_FIX_AND_CONTINUE)
20370 /* gdb on darwin arranges to forward a function from the old
20371 address by modifying the first 5 instructions of the function
20372 to branch to the overriding function. This is necessary to
20373 permit function pointers that point to the old function to
20374 actually forward to the new function. */
20375 emit_insn (gen_nop ());
20376 emit_insn (gen_nop ());
20377 emit_insn (gen_nop ());
20378 emit_insn (gen_nop ());
20379 emit_insn (gen_nop ());
20382 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
20384 reg_mode = V2SImode;
20385 reg_size = 8;
20388 strategy = info->savres_strategy;
20389 using_store_multiple = strategy & SAVRES_MULTIPLE;
20390 saving_FPRs_inline = strategy & SAVE_INLINE_FPRS;
20391 saving_GPRs_inline = strategy & SAVE_INLINE_GPRS;
20393 /* For V.4, update stack before we do any saving and set back pointer. */
20394 if (! WORLD_SAVE_P (info)
20395 && info->push_p
20396 && (DEFAULT_ABI == ABI_V4
20397 || crtl->calls_eh_return))
20399 bool need_r11 = (TARGET_SPE
20400 ? (!saving_GPRs_inline
20401 && info->spe_64bit_regs_used == 0)
20402 : (!saving_FPRs_inline || !saving_GPRs_inline));
20403 rtx copy_reg = need_r11 ? gen_rtx_REG (Pmode, 11) : NULL;
20405 if (info->total_size < 32767)
20406 sp_offset = info->total_size;
20407 else if (need_r11)
20408 frame_reg_rtx = copy_reg;
20409 else if (info->cr_save_p
20410 || info->lr_save_p
20411 || info->first_fp_reg_save < 64
20412 || info->first_gp_reg_save < 32
20413 || info->altivec_size != 0
20414 || info->vrsave_mask != 0
20415 || crtl->calls_eh_return)
20417 copy_reg = frame_ptr_rtx;
20418 frame_reg_rtx = copy_reg;
20420 else
20422 /* The prologue won't be saving any regs so there is no need
20423 to set up a frame register to access any frame save area.
20424 We also won't be using sp_offset anywhere below, but set
20425 the correct value anyway to protect against future
20426 changes to this function. */
20427 sp_offset = info->total_size;
20429 rs6000_emit_allocate_stack (info->total_size, copy_reg);
20430 if (frame_reg_rtx != sp_reg_rtx)
20431 rs6000_emit_stack_tie ();
20434 /* Handle world saves specially here. */
20435 if (WORLD_SAVE_P (info))
20437 int i, j, sz;
20438 rtx treg;
20439 rtvec p;
20440 rtx reg0;
20442 /* save_world expects lr in r0. */
20443 reg0 = gen_rtx_REG (Pmode, 0);
20444 if (info->lr_save_p)
20446 insn = emit_move_insn (reg0,
20447 gen_rtx_REG (Pmode, LR_REGNO));
20448 RTX_FRAME_RELATED_P (insn) = 1;
20451 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
20452 assumptions about the offsets of various bits of the stack
20453 frame. */
20454 gcc_assert (info->gp_save_offset == -220
20455 && info->fp_save_offset == -144
20456 && info->lr_save_offset == 8
20457 && info->cr_save_offset == 4
20458 && info->push_p
20459 && info->lr_save_p
20460 && (!crtl->calls_eh_return
20461 || info->ehrd_offset == -432)
20462 && info->vrsave_save_offset == -224
20463 && info->altivec_save_offset == -416);
20465 treg = gen_rtx_REG (SImode, 11);
20466 emit_move_insn (treg, GEN_INT (-info->total_size));
20468 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
20469 in R11. It also clobbers R12, so beware! */
20471 /* Preserve CR2 for save_world prologues */
20472 sz = 5;
20473 sz += 32 - info->first_gp_reg_save;
20474 sz += 64 - info->first_fp_reg_save;
20475 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
20476 p = rtvec_alloc (sz);
20477 j = 0;
20478 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
20479 gen_rtx_REG (SImode,
20480 LR_REGNO));
20481 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
20482 gen_rtx_SYMBOL_REF (Pmode,
20483 "*save_world"));
20484 /* We do floats first so that the instruction pattern matches
20485 properly. */
20486 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20488 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20489 ? DFmode : SFmode),
20490 info->first_fp_reg_save + i);
20491 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20492 GEN_INT (info->fp_save_offset
20493 + sp_offset + 8 * i));
20494 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20495 ? DFmode : SFmode), addr);
20497 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20499 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
20501 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
20502 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20503 GEN_INT (info->altivec_save_offset
20504 + sp_offset + 16 * i));
20505 rtx mem = gen_frame_mem (V4SImode, addr);
20507 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20509 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20511 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20512 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20513 GEN_INT (info->gp_save_offset
20514 + sp_offset + reg_size * i));
20515 rtx mem = gen_frame_mem (reg_mode, addr);
20517 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20521 /* CR register traditionally saved as CR2. */
20522 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
20523 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20524 GEN_INT (info->cr_save_offset
20525 + sp_offset));
20526 rtx mem = gen_frame_mem (reg_mode, addr);
20528 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20530 /* Explain about use of R0. */
20531 if (info->lr_save_p)
20533 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20534 GEN_INT (info->lr_save_offset
20535 + sp_offset));
20536 rtx mem = gen_frame_mem (reg_mode, addr);
20538 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
20540 /* Explain what happens to the stack pointer. */
20542 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
20543 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
20546 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20547 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20548 treg, GEN_INT (-info->total_size));
20549 sp_offset = info->total_size;
20552 /* If we use the link register, get it into r0. */
20553 if (!WORLD_SAVE_P (info) && info->lr_save_p)
20555 rtx addr, reg, mem;
20557 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
20558 gen_rtx_REG (Pmode, LR_REGNO));
20559 RTX_FRAME_RELATED_P (insn) = 1;
20561 if (!(strategy & (SAVE_NOINLINE_GPRS_SAVES_LR
20562 | SAVE_NOINLINE_FPRS_SAVES_LR)))
20564 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20565 GEN_INT (info->lr_save_offset + sp_offset));
20566 reg = gen_rtx_REG (Pmode, 0);
20567 mem = gen_rtx_MEM (Pmode, addr);
20568 /* This should not be of rs6000_sr_alias_set, because of
20569 __builtin_return_address. */
20571 insn = emit_move_insn (mem, reg);
20572 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20573 NULL_RTX, NULL_RTX);
20577 /* If we need to save CR, put it into r12 or r11. */
20578 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
20580 rtx set;
20582 cr_save_rtx
20583 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
20584 ? 11 : 12);
20585 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20586 RTX_FRAME_RELATED_P (insn) = 1;
20587 /* Now, there's no way that dwarf2out_frame_debug_expr is going
20588 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
20589 But that's OK. All we have to do is specify that _one_ condition
20590 code register is saved in this stack slot. The thrower's epilogue
20591 will then restore all the call-saved registers.
20592 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
20593 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
20594 gen_rtx_REG (SImode, CR2_REGNO));
20595 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20598 /* Do any required saving of fpr's. If only one or two to save, do
20599 it ourselves. Otherwise, call function. */
20600 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
20602 int i;
20603 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20604 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
20605 && ! call_used_regs[info->first_fp_reg_save+i]))
20606 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
20607 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20608 ? DFmode : SFmode,
20609 info->first_fp_reg_save + i,
20610 info->fp_save_offset + sp_offset + 8 * i,
20611 info->total_size);
20613 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
20615 rtx par;
20617 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20618 info->fp_save_offset + sp_offset,
20619 DFmode,
20620 /*savep=*/true, /*gpr=*/false,
20621 /*lr=*/(strategy
20622 & SAVE_NOINLINE_FPRS_SAVES_LR)
20623 != 0);
20624 insn = emit_insn (par);
20625 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20626 NULL_RTX, NULL_RTX);
20629 /* Save GPRs. This is done as a PARALLEL if we are using
20630 the store-multiple instructions. */
20631 if (!WORLD_SAVE_P (info)
20632 && TARGET_SPE_ABI
20633 && info->spe_64bit_regs_used != 0
20634 && info->first_gp_reg_save != 32)
20636 int i;
20637 rtx spe_save_area_ptr;
20639 /* Determine whether we can address all of the registers that need
20640 to be saved with an offset from the stack pointer that fits in
20641 the small const field for SPE memory instructions. */
20642 int spe_regs_addressable_via_sp
20643 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
20644 + (32 - info->first_gp_reg_save - 1) * reg_size)
20645 && saving_GPRs_inline);
20646 int spe_offset;
20648 if (spe_regs_addressable_via_sp)
20650 spe_save_area_ptr = frame_reg_rtx;
20651 spe_offset = info->spe_gp_save_offset + sp_offset;
20653 else
20655 /* Make r11 point to the start of the SPE save area. We need
20656 to be careful here if r11 is holding the static chain. If
20657 it is, then temporarily save it in r0. We would use r0 as
20658 our base register here, but using r0 as a base register in
20659 loads and stores means something different from what we
20660 would like. */
20661 int ool_adjust = (saving_GPRs_inline
20663 : (info->first_gp_reg_save
20664 - (FIRST_SAVRES_REGISTER+1))*8);
20665 HOST_WIDE_INT offset = (info->spe_gp_save_offset
20666 + sp_offset - ool_adjust);
20668 if (using_static_chain_p)
20670 rtx r0 = gen_rtx_REG (Pmode, 0);
20671 gcc_assert (info->first_gp_reg_save > 11);
20673 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
20676 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
20677 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
20678 frame_reg_rtx,
20679 GEN_INT (offset)));
20680 /* We need to make sure the move to r11 gets noted for
20681 properly outputting unwind information. */
20682 if (!saving_GPRs_inline)
20683 rs6000_frame_related (insn, frame_reg_rtx, offset,
20684 NULL_RTX, NULL_RTX);
20685 spe_offset = 0;
20688 if (saving_GPRs_inline)
20690 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20691 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20693 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20694 rtx offset, addr, mem;
20696 /* We're doing all this to ensure that the offset fits into
20697 the immediate offset of 'evstdd'. */
20698 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
20700 offset = GEN_INT (reg_size * i + spe_offset);
20701 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
20702 mem = gen_rtx_MEM (V2SImode, addr);
20704 insn = emit_move_insn (mem, reg);
20706 rs6000_frame_related (insn, spe_save_area_ptr,
20707 info->spe_gp_save_offset
20708 + sp_offset + reg_size * i,
20709 offset, const0_rtx);
20712 else
20714 rtx par;
20716 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
20717 0, reg_mode,
20718 /*savep=*/true, /*gpr=*/true,
20719 /*lr=*/false);
20720 insn = emit_insn (par);
20721 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20722 NULL_RTX, NULL_RTX);
20726 /* Move the static chain pointer back. */
20727 if (using_static_chain_p && !spe_regs_addressable_via_sp)
20728 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
20730 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
20732 rtx par;
20734 /* Need to adjust r11 (r12) if we saved any FPRs. */
20735 if (info->first_fp_reg_save != 64)
20737 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
20738 ? 12 : 11);
20739 rtx offset = GEN_INT (sp_offset
20740 + (-8 * (64-info->first_fp_reg_save)));
20741 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
20744 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20745 info->gp_save_offset + sp_offset,
20746 reg_mode,
20747 /*savep=*/true, /*gpr=*/true,
20748 /*lr=*/(strategy
20749 & SAVE_NOINLINE_GPRS_SAVES_LR)
20750 != 0);
20751 insn = emit_insn (par);
20752 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20753 NULL_RTX, NULL_RTX);
20755 else if (!WORLD_SAVE_P (info) && using_store_multiple)
20757 rtvec p;
20758 int i;
20759 p = rtvec_alloc (32 - info->first_gp_reg_save);
20760 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20762 rtx addr, reg, mem;
20763 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20764 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20765 GEN_INT (info->gp_save_offset
20766 + sp_offset
20767 + reg_size * i));
20768 mem = gen_frame_mem (reg_mode, addr);
20770 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
20772 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20773 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20774 NULL_RTX, NULL_RTX);
20776 else if (!WORLD_SAVE_P (info))
20778 int i;
20779 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20780 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20782 rtx addr, reg, mem;
20783 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20785 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20786 GEN_INT (info->gp_save_offset
20787 + sp_offset
20788 + reg_size * i));
20789 mem = gen_frame_mem (reg_mode, addr);
20791 insn = emit_move_insn (mem, reg);
20792 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20793 NULL_RTX, NULL_RTX);
20797 /* ??? There's no need to emit actual instructions here, but it's the
20798 easiest way to get the frame unwind information emitted. */
20799 if (crtl->calls_eh_return)
20801 unsigned int i, regno;
20803 for (i = 0; ; ++i)
20805 regno = EH_RETURN_DATA_REGNO (i);
20806 if (regno == INVALID_REGNUM)
20807 break;
20809 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
20810 info->ehrd_offset + sp_offset
20811 + reg_size * (int) i,
20812 info->total_size);
20816 /* In AIX ABI we need to make sure r2 is really saved. */
20817 if (TARGET_AIX && crtl->calls_eh_return)
20819 rtx tmp_reg, tmp_reg_si, hi, lo, compare_result, toc_save_done, jump;
20820 long toc_restore_insn;
20822 gcc_assert (frame_reg_rtx == frame_ptr_rtx
20823 || frame_reg_rtx == sp_reg_rtx);
20824 tmp_reg = gen_rtx_REG (Pmode, 11);
20825 tmp_reg_si = gen_rtx_REG (SImode, 11);
20826 if (using_static_chain_p)
20827 emit_move_insn (gen_rtx_REG (Pmode, 0), tmp_reg);
20828 gcc_assert (saving_GPRs_inline && saving_FPRs_inline);
20829 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, LR_REGNO));
20830 /* Peek at instruction to which this function returns. If it's
20831 restoring r2, then we know we've already saved r2. We can't
20832 unconditionally save r2 because the value we have will already
20833 be updated if we arrived at this function via a plt call or
20834 toc adjusting stub. */
20835 emit_move_insn (tmp_reg_si, gen_rtx_MEM (SImode, tmp_reg));
20836 toc_restore_insn = TARGET_32BIT ? 0x80410014 : 0xE8410028;
20837 hi = gen_int_mode (toc_restore_insn & ~0xffff, SImode);
20838 emit_insn (gen_xorsi3 (tmp_reg_si, tmp_reg_si, hi));
20839 compare_result = gen_rtx_REG (CCUNSmode, CR0_REGNO);
20840 validate_condition_mode (EQ, CCUNSmode);
20841 lo = gen_int_mode (toc_restore_insn & 0xffff, SImode);
20842 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
20843 gen_rtx_COMPARE (CCUNSmode, tmp_reg_si, lo)));
20844 toc_save_done = gen_label_rtx ();
20845 jump = gen_rtx_IF_THEN_ELSE (VOIDmode,
20846 gen_rtx_EQ (VOIDmode, compare_result,
20847 const0_rtx),
20848 gen_rtx_LABEL_REF (VOIDmode, toc_save_done),
20849 pc_rtx);
20850 jump = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, jump));
20851 JUMP_LABEL (jump) = toc_save_done;
20852 LABEL_NUSES (toc_save_done) += 1;
20854 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, 2,
20855 sp_offset + 5 * reg_size, info->total_size);
20856 emit_label (toc_save_done);
20857 if (using_static_chain_p)
20858 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, 0));
20861 /* Save CR if we use any that must be preserved. */
20862 if (!WORLD_SAVE_P (info) && info->cr_save_p)
20864 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20865 GEN_INT (info->cr_save_offset + sp_offset));
20866 rtx mem = gen_frame_mem (SImode, addr);
20867 /* See the large comment above about why CR2_REGNO is used. */
20868 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
20870 /* If r12 was used to hold the original sp, copy cr into r0 now
20871 that it's free. */
20872 if (REGNO (frame_reg_rtx) == 12)
20874 rtx set;
20876 cr_save_rtx = gen_rtx_REG (SImode, 0);
20877 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20878 RTX_FRAME_RELATED_P (insn) = 1;
20879 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
20880 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20882 insn = emit_move_insn (mem, cr_save_rtx);
20884 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20885 NULL_RTX, NULL_RTX);
20888 /* Update stack and set back pointer unless this is V.4,
20889 for which it was done previously. */
20890 if (!WORLD_SAVE_P (info) && info->push_p
20891 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
20893 rtx copy_reg = NULL;
20895 if (info->total_size < 32767)
20896 sp_offset = info->total_size;
20897 else if (info->altivec_size != 0
20898 || info->vrsave_mask != 0)
20900 copy_reg = frame_ptr_rtx;
20901 frame_reg_rtx = copy_reg;
20903 else
20904 sp_offset = info->total_size;
20905 rs6000_emit_allocate_stack (info->total_size, copy_reg);
20906 if (frame_reg_rtx != sp_reg_rtx)
20907 rs6000_emit_stack_tie ();
20910 /* Set frame pointer, if needed. */
20911 if (frame_pointer_needed)
20913 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
20914 sp_reg_rtx);
20915 RTX_FRAME_RELATED_P (insn) = 1;
20918 /* Save AltiVec registers if needed. Save here because the red zone does
20919 not include AltiVec registers. */
20920 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
20922 int i;
20924 /* There should be a non inline version of this, for when we
20925 are saving lots of vector registers. */
20926 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20927 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20929 rtx areg, savereg, mem;
20930 int offset;
20932 offset = info->altivec_save_offset + sp_offset
20933 + 16 * (i - info->first_altivec_reg_save);
20935 savereg = gen_rtx_REG (V4SImode, i);
20937 areg = gen_rtx_REG (Pmode, 0);
20938 emit_move_insn (areg, GEN_INT (offset));
20940 /* AltiVec addressing mode is [reg+reg]. */
20941 mem = gen_frame_mem (V4SImode,
20942 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
20944 insn = emit_move_insn (mem, savereg);
20946 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20947 areg, GEN_INT (offset));
20951 /* VRSAVE is a bit vector representing which AltiVec registers
20952 are used. The OS uses this to determine which vector
20953 registers to save on a context switch. We need to save
20954 VRSAVE on the stack frame, add whatever AltiVec registers we
20955 used in this function, and do the corresponding magic in the
20956 epilogue. */
20958 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
20959 && info->vrsave_mask != 0)
20961 rtx reg, mem, vrsave;
20962 int offset;
20964 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
20965 as frame_reg_rtx and r11 as the static chain pointer for
20966 nested functions. */
20967 reg = gen_rtx_REG (SImode, 0);
20968 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
20969 if (TARGET_MACHO)
20970 emit_insn (gen_get_vrsave_internal (reg));
20971 else
20972 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
20974 if (!WORLD_SAVE_P (info))
20976 /* Save VRSAVE. */
20977 offset = info->vrsave_save_offset + sp_offset;
20978 mem = gen_frame_mem (SImode,
20979 gen_rtx_PLUS (Pmode, frame_reg_rtx,
20980 GEN_INT (offset)));
20981 insn = emit_move_insn (mem, reg);
20984 /* Include the registers in the mask. */
20985 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
20987 insn = emit_insn (generate_set_vrsave (reg, info, 0));
20990 if (TARGET_SINGLE_PIC_BASE)
20991 return; /* Do not set PIC register */
20993 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
20994 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
20995 || (DEFAULT_ABI == ABI_V4
20996 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
20997 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
20999 /* If emit_load_toc_table will use the link register, we need to save
21000 it. We use R12 for this purpose because emit_load_toc_table
21001 can use register 0. This allows us to use a plain 'blr' to return
21002 from the procedure more often. */
21003 int save_LR_around_toc_setup = (TARGET_ELF
21004 && DEFAULT_ABI != ABI_AIX
21005 && flag_pic
21006 && ! info->lr_save_p
21007 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
21008 if (save_LR_around_toc_setup)
21010 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
21012 insn = emit_move_insn (frame_ptr_rtx, lr);
21013 RTX_FRAME_RELATED_P (insn) = 1;
21015 rs6000_emit_load_toc_table (TRUE);
21017 insn = emit_move_insn (lr, frame_ptr_rtx);
21018 RTX_FRAME_RELATED_P (insn) = 1;
21020 else
21021 rs6000_emit_load_toc_table (TRUE);
21024 #if TARGET_MACHO
21025 if (DEFAULT_ABI == ABI_DARWIN
21026 && flag_pic && crtl->uses_pic_offset_table)
21028 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
21029 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
21031 /* Save and restore LR locally around this call (in R0). */
21032 if (!info->lr_save_p)
21033 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
21035 emit_insn (gen_load_macho_picbase (src));
21037 emit_move_insn (gen_rtx_REG (Pmode,
21038 RS6000_PIC_OFFSET_TABLE_REGNUM),
21039 lr);
21041 if (!info->lr_save_p)
21042 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
21044 #endif
21047 /* Write function prologue. */
21049 static void
21050 rs6000_output_function_prologue (FILE *file,
21051 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
21053 rs6000_stack_t *info = rs6000_stack_info ();
21055 if (TARGET_DEBUG_STACK)
21056 debug_stack_info (info);
21058 /* Write .extern for any function we will call to save and restore
21059 fp values. */
21060 if (info->first_fp_reg_save < 64)
21062 char *name;
21063 int regno = info->first_fp_reg_save - 32;
21065 if ((info->savres_strategy & SAVE_INLINE_FPRS) == 0)
21067 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
21068 /*gpr=*/false, /*lr=*/false);
21069 fprintf (file, "\t.extern %s\n", name);
21071 if ((info->savres_strategy & REST_INLINE_FPRS) == 0)
21073 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
21074 /*gpr=*/false, /*lr=*/true);
21075 fprintf (file, "\t.extern %s\n", name);
21079 /* Write .extern for AIX common mode routines, if needed. */
21080 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
21082 fputs ("\t.extern __mulh\n", file);
21083 fputs ("\t.extern __mull\n", file);
21084 fputs ("\t.extern __divss\n", file);
21085 fputs ("\t.extern __divus\n", file);
21086 fputs ("\t.extern __quoss\n", file);
21087 fputs ("\t.extern __quous\n", file);
21088 common_mode_defined = 1;
21091 if (! HAVE_prologue)
21093 rtx prologue;
21095 start_sequence ();
21097 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
21098 the "toplevel" insn chain. */
21099 emit_note (NOTE_INSN_DELETED);
21100 rs6000_emit_prologue ();
21101 emit_note (NOTE_INSN_DELETED);
21103 /* Expand INSN_ADDRESSES so final() doesn't crash. */
21105 rtx insn;
21106 unsigned addr = 0;
21107 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
21109 INSN_ADDRESSES_NEW (insn, addr);
21110 addr += 4;
21114 prologue = get_insns ();
21115 end_sequence ();
21117 if (TARGET_DEBUG_STACK)
21118 debug_rtx_list (prologue, 100);
21120 emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb),
21121 ENTRY_BLOCK_PTR);
21124 rs6000_pic_labelno++;
21127 /* Non-zero if vmx regs are restored before the frame pop, zero if
21128 we restore after the pop when possible. */
21129 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
21131 /* Reload CR from REG. */
21133 static void
21134 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
21136 int count = 0;
21137 int i;
21139 if (using_mfcr_multiple)
21141 for (i = 0; i < 8; i++)
21142 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
21143 count++;
21144 gcc_assert (count);
21147 if (using_mfcr_multiple && count > 1)
21149 rtvec p;
21150 int ndx;
21152 p = rtvec_alloc (count);
21154 ndx = 0;
21155 for (i = 0; i < 8; i++)
21156 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
21158 rtvec r = rtvec_alloc (2);
21159 RTVEC_ELT (r, 0) = reg;
21160 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
21161 RTVEC_ELT (p, ndx) =
21162 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
21163 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
21164 ndx++;
21166 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
21167 gcc_assert (ndx == count);
21169 else
21170 for (i = 0; i < 8; i++)
21171 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
21173 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
21174 CR0_REGNO+i),
21175 reg));
21179 /* Return true if OFFSET from stack pointer can be clobbered by signals.
21180 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
21181 below stack pointer not cloberred by signals. */
21183 static inline bool
21184 offset_below_red_zone_p (HOST_WIDE_INT offset)
21186 return offset < (DEFAULT_ABI == ABI_V4
21188 : TARGET_32BIT ? -220 : -288);
21191 /* Emit function epilogue as insns. */
21193 void
21194 rs6000_emit_epilogue (int sibcall)
21196 rs6000_stack_t *info;
21197 int restoring_GPRs_inline;
21198 int restoring_FPRs_inline;
21199 int using_load_multiple;
21200 int using_mtcr_multiple;
21201 int use_backchain_to_restore_sp;
21202 int restore_lr;
21203 int strategy;
21204 int sp_offset = 0;
21205 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
21206 rtx frame_reg_rtx = sp_reg_rtx;
21207 rtx cfa_restores = NULL_RTX;
21208 rtx insn;
21209 rtx cr_save_reg = NULL_RTX;
21210 enum machine_mode reg_mode = Pmode;
21211 int reg_size = TARGET_32BIT ? 4 : 8;
21212 int i;
21214 info = rs6000_stack_info ();
21216 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
21218 reg_mode = V2SImode;
21219 reg_size = 8;
21222 strategy = info->savres_strategy;
21223 using_load_multiple = strategy & SAVRES_MULTIPLE;
21224 restoring_FPRs_inline = sibcall || (strategy & REST_INLINE_FPRS);
21225 restoring_GPRs_inline = sibcall || (strategy & REST_INLINE_GPRS);
21226 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
21227 || rs6000_cpu == PROCESSOR_PPC603
21228 || rs6000_cpu == PROCESSOR_PPC750
21229 || optimize_size);
21230 /* Restore via the backchain when we have a large frame, since this
21231 is more efficient than an addis, addi pair. The second condition
21232 here will not trigger at the moment; We don't actually need a
21233 frame pointer for alloca, but the generic parts of the compiler
21234 give us one anyway. */
21235 use_backchain_to_restore_sp = (info->total_size > 32767
21236 || info->total_size
21237 + (info->lr_save_p ? info->lr_save_offset : 0)
21238 > 32767
21239 || (cfun->calls_alloca
21240 && !frame_pointer_needed));
21241 restore_lr = (info->lr_save_p
21242 && (restoring_FPRs_inline
21243 || (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR))
21244 && (restoring_GPRs_inline
21245 || info->first_fp_reg_save < 64));
21247 if (WORLD_SAVE_P (info))
21249 int i, j;
21250 char rname[30];
21251 const char *alloc_rname;
21252 rtvec p;
21254 /* eh_rest_world_r10 will return to the location saved in the LR
21255 stack slot (which is not likely to be our caller.)
21256 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
21257 rest_world is similar, except any R10 parameter is ignored.
21258 The exception-handling stuff that was here in 2.95 is no
21259 longer necessary. */
21261 p = rtvec_alloc (9
21263 + 32 - info->first_gp_reg_save
21264 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
21265 + 63 + 1 - info->first_fp_reg_save);
21267 strcpy (rname, ((crtl->calls_eh_return) ?
21268 "*eh_rest_world_r10" : "*rest_world"));
21269 alloc_rname = ggc_strdup (rname);
21271 j = 0;
21272 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
21273 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
21274 gen_rtx_REG (Pmode,
21275 LR_REGNO));
21276 RTVEC_ELT (p, j++)
21277 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
21278 /* The instruction pattern requires a clobber here;
21279 it is shared with the restVEC helper. */
21280 RTVEC_ELT (p, j++)
21281 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
21284 /* CR register traditionally saved as CR2. */
21285 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
21286 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21287 GEN_INT (info->cr_save_offset));
21288 rtx mem = gen_frame_mem (reg_mode, addr);
21290 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21293 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21295 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21296 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21297 GEN_INT (info->gp_save_offset
21298 + reg_size * i));
21299 rtx mem = gen_frame_mem (reg_mode, addr);
21301 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21303 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
21305 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
21306 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21307 GEN_INT (info->altivec_save_offset
21308 + 16 * i));
21309 rtx mem = gen_frame_mem (V4SImode, addr);
21311 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21313 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
21315 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21316 ? DFmode : SFmode),
21317 info->first_fp_reg_save + i);
21318 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21319 GEN_INT (info->fp_save_offset
21320 + 8 * i));
21321 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21322 ? DFmode : SFmode), addr);
21324 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21326 RTVEC_ELT (p, j++)
21327 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
21328 RTVEC_ELT (p, j++)
21329 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
21330 RTVEC_ELT (p, j++)
21331 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
21332 RTVEC_ELT (p, j++)
21333 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
21334 RTVEC_ELT (p, j++)
21335 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
21336 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
21338 return;
21341 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
21342 if (info->push_p)
21343 sp_offset = info->total_size;
21345 /* Restore AltiVec registers if we must do so before adjusting the
21346 stack. */
21347 if (TARGET_ALTIVEC_ABI
21348 && info->altivec_size != 0
21349 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21350 || (DEFAULT_ABI != ABI_V4
21351 && offset_below_red_zone_p (info->altivec_save_offset))))
21353 int i;
21355 if (use_backchain_to_restore_sp)
21357 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21358 emit_move_insn (frame_reg_rtx,
21359 gen_rtx_MEM (Pmode, sp_reg_rtx));
21360 sp_offset = 0;
21362 else if (frame_pointer_needed)
21363 frame_reg_rtx = hard_frame_pointer_rtx;
21365 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
21366 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
21368 rtx addr, areg, mem, reg;
21370 areg = gen_rtx_REG (Pmode, 0);
21371 emit_move_insn
21372 (areg, GEN_INT (info->altivec_save_offset
21373 + sp_offset
21374 + 16 * (i - info->first_altivec_reg_save)));
21376 /* AltiVec addressing mode is [reg+reg]. */
21377 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
21378 mem = gen_frame_mem (V4SImode, addr);
21380 reg = gen_rtx_REG (V4SImode, i);
21381 emit_move_insn (reg, mem);
21382 if (offset_below_red_zone_p (info->altivec_save_offset
21383 + (i - info->first_altivec_reg_save)
21384 * 16))
21385 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21386 cfa_restores);
21390 /* Restore VRSAVE if we must do so before adjusting the stack. */
21391 if (TARGET_ALTIVEC
21392 && TARGET_ALTIVEC_VRSAVE
21393 && info->vrsave_mask != 0
21394 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21395 || (DEFAULT_ABI != ABI_V4
21396 && offset_below_red_zone_p (info->vrsave_save_offset))))
21398 rtx addr, mem, reg;
21400 if (frame_reg_rtx == sp_reg_rtx)
21402 if (use_backchain_to_restore_sp)
21404 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21405 emit_move_insn (frame_reg_rtx,
21406 gen_rtx_MEM (Pmode, sp_reg_rtx));
21407 sp_offset = 0;
21409 else if (frame_pointer_needed)
21410 frame_reg_rtx = hard_frame_pointer_rtx;
21413 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21414 GEN_INT (info->vrsave_save_offset + sp_offset));
21415 mem = gen_frame_mem (SImode, addr);
21416 reg = gen_rtx_REG (SImode, 12);
21417 emit_move_insn (reg, mem);
21419 emit_insn (generate_set_vrsave (reg, info, 1));
21422 insn = NULL_RTX;
21423 /* If we have a large stack frame, restore the old stack pointer
21424 using the backchain. */
21425 if (use_backchain_to_restore_sp)
21427 if (frame_reg_rtx == sp_reg_rtx)
21429 /* Under V.4, don't reset the stack pointer until after we're done
21430 loading the saved registers. */
21431 if (DEFAULT_ABI == ABI_V4)
21432 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21434 insn = emit_move_insn (frame_reg_rtx,
21435 gen_rtx_MEM (Pmode, sp_reg_rtx));
21436 sp_offset = 0;
21438 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21439 && DEFAULT_ABI == ABI_V4)
21440 /* frame_reg_rtx has been set up by the altivec restore. */
21442 else
21444 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
21445 frame_reg_rtx = sp_reg_rtx;
21448 /* If we have a frame pointer, we can restore the old stack pointer
21449 from it. */
21450 else if (frame_pointer_needed)
21452 frame_reg_rtx = sp_reg_rtx;
21453 if (DEFAULT_ABI == ABI_V4)
21454 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21455 /* Prevent reordering memory accesses against stack pointer restore. */
21456 else if (cfun->calls_alloca
21457 || offset_below_red_zone_p (-info->total_size))
21459 rtx mem1 = gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx);
21460 rtx mem2 = gen_rtx_MEM (BLKmode, sp_reg_rtx);
21461 MEM_NOTRAP_P (mem1) = 1;
21462 MEM_NOTRAP_P (mem2) = 1;
21463 emit_insn (gen_frame_tie (mem1, mem2));
21466 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
21467 GEN_INT (info->total_size)));
21468 sp_offset = 0;
21470 else if (info->push_p
21471 && DEFAULT_ABI != ABI_V4
21472 && !crtl->calls_eh_return)
21474 /* Prevent reordering memory accesses against stack pointer restore. */
21475 if (cfun->calls_alloca
21476 || offset_below_red_zone_p (-info->total_size))
21478 rtx mem = gen_rtx_MEM (BLKmode, sp_reg_rtx);
21479 MEM_NOTRAP_P (mem) = 1;
21480 emit_insn (gen_stack_tie (mem));
21482 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
21483 GEN_INT (info->total_size)));
21484 sp_offset = 0;
21486 if (insn && frame_reg_rtx == sp_reg_rtx)
21488 if (cfa_restores)
21490 REG_NOTES (insn) = cfa_restores;
21491 cfa_restores = NULL_RTX;
21493 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
21494 RTX_FRAME_RELATED_P (insn) = 1;
21497 /* Restore AltiVec registers if we have not done so already. */
21498 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21499 && TARGET_ALTIVEC_ABI
21500 && info->altivec_size != 0
21501 && (DEFAULT_ABI == ABI_V4
21502 || !offset_below_red_zone_p (info->altivec_save_offset)))
21504 int i;
21506 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
21507 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
21509 rtx addr, areg, mem, reg;
21511 areg = gen_rtx_REG (Pmode, 0);
21512 emit_move_insn
21513 (areg, GEN_INT (info->altivec_save_offset
21514 + sp_offset
21515 + 16 * (i - info->first_altivec_reg_save)));
21517 /* AltiVec addressing mode is [reg+reg]. */
21518 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
21519 mem = gen_frame_mem (V4SImode, addr);
21521 reg = gen_rtx_REG (V4SImode, i);
21522 emit_move_insn (reg, mem);
21523 if (DEFAULT_ABI == ABI_V4)
21524 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21525 cfa_restores);
21529 /* Restore VRSAVE if we have not done so already. */
21530 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21531 && TARGET_ALTIVEC
21532 && TARGET_ALTIVEC_VRSAVE
21533 && info->vrsave_mask != 0
21534 && (DEFAULT_ABI == ABI_V4
21535 || !offset_below_red_zone_p (info->vrsave_save_offset)))
21537 rtx addr, mem, reg;
21539 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21540 GEN_INT (info->vrsave_save_offset + sp_offset));
21541 mem = gen_frame_mem (SImode, addr);
21542 reg = gen_rtx_REG (SImode, 12);
21543 emit_move_insn (reg, mem);
21545 emit_insn (generate_set_vrsave (reg, info, 1));
21548 /* Get the old lr if we saved it. If we are restoring registers
21549 out-of-line, then the out-of-line routines can do this for us. */
21550 if (restore_lr && restoring_GPRs_inline)
21552 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21553 info->lr_save_offset + sp_offset);
21555 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21558 /* Get the old cr if we saved it. */
21559 if (info->cr_save_p)
21561 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21562 GEN_INT (info->cr_save_offset + sp_offset));
21563 rtx mem = gen_frame_mem (SImode, addr);
21565 cr_save_reg = gen_rtx_REG (SImode,
21566 DEFAULT_ABI == ABI_AIX
21567 && !restoring_GPRs_inline
21568 && info->first_fp_reg_save < 64
21569 ? 11 : 12);
21570 emit_move_insn (cr_save_reg, mem);
21573 /* Set LR here to try to overlap restores below. LR is always saved
21574 above incoming stack, so it never needs REG_CFA_RESTORE. */
21575 if (restore_lr && restoring_GPRs_inline)
21576 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21577 gen_rtx_REG (Pmode, 0));
21579 /* Load exception handler data registers, if needed. */
21580 if (crtl->calls_eh_return)
21582 unsigned int i, regno;
21584 if (TARGET_AIX)
21586 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21587 GEN_INT (sp_offset + 5 * reg_size));
21588 rtx mem = gen_frame_mem (reg_mode, addr);
21590 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
21593 for (i = 0; ; ++i)
21595 rtx mem;
21597 regno = EH_RETURN_DATA_REGNO (i);
21598 if (regno == INVALID_REGNUM)
21599 break;
21601 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
21602 info->ehrd_offset + sp_offset
21603 + reg_size * (int) i);
21605 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
21609 /* Restore GPRs. This is done as a PARALLEL if we are using
21610 the load-multiple instructions. */
21611 if (TARGET_SPE_ABI
21612 && info->spe_64bit_regs_used != 0
21613 && info->first_gp_reg_save != 32)
21615 /* Determine whether we can address all of the registers that need
21616 to be saved with an offset from the stack pointer that fits in
21617 the small const field for SPE memory instructions. */
21618 int spe_regs_addressable_via_sp
21619 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
21620 + (32 - info->first_gp_reg_save - 1) * reg_size)
21621 && restoring_GPRs_inline);
21622 int spe_offset;
21624 if (spe_regs_addressable_via_sp)
21625 spe_offset = info->spe_gp_save_offset + sp_offset;
21626 else
21628 rtx old_frame_reg_rtx = frame_reg_rtx;
21629 /* Make r11 point to the start of the SPE save area. We worried about
21630 not clobbering it when we were saving registers in the prologue.
21631 There's no need to worry here because the static chain is passed
21632 anew to every function. */
21633 int ool_adjust = (restoring_GPRs_inline
21635 : (info->first_gp_reg_save
21636 - (FIRST_SAVRES_REGISTER+1))*8);
21638 if (frame_reg_rtx == sp_reg_rtx)
21639 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21640 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
21641 GEN_INT (info->spe_gp_save_offset
21642 + sp_offset
21643 - ool_adjust)));
21644 /* Keep the invariant that frame_reg_rtx + sp_offset points
21645 at the top of the stack frame. */
21646 sp_offset = -info->spe_gp_save_offset;
21648 spe_offset = 0;
21651 if (restoring_GPRs_inline)
21653 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21654 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21656 rtx offset, addr, mem, reg;
21658 /* We're doing all this to ensure that the immediate offset
21659 fits into the immediate field of 'evldd'. */
21660 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
21662 offset = GEN_INT (spe_offset + reg_size * i);
21663 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
21664 mem = gen_rtx_MEM (V2SImode, addr);
21665 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21667 insn = emit_move_insn (reg, mem);
21668 if (DEFAULT_ABI == ABI_V4)
21670 if (frame_pointer_needed
21671 && info->first_gp_reg_save + i
21672 == HARD_FRAME_POINTER_REGNUM)
21674 add_reg_note (insn, REG_CFA_DEF_CFA,
21675 plus_constant (frame_reg_rtx,
21676 sp_offset));
21677 RTX_FRAME_RELATED_P (insn) = 1;
21680 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21681 cfa_restores);
21685 else
21687 rtx par;
21689 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
21690 0, reg_mode,
21691 /*savep=*/false, /*gpr=*/true,
21692 /*lr=*/true);
21693 emit_jump_insn (par);
21694 /* We don't want anybody else emitting things after we jumped
21695 back. */
21696 return;
21699 else if (!restoring_GPRs_inline)
21701 /* We are jumping to an out-of-line function. */
21702 bool can_use_exit = info->first_fp_reg_save == 64;
21703 rtx par;
21705 /* Emit stack reset code if we need it. */
21706 if (can_use_exit)
21707 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21708 sp_offset, can_use_exit);
21709 else
21711 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
21712 ? 12 : 11),
21713 frame_reg_rtx,
21714 GEN_INT (sp_offset - info->fp_size)));
21715 if (REGNO (frame_reg_rtx) == 11)
21716 sp_offset += info->fp_size;
21719 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
21720 info->gp_save_offset, reg_mode,
21721 /*savep=*/false, /*gpr=*/true,
21722 /*lr=*/can_use_exit);
21724 if (can_use_exit)
21726 if (info->cr_save_p)
21728 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21729 if (DEFAULT_ABI == ABI_V4)
21730 cfa_restores
21731 = alloc_reg_note (REG_CFA_RESTORE,
21732 gen_rtx_REG (SImode, CR2_REGNO),
21733 cfa_restores);
21736 emit_jump_insn (par);
21738 /* We don't want anybody else emitting things after we jumped
21739 back. */
21740 return;
21743 insn = emit_insn (par);
21744 if (DEFAULT_ABI == ABI_V4)
21746 if (frame_pointer_needed)
21748 add_reg_note (insn, REG_CFA_DEF_CFA,
21749 plus_constant (frame_reg_rtx, sp_offset));
21750 RTX_FRAME_RELATED_P (insn) = 1;
21753 for (i = info->first_gp_reg_save; i < 32; i++)
21754 cfa_restores
21755 = alloc_reg_note (REG_CFA_RESTORE,
21756 gen_rtx_REG (reg_mode, i), cfa_restores);
21759 else if (using_load_multiple)
21761 rtvec p;
21762 p = rtvec_alloc (32 - info->first_gp_reg_save);
21763 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21765 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21766 GEN_INT (info->gp_save_offset
21767 + sp_offset
21768 + reg_size * i));
21769 rtx mem = gen_frame_mem (reg_mode, addr);
21770 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21772 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
21773 if (DEFAULT_ABI == ABI_V4)
21774 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21775 cfa_restores);
21777 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
21778 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
21780 add_reg_note (insn, REG_CFA_DEF_CFA,
21781 plus_constant (frame_reg_rtx, sp_offset));
21782 RTX_FRAME_RELATED_P (insn) = 1;
21785 else
21787 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21788 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21790 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21791 GEN_INT (info->gp_save_offset
21792 + sp_offset
21793 + reg_size * i));
21794 rtx mem = gen_frame_mem (reg_mode, addr);
21795 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21797 insn = emit_move_insn (reg, mem);
21798 if (DEFAULT_ABI == ABI_V4)
21800 if (frame_pointer_needed
21801 && info->first_gp_reg_save + i
21802 == HARD_FRAME_POINTER_REGNUM)
21804 add_reg_note (insn, REG_CFA_DEF_CFA,
21805 plus_constant (frame_reg_rtx, sp_offset));
21806 RTX_FRAME_RELATED_P (insn) = 1;
21809 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21810 cfa_restores);
21815 if (restore_lr && !restoring_GPRs_inline)
21817 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21818 info->lr_save_offset + sp_offset);
21820 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21821 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21822 gen_rtx_REG (Pmode, 0));
21825 /* Restore fpr's if we need to do it without calling a function. */
21826 if (restoring_FPRs_inline)
21827 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21828 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
21829 && ! call_used_regs[info->first_fp_reg_save+i]))
21831 rtx addr, mem, reg;
21832 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21833 GEN_INT (info->fp_save_offset
21834 + sp_offset
21835 + 8 * i));
21836 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21837 ? DFmode : SFmode), addr);
21838 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21839 ? DFmode : SFmode),
21840 info->first_fp_reg_save + i);
21842 emit_move_insn (reg, mem);
21843 if (DEFAULT_ABI == ABI_V4)
21844 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21845 cfa_restores);
21848 /* If we saved cr, restore it here. Just those that were used. */
21849 if (info->cr_save_p)
21851 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21852 if (DEFAULT_ABI == ABI_V4)
21853 cfa_restores
21854 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
21855 cfa_restores);
21858 /* If this is V.4, unwind the stack pointer after all of the loads
21859 have been done. */
21860 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21861 sp_offset, !restoring_FPRs_inline);
21862 if (insn)
21864 if (cfa_restores)
21866 REG_NOTES (insn) = cfa_restores;
21867 cfa_restores = NULL_RTX;
21869 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
21870 RTX_FRAME_RELATED_P (insn) = 1;
21873 if (crtl->calls_eh_return)
21875 rtx sa = EH_RETURN_STACKADJ_RTX;
21876 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
21879 if (!sibcall)
21881 rtvec p;
21882 bool lr = (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
21883 if (! restoring_FPRs_inline)
21884 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
21885 else
21886 p = rtvec_alloc (2);
21888 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
21889 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
21890 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
21891 : gen_rtx_CLOBBER (VOIDmode,
21892 gen_rtx_REG (Pmode, 65)));
21894 /* If we have to restore more than two FP registers, branch to the
21895 restore function. It will return to our caller. */
21896 if (! restoring_FPRs_inline)
21898 int i;
21899 rtx sym;
21901 sym = rs6000_savres_routine_sym (info,
21902 /*savep=*/false,
21903 /*gpr=*/false,
21904 /*lr=*/lr);
21905 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
21906 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
21907 gen_rtx_REG (Pmode,
21908 DEFAULT_ABI == ABI_AIX
21909 ? 1 : 11));
21910 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21912 rtx addr, mem;
21913 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
21914 GEN_INT (info->fp_save_offset + 8*i));
21915 mem = gen_frame_mem (DFmode, addr);
21917 RTVEC_ELT (p, i+4) =
21918 gen_rtx_SET (VOIDmode,
21919 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
21920 mem);
21924 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
21928 /* Write function epilogue. */
21930 static void
21931 rs6000_output_function_epilogue (FILE *file,
21932 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
21934 if (! HAVE_epilogue)
21936 rtx insn = get_last_insn ();
21937 /* If the last insn was a BARRIER, we don't have to write anything except
21938 the trace table. */
21939 if (GET_CODE (insn) == NOTE)
21940 insn = prev_nonnote_insn (insn);
21941 if (insn == 0 || GET_CODE (insn) != BARRIER)
21943 /* This is slightly ugly, but at least we don't have two
21944 copies of the epilogue-emitting code. */
21945 start_sequence ();
21947 /* A NOTE_INSN_DELETED is supposed to be at the start
21948 and end of the "toplevel" insn chain. */
21949 emit_note (NOTE_INSN_DELETED);
21950 rs6000_emit_epilogue (FALSE);
21951 emit_note (NOTE_INSN_DELETED);
21953 /* Expand INSN_ADDRESSES so final() doesn't crash. */
21955 rtx insn;
21956 unsigned addr = 0;
21957 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
21959 INSN_ADDRESSES_NEW (insn, addr);
21960 addr += 4;
21964 if (TARGET_DEBUG_STACK)
21965 debug_rtx_list (get_insns (), 100);
21966 final (get_insns (), file, FALSE);
21967 end_sequence ();
21971 #if TARGET_MACHO
21972 macho_branch_islands ();
21973 /* Mach-O doesn't support labels at the end of objects, so if
21974 it looks like we might want one, insert a NOP. */
21976 rtx insn = get_last_insn ();
21977 while (insn
21978 && NOTE_P (insn)
21979 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
21980 insn = PREV_INSN (insn);
21981 if (insn
21982 && (LABEL_P (insn)
21983 || (NOTE_P (insn)
21984 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
21985 fputs ("\tnop\n", file);
21987 #endif
21989 /* Output a traceback table here. See /usr/include/sys/debug.h for info
21990 on its format.
21992 We don't output a traceback table if -finhibit-size-directive was
21993 used. The documentation for -finhibit-size-directive reads
21994 ``don't output a @code{.size} assembler directive, or anything
21995 else that would cause trouble if the function is split in the
21996 middle, and the two halves are placed at locations far apart in
21997 memory.'' The traceback table has this property, since it
21998 includes the offset from the start of the function to the
21999 traceback table itself.
22001 System V.4 Powerpc's (and the embedded ABI derived from it) use a
22002 different traceback table. */
22003 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
22004 && rs6000_traceback != traceback_none && !cfun->is_thunk)
22006 const char *fname = NULL;
22007 const char *language_string = lang_hooks.name;
22008 int fixed_parms = 0, float_parms = 0, parm_info = 0;
22009 int i;
22010 int optional_tbtab;
22011 rs6000_stack_t *info = rs6000_stack_info ();
22013 if (rs6000_traceback == traceback_full)
22014 optional_tbtab = 1;
22015 else if (rs6000_traceback == traceback_part)
22016 optional_tbtab = 0;
22017 else
22018 optional_tbtab = !optimize_size && !TARGET_ELF;
22020 if (optional_tbtab)
22022 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
22023 while (*fname == '.') /* V.4 encodes . in the name */
22024 fname++;
22026 /* Need label immediately before tbtab, so we can compute
22027 its offset from the function start. */
22028 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
22029 ASM_OUTPUT_LABEL (file, fname);
22032 /* The .tbtab pseudo-op can only be used for the first eight
22033 expressions, since it can't handle the possibly variable
22034 length fields that follow. However, if you omit the optional
22035 fields, the assembler outputs zeros for all optional fields
22036 anyways, giving each variable length field is minimum length
22037 (as defined in sys/debug.h). Thus we can not use the .tbtab
22038 pseudo-op at all. */
22040 /* An all-zero word flags the start of the tbtab, for debuggers
22041 that have to find it by searching forward from the entry
22042 point or from the current pc. */
22043 fputs ("\t.long 0\n", file);
22045 /* Tbtab format type. Use format type 0. */
22046 fputs ("\t.byte 0,", file);
22048 /* Language type. Unfortunately, there does not seem to be any
22049 official way to discover the language being compiled, so we
22050 use language_string.
22051 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
22052 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
22053 a number, so for now use 9. LTO isn't assigned a number either,
22054 so for now use 0. */
22055 if (! strcmp (language_string, "GNU C")
22056 || ! strcmp (language_string, "GNU GIMPLE"))
22057 i = 0;
22058 else if (! strcmp (language_string, "GNU F77")
22059 || ! strcmp (language_string, "GNU Fortran"))
22060 i = 1;
22061 else if (! strcmp (language_string, "GNU Pascal"))
22062 i = 2;
22063 else if (! strcmp (language_string, "GNU Ada"))
22064 i = 3;
22065 else if (! strcmp (language_string, "GNU C++")
22066 || ! strcmp (language_string, "GNU Objective-C++"))
22067 i = 9;
22068 else if (! strcmp (language_string, "GNU Java"))
22069 i = 13;
22070 else if (! strcmp (language_string, "GNU Objective-C"))
22071 i = 14;
22072 else
22073 gcc_unreachable ();
22074 fprintf (file, "%d,", i);
22076 /* 8 single bit fields: global linkage (not set for C extern linkage,
22077 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
22078 from start of procedure stored in tbtab, internal function, function
22079 has controlled storage, function has no toc, function uses fp,
22080 function logs/aborts fp operations. */
22081 /* Assume that fp operations are used if any fp reg must be saved. */
22082 fprintf (file, "%d,",
22083 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
22085 /* 6 bitfields: function is interrupt handler, name present in
22086 proc table, function calls alloca, on condition directives
22087 (controls stack walks, 3 bits), saves condition reg, saves
22088 link reg. */
22089 /* The `function calls alloca' bit seems to be set whenever reg 31 is
22090 set up as a frame pointer, even when there is no alloca call. */
22091 fprintf (file, "%d,",
22092 ((optional_tbtab << 6)
22093 | ((optional_tbtab & frame_pointer_needed) << 5)
22094 | (info->cr_save_p << 1)
22095 | (info->lr_save_p)));
22097 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
22098 (6 bits). */
22099 fprintf (file, "%d,",
22100 (info->push_p << 7) | (64 - info->first_fp_reg_save));
22102 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
22103 fprintf (file, "%d,", (32 - first_reg_to_save ()));
22105 if (optional_tbtab)
22107 /* Compute the parameter info from the function decl argument
22108 list. */
22109 tree decl;
22110 int next_parm_info_bit = 31;
22112 for (decl = DECL_ARGUMENTS (current_function_decl);
22113 decl; decl = DECL_CHAIN (decl))
22115 rtx parameter = DECL_INCOMING_RTL (decl);
22116 enum machine_mode mode = GET_MODE (parameter);
22118 if (GET_CODE (parameter) == REG)
22120 if (SCALAR_FLOAT_MODE_P (mode))
22122 int bits;
22124 float_parms++;
22126 switch (mode)
22128 case SFmode:
22129 case SDmode:
22130 bits = 0x2;
22131 break;
22133 case DFmode:
22134 case DDmode:
22135 case TFmode:
22136 case TDmode:
22137 bits = 0x3;
22138 break;
22140 default:
22141 gcc_unreachable ();
22144 /* If only one bit will fit, don't or in this entry. */
22145 if (next_parm_info_bit > 0)
22146 parm_info |= (bits << (next_parm_info_bit - 1));
22147 next_parm_info_bit -= 2;
22149 else
22151 fixed_parms += ((GET_MODE_SIZE (mode)
22152 + (UNITS_PER_WORD - 1))
22153 / UNITS_PER_WORD);
22154 next_parm_info_bit -= 1;
22160 /* Number of fixed point parameters. */
22161 /* This is actually the number of words of fixed point parameters; thus
22162 an 8 byte struct counts as 2; and thus the maximum value is 8. */
22163 fprintf (file, "%d,", fixed_parms);
22165 /* 2 bitfields: number of floating point parameters (7 bits), parameters
22166 all on stack. */
22167 /* This is actually the number of fp registers that hold parameters;
22168 and thus the maximum value is 13. */
22169 /* Set parameters on stack bit if parameters are not in their original
22170 registers, regardless of whether they are on the stack? Xlc
22171 seems to set the bit when not optimizing. */
22172 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
22174 if (! optional_tbtab)
22175 return;
22177 /* Optional fields follow. Some are variable length. */
22179 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
22180 11 double float. */
22181 /* There is an entry for each parameter in a register, in the order that
22182 they occur in the parameter list. Any intervening arguments on the
22183 stack are ignored. If the list overflows a long (max possible length
22184 34 bits) then completely leave off all elements that don't fit. */
22185 /* Only emit this long if there was at least one parameter. */
22186 if (fixed_parms || float_parms)
22187 fprintf (file, "\t.long %d\n", parm_info);
22189 /* Offset from start of code to tb table. */
22190 fputs ("\t.long ", file);
22191 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
22192 RS6000_OUTPUT_BASENAME (file, fname);
22193 putc ('-', file);
22194 rs6000_output_function_entry (file, fname);
22195 putc ('\n', file);
22197 /* Interrupt handler mask. */
22198 /* Omit this long, since we never set the interrupt handler bit
22199 above. */
22201 /* Number of CTL (controlled storage) anchors. */
22202 /* Omit this long, since the has_ctl bit is never set above. */
22204 /* Displacement into stack of each CTL anchor. */
22205 /* Omit this list of longs, because there are no CTL anchors. */
22207 /* Length of function name. */
22208 if (*fname == '*')
22209 ++fname;
22210 fprintf (file, "\t.short %d\n", (int) strlen (fname));
22212 /* Function name. */
22213 assemble_string (fname, strlen (fname));
22215 /* Register for alloca automatic storage; this is always reg 31.
22216 Only emit this if the alloca bit was set above. */
22217 if (frame_pointer_needed)
22218 fputs ("\t.byte 31\n", file);
22220 fputs ("\t.align 2\n", file);
22224 /* A C compound statement that outputs the assembler code for a thunk
22225 function, used to implement C++ virtual function calls with
22226 multiple inheritance. The thunk acts as a wrapper around a virtual
22227 function, adjusting the implicit object parameter before handing
22228 control off to the real function.
22230 First, emit code to add the integer DELTA to the location that
22231 contains the incoming first argument. Assume that this argument
22232 contains a pointer, and is the one used to pass the `this' pointer
22233 in C++. This is the incoming argument *before* the function
22234 prologue, e.g. `%o0' on a sparc. The addition must preserve the
22235 values of all other incoming arguments.
22237 After the addition, emit code to jump to FUNCTION, which is a
22238 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
22239 not touch the return address. Hence returning from FUNCTION will
22240 return to whoever called the current `thunk'.
22242 The effect must be as if FUNCTION had been called directly with the
22243 adjusted first argument. This macro is responsible for emitting
22244 all of the code for a thunk function; output_function_prologue()
22245 and output_function_epilogue() are not invoked.
22247 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
22248 been extracted from it.) It might possibly be useful on some
22249 targets, but probably not.
22251 If you do not define this macro, the target-independent code in the
22252 C++ frontend will generate a less efficient heavyweight thunk that
22253 calls FUNCTION instead of jumping to it. The generic approach does
22254 not support varargs. */
22256 static void
22257 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
22258 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
22259 tree function)
22261 rtx this_rtx, insn, funexp;
22263 reload_completed = 1;
22264 epilogue_completed = 1;
22266 /* Mark the end of the (empty) prologue. */
22267 emit_note (NOTE_INSN_PROLOGUE_END);
22269 /* Find the "this" pointer. If the function returns a structure,
22270 the structure return pointer is in r3. */
22271 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
22272 this_rtx = gen_rtx_REG (Pmode, 4);
22273 else
22274 this_rtx = gen_rtx_REG (Pmode, 3);
22276 /* Apply the constant offset, if required. */
22277 if (delta)
22278 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
22280 /* Apply the offset from the vtable, if required. */
22281 if (vcall_offset)
22283 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
22284 rtx tmp = gen_rtx_REG (Pmode, 12);
22286 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
22287 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
22289 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
22290 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
22292 else
22294 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
22296 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
22298 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
22301 /* Generate a tail call to the target function. */
22302 if (!TREE_USED (function))
22304 assemble_external (function);
22305 TREE_USED (function) = 1;
22307 funexp = XEXP (DECL_RTL (function), 0);
22308 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
22310 #if TARGET_MACHO
22311 if (MACHOPIC_INDIRECT)
22312 funexp = machopic_indirect_call_target (funexp);
22313 #endif
22315 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
22316 generate sibcall RTL explicitly. */
22317 insn = emit_call_insn (
22318 gen_rtx_PARALLEL (VOIDmode,
22319 gen_rtvec (4,
22320 gen_rtx_CALL (VOIDmode,
22321 funexp, const0_rtx),
22322 gen_rtx_USE (VOIDmode, const0_rtx),
22323 gen_rtx_USE (VOIDmode,
22324 gen_rtx_REG (SImode,
22325 LR_REGNO)),
22326 gen_rtx_RETURN (VOIDmode))));
22327 SIBLING_CALL_P (insn) = 1;
22328 emit_barrier ();
22330 /* Run just enough of rest_of_compilation to get the insns emitted.
22331 There's not really enough bulk here to make other passes such as
22332 instruction scheduling worth while. Note that use_thunk calls
22333 assemble_start_function and assemble_end_function. */
22334 insn = get_insns ();
22335 insn_locators_alloc ();
22336 shorten_branches (insn);
22337 final_start_function (insn, file, 1);
22338 final (insn, file, 1);
22339 final_end_function ();
22341 reload_completed = 0;
22342 epilogue_completed = 0;
22345 /* A quick summary of the various types of 'constant-pool tables'
22346 under PowerPC:
22348 Target Flags Name One table per
22349 AIX (none) AIX TOC object file
22350 AIX -mfull-toc AIX TOC object file
22351 AIX -mminimal-toc AIX minimal TOC translation unit
22352 SVR4/EABI (none) SVR4 SDATA object file
22353 SVR4/EABI -fpic SVR4 pic object file
22354 SVR4/EABI -fPIC SVR4 PIC translation unit
22355 SVR4/EABI -mrelocatable EABI TOC function
22356 SVR4/EABI -maix AIX TOC object file
22357 SVR4/EABI -maix -mminimal-toc
22358 AIX minimal TOC translation unit
22360 Name Reg. Set by entries contains:
22361 made by addrs? fp? sum?
22363 AIX TOC 2 crt0 as Y option option
22364 AIX minimal TOC 30 prolog gcc Y Y option
22365 SVR4 SDATA 13 crt0 gcc N Y N
22366 SVR4 pic 30 prolog ld Y not yet N
22367 SVR4 PIC 30 prolog gcc Y option option
22368 EABI TOC 30 prolog gcc Y option option
22372 /* Hash functions for the hash table. */
22374 static unsigned
22375 rs6000_hash_constant (rtx k)
22377 enum rtx_code code = GET_CODE (k);
22378 enum machine_mode mode = GET_MODE (k);
22379 unsigned result = (code << 3) ^ mode;
22380 const char *format;
22381 int flen, fidx;
22383 format = GET_RTX_FORMAT (code);
22384 flen = strlen (format);
22385 fidx = 0;
22387 switch (code)
22389 case LABEL_REF:
22390 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
22392 case CONST_DOUBLE:
22393 if (mode != VOIDmode)
22394 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
22395 flen = 2;
22396 break;
22398 case CODE_LABEL:
22399 fidx = 3;
22400 break;
22402 default:
22403 break;
22406 for (; fidx < flen; fidx++)
22407 switch (format[fidx])
22409 case 's':
22411 unsigned i, len;
22412 const char *str = XSTR (k, fidx);
22413 len = strlen (str);
22414 result = result * 613 + len;
22415 for (i = 0; i < len; i++)
22416 result = result * 613 + (unsigned) str[i];
22417 break;
22419 case 'u':
22420 case 'e':
22421 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
22422 break;
22423 case 'i':
22424 case 'n':
22425 result = result * 613 + (unsigned) XINT (k, fidx);
22426 break;
22427 case 'w':
22428 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
22429 result = result * 613 + (unsigned) XWINT (k, fidx);
22430 else
22432 size_t i;
22433 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
22434 result = result * 613 + (unsigned) (XWINT (k, fidx)
22435 >> CHAR_BIT * i);
22437 break;
22438 case '0':
22439 break;
22440 default:
22441 gcc_unreachable ();
22444 return result;
22447 static unsigned
22448 toc_hash_function (const void *hash_entry)
22450 const struct toc_hash_struct *thc =
22451 (const struct toc_hash_struct *) hash_entry;
22452 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
22455 /* Compare H1 and H2 for equivalence. */
22457 static int
22458 toc_hash_eq (const void *h1, const void *h2)
22460 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
22461 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
22463 if (((const struct toc_hash_struct *) h1)->key_mode
22464 != ((const struct toc_hash_struct *) h2)->key_mode)
22465 return 0;
22467 return rtx_equal_p (r1, r2);
22470 /* These are the names given by the C++ front-end to vtables, and
22471 vtable-like objects. Ideally, this logic should not be here;
22472 instead, there should be some programmatic way of inquiring as
22473 to whether or not an object is a vtable. */
22475 #define VTABLE_NAME_P(NAME) \
22476 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
22477 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
22478 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
22479 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
22480 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
22482 #ifdef NO_DOLLAR_IN_LABEL
22483 /* Return a GGC-allocated character string translating dollar signs in
22484 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
22486 const char *
22487 rs6000_xcoff_strip_dollar (const char *name)
22489 char *strip, *p;
22490 int len;
22492 p = strchr (name, '$');
22494 if (p == 0 || p == name)
22495 return name;
22497 len = strlen (name);
22498 strip = (char *) alloca (len + 1);
22499 strcpy (strip, name);
22500 p = strchr (strip, '$');
22501 while (p)
22503 *p = '_';
22504 p = strchr (p + 1, '$');
22507 return ggc_alloc_string (strip, len);
22509 #endif
22511 void
22512 rs6000_output_symbol_ref (FILE *file, rtx x)
22514 /* Currently C++ toc references to vtables can be emitted before it
22515 is decided whether the vtable is public or private. If this is
22516 the case, then the linker will eventually complain that there is
22517 a reference to an unknown section. Thus, for vtables only,
22518 we emit the TOC reference to reference the symbol and not the
22519 section. */
22520 const char *name = XSTR (x, 0);
22522 if (VTABLE_NAME_P (name))
22524 RS6000_OUTPUT_BASENAME (file, name);
22526 else
22527 assemble_name (file, name);
22530 /* Output a TOC entry. We derive the entry name from what is being
22531 written. */
22533 void
22534 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
22536 char buf[256];
22537 const char *name = buf;
22538 rtx base = x;
22539 HOST_WIDE_INT offset = 0;
22541 gcc_assert (!TARGET_NO_TOC);
22543 /* When the linker won't eliminate them, don't output duplicate
22544 TOC entries (this happens on AIX if there is any kind of TOC,
22545 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
22546 CODE_LABELs. */
22547 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
22549 struct toc_hash_struct *h;
22550 void * * found;
22552 /* Create toc_hash_table. This can't be done at TARGET_OPTION_OVERRIDE
22553 time because GGC is not initialized at that point. */
22554 if (toc_hash_table == NULL)
22555 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
22556 toc_hash_eq, NULL);
22558 h = ggc_alloc_toc_hash_struct ();
22559 h->key = x;
22560 h->key_mode = mode;
22561 h->labelno = labelno;
22563 found = htab_find_slot (toc_hash_table, h, INSERT);
22564 if (*found == NULL)
22565 *found = h;
22566 else /* This is indeed a duplicate.
22567 Set this label equal to that label. */
22569 fputs ("\t.set ", file);
22570 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22571 fprintf (file, "%d,", labelno);
22572 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22573 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
22574 found)->labelno));
22575 return;
22579 /* If we're going to put a double constant in the TOC, make sure it's
22580 aligned properly when strict alignment is on. */
22581 if (GET_CODE (x) == CONST_DOUBLE
22582 && STRICT_ALIGNMENT
22583 && GET_MODE_BITSIZE (mode) >= 64
22584 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
22585 ASM_OUTPUT_ALIGN (file, 3);
22588 (*targetm.asm_out.internal_label) (file, "LC", labelno);
22590 /* Handle FP constants specially. Note that if we have a minimal
22591 TOC, things we put here aren't actually in the TOC, so we can allow
22592 FP constants. */
22593 if (GET_CODE (x) == CONST_DOUBLE &&
22594 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
22596 REAL_VALUE_TYPE rv;
22597 long k[4];
22599 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22600 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22601 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
22602 else
22603 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
22605 if (TARGET_64BIT)
22607 if (TARGET_MINIMAL_TOC)
22608 fputs (DOUBLE_INT_ASM_OP, file);
22609 else
22610 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22611 k[0] & 0xffffffff, k[1] & 0xffffffff,
22612 k[2] & 0xffffffff, k[3] & 0xffffffff);
22613 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
22614 k[0] & 0xffffffff, k[1] & 0xffffffff,
22615 k[2] & 0xffffffff, k[3] & 0xffffffff);
22616 return;
22618 else
22620 if (TARGET_MINIMAL_TOC)
22621 fputs ("\t.long ", file);
22622 else
22623 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22624 k[0] & 0xffffffff, k[1] & 0xffffffff,
22625 k[2] & 0xffffffff, k[3] & 0xffffffff);
22626 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
22627 k[0] & 0xffffffff, k[1] & 0xffffffff,
22628 k[2] & 0xffffffff, k[3] & 0xffffffff);
22629 return;
22632 else if (GET_CODE (x) == CONST_DOUBLE &&
22633 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
22635 REAL_VALUE_TYPE rv;
22636 long k[2];
22638 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22640 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22641 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
22642 else
22643 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
22645 if (TARGET_64BIT)
22647 if (TARGET_MINIMAL_TOC)
22648 fputs (DOUBLE_INT_ASM_OP, file);
22649 else
22650 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22651 k[0] & 0xffffffff, k[1] & 0xffffffff);
22652 fprintf (file, "0x%lx%08lx\n",
22653 k[0] & 0xffffffff, k[1] & 0xffffffff);
22654 return;
22656 else
22658 if (TARGET_MINIMAL_TOC)
22659 fputs ("\t.long ", file);
22660 else
22661 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22662 k[0] & 0xffffffff, k[1] & 0xffffffff);
22663 fprintf (file, "0x%lx,0x%lx\n",
22664 k[0] & 0xffffffff, k[1] & 0xffffffff);
22665 return;
22668 else if (GET_CODE (x) == CONST_DOUBLE &&
22669 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
22671 REAL_VALUE_TYPE rv;
22672 long l;
22674 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22675 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22676 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
22677 else
22678 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
22680 if (TARGET_64BIT)
22682 if (TARGET_MINIMAL_TOC)
22683 fputs (DOUBLE_INT_ASM_OP, file);
22684 else
22685 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22686 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
22687 return;
22689 else
22691 if (TARGET_MINIMAL_TOC)
22692 fputs ("\t.long ", file);
22693 else
22694 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22695 fprintf (file, "0x%lx\n", l & 0xffffffff);
22696 return;
22699 else if (GET_MODE (x) == VOIDmode
22700 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
22702 unsigned HOST_WIDE_INT low;
22703 HOST_WIDE_INT high;
22705 if (GET_CODE (x) == CONST_DOUBLE)
22707 low = CONST_DOUBLE_LOW (x);
22708 high = CONST_DOUBLE_HIGH (x);
22710 else
22711 #if HOST_BITS_PER_WIDE_INT == 32
22713 low = INTVAL (x);
22714 high = (low & 0x80000000) ? ~0 : 0;
22716 #else
22718 low = INTVAL (x) & 0xffffffff;
22719 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
22721 #endif
22723 /* TOC entries are always Pmode-sized, but since this
22724 is a bigendian machine then if we're putting smaller
22725 integer constants in the TOC we have to pad them.
22726 (This is still a win over putting the constants in
22727 a separate constant pool, because then we'd have
22728 to have both a TOC entry _and_ the actual constant.)
22730 For a 32-bit target, CONST_INT values are loaded and shifted
22731 entirely within `low' and can be stored in one TOC entry. */
22733 /* It would be easy to make this work, but it doesn't now. */
22734 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
22736 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
22738 #if HOST_BITS_PER_WIDE_INT == 32
22739 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
22740 POINTER_SIZE, &low, &high, 0);
22741 #else
22742 low |= high << 32;
22743 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
22744 high = (HOST_WIDE_INT) low >> 32;
22745 low &= 0xffffffff;
22746 #endif
22749 if (TARGET_64BIT)
22751 if (TARGET_MINIMAL_TOC)
22752 fputs (DOUBLE_INT_ASM_OP, file);
22753 else
22754 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22755 (long) high & 0xffffffff, (long) low & 0xffffffff);
22756 fprintf (file, "0x%lx%08lx\n",
22757 (long) high & 0xffffffff, (long) low & 0xffffffff);
22758 return;
22760 else
22762 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
22764 if (TARGET_MINIMAL_TOC)
22765 fputs ("\t.long ", file);
22766 else
22767 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22768 (long) high & 0xffffffff, (long) low & 0xffffffff);
22769 fprintf (file, "0x%lx,0x%lx\n",
22770 (long) high & 0xffffffff, (long) low & 0xffffffff);
22772 else
22774 if (TARGET_MINIMAL_TOC)
22775 fputs ("\t.long ", file);
22776 else
22777 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
22778 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
22780 return;
22784 if (GET_CODE (x) == CONST)
22786 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
22787 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
22789 base = XEXP (XEXP (x, 0), 0);
22790 offset = INTVAL (XEXP (XEXP (x, 0), 1));
22793 switch (GET_CODE (base))
22795 case SYMBOL_REF:
22796 name = XSTR (base, 0);
22797 break;
22799 case LABEL_REF:
22800 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
22801 CODE_LABEL_NUMBER (XEXP (base, 0)));
22802 break;
22804 case CODE_LABEL:
22805 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
22806 break;
22808 default:
22809 gcc_unreachable ();
22812 if (TARGET_MINIMAL_TOC)
22813 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
22814 else
22816 fputs ("\t.tc ", file);
22817 RS6000_OUTPUT_BASENAME (file, name);
22819 if (offset < 0)
22820 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
22821 else if (offset)
22822 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
22824 fputs ("[TC],", file);
22827 /* Currently C++ toc references to vtables can be emitted before it
22828 is decided whether the vtable is public or private. If this is
22829 the case, then the linker will eventually complain that there is
22830 a TOC reference to an unknown section. Thus, for vtables only,
22831 we emit the TOC reference to reference the symbol and not the
22832 section. */
22833 if (VTABLE_NAME_P (name))
22835 RS6000_OUTPUT_BASENAME (file, name);
22836 if (offset < 0)
22837 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
22838 else if (offset > 0)
22839 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
22841 else
22842 output_addr_const (file, x);
22843 putc ('\n', file);
22846 /* Output an assembler pseudo-op to write an ASCII string of N characters
22847 starting at P to FILE.
22849 On the RS/6000, we have to do this using the .byte operation and
22850 write out special characters outside the quoted string.
22851 Also, the assembler is broken; very long strings are truncated,
22852 so we must artificially break them up early. */
22854 void
22855 output_ascii (FILE *file, const char *p, int n)
22857 char c;
22858 int i, count_string;
22859 const char *for_string = "\t.byte \"";
22860 const char *for_decimal = "\t.byte ";
22861 const char *to_close = NULL;
22863 count_string = 0;
22864 for (i = 0; i < n; i++)
22866 c = *p++;
22867 if (c >= ' ' && c < 0177)
22869 if (for_string)
22870 fputs (for_string, file);
22871 putc (c, file);
22873 /* Write two quotes to get one. */
22874 if (c == '"')
22876 putc (c, file);
22877 ++count_string;
22880 for_string = NULL;
22881 for_decimal = "\"\n\t.byte ";
22882 to_close = "\"\n";
22883 ++count_string;
22885 if (count_string >= 512)
22887 fputs (to_close, file);
22889 for_string = "\t.byte \"";
22890 for_decimal = "\t.byte ";
22891 to_close = NULL;
22892 count_string = 0;
22895 else
22897 if (for_decimal)
22898 fputs (for_decimal, file);
22899 fprintf (file, "%d", c);
22901 for_string = "\n\t.byte \"";
22902 for_decimal = ", ";
22903 to_close = "\n";
22904 count_string = 0;
22908 /* Now close the string if we have written one. Then end the line. */
22909 if (to_close)
22910 fputs (to_close, file);
22913 /* Generate a unique section name for FILENAME for a section type
22914 represented by SECTION_DESC. Output goes into BUF.
22916 SECTION_DESC can be any string, as long as it is different for each
22917 possible section type.
22919 We name the section in the same manner as xlc. The name begins with an
22920 underscore followed by the filename (after stripping any leading directory
22921 names) with the last period replaced by the string SECTION_DESC. If
22922 FILENAME does not contain a period, SECTION_DESC is appended to the end of
22923 the name. */
22925 void
22926 rs6000_gen_section_name (char **buf, const char *filename,
22927 const char *section_desc)
22929 const char *q, *after_last_slash, *last_period = 0;
22930 char *p;
22931 int len;
22933 after_last_slash = filename;
22934 for (q = filename; *q; q++)
22936 if (*q == '/')
22937 after_last_slash = q + 1;
22938 else if (*q == '.')
22939 last_period = q;
22942 len = strlen (after_last_slash) + strlen (section_desc) + 2;
22943 *buf = (char *) xmalloc (len);
22945 p = *buf;
22946 *p++ = '_';
22948 for (q = after_last_slash; *q; q++)
22950 if (q == last_period)
22952 strcpy (p, section_desc);
22953 p += strlen (section_desc);
22954 break;
22957 else if (ISALNUM (*q))
22958 *p++ = *q;
22961 if (last_period == 0)
22962 strcpy (p, section_desc);
22963 else
22964 *p = '\0';
22967 /* Emit profile function. */
22969 void
22970 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
22972 /* Non-standard profiling for kernels, which just saves LR then calls
22973 _mcount without worrying about arg saves. The idea is to change
22974 the function prologue as little as possible as it isn't easy to
22975 account for arg save/restore code added just for _mcount. */
22976 if (TARGET_PROFILE_KERNEL)
22977 return;
22979 if (DEFAULT_ABI == ABI_AIX)
22981 #ifndef NO_PROFILE_COUNTERS
22982 # define NO_PROFILE_COUNTERS 0
22983 #endif
22984 if (NO_PROFILE_COUNTERS)
22985 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22986 LCT_NORMAL, VOIDmode, 0);
22987 else
22989 char buf[30];
22990 const char *label_name;
22991 rtx fun;
22993 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
22994 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
22995 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
22997 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22998 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
23001 else if (DEFAULT_ABI == ABI_DARWIN)
23003 const char *mcount_name = RS6000_MCOUNT;
23004 int caller_addr_regno = LR_REGNO;
23006 /* Be conservative and always set this, at least for now. */
23007 crtl->uses_pic_offset_table = 1;
23009 #if TARGET_MACHO
23010 /* For PIC code, set up a stub and collect the caller's address
23011 from r0, which is where the prologue puts it. */
23012 if (MACHOPIC_INDIRECT
23013 && crtl->uses_pic_offset_table)
23014 caller_addr_regno = 0;
23015 #endif
23016 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
23017 LCT_NORMAL, VOIDmode, 1,
23018 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
23022 /* Write function profiler code. */
23024 void
23025 output_function_profiler (FILE *file, int labelno)
23027 char buf[100];
23029 switch (DEFAULT_ABI)
23031 default:
23032 gcc_unreachable ();
23034 case ABI_V4:
23035 if (!TARGET_32BIT)
23037 warning (0, "no profiling of 64-bit code for this ABI");
23038 return;
23040 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
23041 fprintf (file, "\tmflr %s\n", reg_names[0]);
23042 if (NO_PROFILE_COUNTERS)
23044 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
23045 reg_names[0], reg_names[1]);
23047 else if (TARGET_SECURE_PLT && flag_pic)
23049 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
23050 reg_names[0], reg_names[1]);
23051 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
23052 asm_fprintf (file, "\t{cau|addis} %s,%s,",
23053 reg_names[12], reg_names[12]);
23054 assemble_name (file, buf);
23055 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
23056 assemble_name (file, buf);
23057 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
23059 else if (flag_pic == 1)
23061 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
23062 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
23063 reg_names[0], reg_names[1]);
23064 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
23065 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
23066 assemble_name (file, buf);
23067 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
23069 else if (flag_pic > 1)
23071 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
23072 reg_names[0], reg_names[1]);
23073 /* Now, we need to get the address of the label. */
23074 fputs ("\tbcl 20,31,1f\n\t.long ", file);
23075 assemble_name (file, buf);
23076 fputs ("-.\n1:", file);
23077 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
23078 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
23079 reg_names[0], reg_names[11]);
23080 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
23081 reg_names[0], reg_names[0], reg_names[11]);
23083 else
23085 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
23086 assemble_name (file, buf);
23087 fputs ("@ha\n", file);
23088 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
23089 reg_names[0], reg_names[1]);
23090 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
23091 assemble_name (file, buf);
23092 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
23095 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
23096 fprintf (file, "\tbl %s%s\n",
23097 RS6000_MCOUNT, flag_pic ? "@plt" : "");
23098 break;
23100 case ABI_AIX:
23101 case ABI_DARWIN:
23102 if (!TARGET_PROFILE_KERNEL)
23104 /* Don't do anything, done in output_profile_hook (). */
23106 else
23108 gcc_assert (!TARGET_32BIT);
23110 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
23111 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
23113 if (cfun->static_chain_decl != NULL)
23115 asm_fprintf (file, "\tstd %s,24(%s)\n",
23116 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
23117 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
23118 asm_fprintf (file, "\tld %s,24(%s)\n",
23119 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
23121 else
23122 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
23124 break;
23130 /* The following variable value is the last issued insn. */
23132 static rtx last_scheduled_insn;
23134 /* The following variable helps to balance issuing of load and
23135 store instructions */
23137 static int load_store_pendulum;
23139 /* Power4 load update and store update instructions are cracked into a
23140 load or store and an integer insn which are executed in the same cycle.
23141 Branches have their own dispatch slot which does not count against the
23142 GCC issue rate, but it changes the program flow so there are no other
23143 instructions to issue in this cycle. */
23145 static int
23146 rs6000_variable_issue_1 (rtx insn, int more)
23148 last_scheduled_insn = insn;
23149 if (GET_CODE (PATTERN (insn)) == USE
23150 || GET_CODE (PATTERN (insn)) == CLOBBER)
23152 cached_can_issue_more = more;
23153 return cached_can_issue_more;
23156 if (insn_terminates_group_p (insn, current_group))
23158 cached_can_issue_more = 0;
23159 return cached_can_issue_more;
23162 /* If no reservation, but reach here */
23163 if (recog_memoized (insn) < 0)
23164 return more;
23166 if (rs6000_sched_groups)
23168 if (is_microcoded_insn (insn))
23169 cached_can_issue_more = 0;
23170 else if (is_cracked_insn (insn))
23171 cached_can_issue_more = more > 2 ? more - 2 : 0;
23172 else
23173 cached_can_issue_more = more - 1;
23175 return cached_can_issue_more;
23178 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
23179 return 0;
23181 cached_can_issue_more = more - 1;
23182 return cached_can_issue_more;
23185 static int
23186 rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more)
23188 int r = rs6000_variable_issue_1 (insn, more);
23189 if (verbose)
23190 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r);
23191 return r;
23194 /* Adjust the cost of a scheduling dependency. Return the new cost of
23195 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
23197 static int
23198 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
23200 enum attr_type attr_type;
23202 if (! recog_memoized (insn))
23203 return 0;
23205 switch (REG_NOTE_KIND (link))
23207 case REG_DEP_TRUE:
23209 /* Data dependency; DEP_INSN writes a register that INSN reads
23210 some cycles later. */
23212 /* Separate a load from a narrower, dependent store. */
23213 if (rs6000_sched_groups
23214 && GET_CODE (PATTERN (insn)) == SET
23215 && GET_CODE (PATTERN (dep_insn)) == SET
23216 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
23217 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
23218 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
23219 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
23220 return cost + 14;
23222 attr_type = get_attr_type (insn);
23224 switch (attr_type)
23226 case TYPE_JMPREG:
23227 /* Tell the first scheduling pass about the latency between
23228 a mtctr and bctr (and mtlr and br/blr). The first
23229 scheduling pass will not know about this latency since
23230 the mtctr instruction, which has the latency associated
23231 to it, will be generated by reload. */
23232 return TARGET_POWER ? 5 : 4;
23233 case TYPE_BRANCH:
23234 /* Leave some extra cycles between a compare and its
23235 dependent branch, to inhibit expensive mispredicts. */
23236 if ((rs6000_cpu_attr == CPU_PPC603
23237 || rs6000_cpu_attr == CPU_PPC604
23238 || rs6000_cpu_attr == CPU_PPC604E
23239 || rs6000_cpu_attr == CPU_PPC620
23240 || rs6000_cpu_attr == CPU_PPC630
23241 || rs6000_cpu_attr == CPU_PPC750
23242 || rs6000_cpu_attr == CPU_PPC7400
23243 || rs6000_cpu_attr == CPU_PPC7450
23244 || rs6000_cpu_attr == CPU_POWER4
23245 || rs6000_cpu_attr == CPU_POWER5
23246 || rs6000_cpu_attr == CPU_POWER7
23247 || rs6000_cpu_attr == CPU_CELL)
23248 && recog_memoized (dep_insn)
23249 && (INSN_CODE (dep_insn) >= 0))
23251 switch (get_attr_type (dep_insn))
23253 case TYPE_CMP:
23254 case TYPE_COMPARE:
23255 case TYPE_DELAYED_COMPARE:
23256 case TYPE_IMUL_COMPARE:
23257 case TYPE_LMUL_COMPARE:
23258 case TYPE_FPCOMPARE:
23259 case TYPE_CR_LOGICAL:
23260 case TYPE_DELAYED_CR:
23261 return cost + 2;
23262 default:
23263 break;
23265 break;
23267 case TYPE_STORE:
23268 case TYPE_STORE_U:
23269 case TYPE_STORE_UX:
23270 case TYPE_FPSTORE:
23271 case TYPE_FPSTORE_U:
23272 case TYPE_FPSTORE_UX:
23273 if ((rs6000_cpu == PROCESSOR_POWER6)
23274 && recog_memoized (dep_insn)
23275 && (INSN_CODE (dep_insn) >= 0))
23278 if (GET_CODE (PATTERN (insn)) != SET)
23279 /* If this happens, we have to extend this to schedule
23280 optimally. Return default for now. */
23281 return cost;
23283 /* Adjust the cost for the case where the value written
23284 by a fixed point operation is used as the address
23285 gen value on a store. */
23286 switch (get_attr_type (dep_insn))
23288 case TYPE_LOAD:
23289 case TYPE_LOAD_U:
23290 case TYPE_LOAD_UX:
23291 case TYPE_CNTLZ:
23293 if (! store_data_bypass_p (dep_insn, insn))
23294 return 4;
23295 break;
23297 case TYPE_LOAD_EXT:
23298 case TYPE_LOAD_EXT_U:
23299 case TYPE_LOAD_EXT_UX:
23300 case TYPE_VAR_SHIFT_ROTATE:
23301 case TYPE_VAR_DELAYED_COMPARE:
23303 if (! store_data_bypass_p (dep_insn, insn))
23304 return 6;
23305 break;
23307 case TYPE_INTEGER:
23308 case TYPE_COMPARE:
23309 case TYPE_FAST_COMPARE:
23310 case TYPE_EXTS:
23311 case TYPE_SHIFT:
23312 case TYPE_INSERT_WORD:
23313 case TYPE_INSERT_DWORD:
23314 case TYPE_FPLOAD_U:
23315 case TYPE_FPLOAD_UX:
23316 case TYPE_STORE_U:
23317 case TYPE_STORE_UX:
23318 case TYPE_FPSTORE_U:
23319 case TYPE_FPSTORE_UX:
23321 if (! store_data_bypass_p (dep_insn, insn))
23322 return 3;
23323 break;
23325 case TYPE_IMUL:
23326 case TYPE_IMUL2:
23327 case TYPE_IMUL3:
23328 case TYPE_LMUL:
23329 case TYPE_IMUL_COMPARE:
23330 case TYPE_LMUL_COMPARE:
23332 if (! store_data_bypass_p (dep_insn, insn))
23333 return 17;
23334 break;
23336 case TYPE_IDIV:
23338 if (! store_data_bypass_p (dep_insn, insn))
23339 return 45;
23340 break;
23342 case TYPE_LDIV:
23344 if (! store_data_bypass_p (dep_insn, insn))
23345 return 57;
23346 break;
23348 default:
23349 break;
23352 break;
23354 case TYPE_LOAD:
23355 case TYPE_LOAD_U:
23356 case TYPE_LOAD_UX:
23357 case TYPE_LOAD_EXT:
23358 case TYPE_LOAD_EXT_U:
23359 case TYPE_LOAD_EXT_UX:
23360 if ((rs6000_cpu == PROCESSOR_POWER6)
23361 && recog_memoized (dep_insn)
23362 && (INSN_CODE (dep_insn) >= 0))
23365 /* Adjust the cost for the case where the value written
23366 by a fixed point instruction is used within the address
23367 gen portion of a subsequent load(u)(x) */
23368 switch (get_attr_type (dep_insn))
23370 case TYPE_LOAD:
23371 case TYPE_LOAD_U:
23372 case TYPE_LOAD_UX:
23373 case TYPE_CNTLZ:
23375 if (set_to_load_agen (dep_insn, insn))
23376 return 4;
23377 break;
23379 case TYPE_LOAD_EXT:
23380 case TYPE_LOAD_EXT_U:
23381 case TYPE_LOAD_EXT_UX:
23382 case TYPE_VAR_SHIFT_ROTATE:
23383 case TYPE_VAR_DELAYED_COMPARE:
23385 if (set_to_load_agen (dep_insn, insn))
23386 return 6;
23387 break;
23389 case TYPE_INTEGER:
23390 case TYPE_COMPARE:
23391 case TYPE_FAST_COMPARE:
23392 case TYPE_EXTS:
23393 case TYPE_SHIFT:
23394 case TYPE_INSERT_WORD:
23395 case TYPE_INSERT_DWORD:
23396 case TYPE_FPLOAD_U:
23397 case TYPE_FPLOAD_UX:
23398 case TYPE_STORE_U:
23399 case TYPE_STORE_UX:
23400 case TYPE_FPSTORE_U:
23401 case TYPE_FPSTORE_UX:
23403 if (set_to_load_agen (dep_insn, insn))
23404 return 3;
23405 break;
23407 case TYPE_IMUL:
23408 case TYPE_IMUL2:
23409 case TYPE_IMUL3:
23410 case TYPE_LMUL:
23411 case TYPE_IMUL_COMPARE:
23412 case TYPE_LMUL_COMPARE:
23414 if (set_to_load_agen (dep_insn, insn))
23415 return 17;
23416 break;
23418 case TYPE_IDIV:
23420 if (set_to_load_agen (dep_insn, insn))
23421 return 45;
23422 break;
23424 case TYPE_LDIV:
23426 if (set_to_load_agen (dep_insn, insn))
23427 return 57;
23428 break;
23430 default:
23431 break;
23434 break;
23436 case TYPE_FPLOAD:
23437 if ((rs6000_cpu == PROCESSOR_POWER6)
23438 && recog_memoized (dep_insn)
23439 && (INSN_CODE (dep_insn) >= 0)
23440 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
23441 return 2;
23443 default:
23444 break;
23447 /* Fall out to return default cost. */
23449 break;
23451 case REG_DEP_OUTPUT:
23452 /* Output dependency; DEP_INSN writes a register that INSN writes some
23453 cycles later. */
23454 if ((rs6000_cpu == PROCESSOR_POWER6)
23455 && recog_memoized (dep_insn)
23456 && (INSN_CODE (dep_insn) >= 0))
23458 attr_type = get_attr_type (insn);
23460 switch (attr_type)
23462 case TYPE_FP:
23463 if (get_attr_type (dep_insn) == TYPE_FP)
23464 return 1;
23465 break;
23466 case TYPE_FPLOAD:
23467 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
23468 return 2;
23469 break;
23470 default:
23471 break;
23474 case REG_DEP_ANTI:
23475 /* Anti dependency; DEP_INSN reads a register that INSN writes some
23476 cycles later. */
23477 return 0;
23479 default:
23480 gcc_unreachable ();
23483 return cost;
23486 /* Debug version of rs6000_adjust_cost. */
23488 static int
23489 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
23491 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
23493 if (ret != cost)
23495 const char *dep;
23497 switch (REG_NOTE_KIND (link))
23499 default: dep = "unknown depencency"; break;
23500 case REG_DEP_TRUE: dep = "data dependency"; break;
23501 case REG_DEP_OUTPUT: dep = "output dependency"; break;
23502 case REG_DEP_ANTI: dep = "anti depencency"; break;
23505 fprintf (stderr,
23506 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
23507 "%s, insn:\n", ret, cost, dep);
23509 debug_rtx (insn);
23512 return ret;
23515 /* The function returns a true if INSN is microcoded.
23516 Return false otherwise. */
23518 static bool
23519 is_microcoded_insn (rtx insn)
23521 if (!insn || !NONDEBUG_INSN_P (insn)
23522 || GET_CODE (PATTERN (insn)) == USE
23523 || GET_CODE (PATTERN (insn)) == CLOBBER)
23524 return false;
23526 if (rs6000_cpu_attr == CPU_CELL)
23527 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
23529 if (rs6000_sched_groups)
23531 enum attr_type type = get_attr_type (insn);
23532 if (type == TYPE_LOAD_EXT_U
23533 || type == TYPE_LOAD_EXT_UX
23534 || type == TYPE_LOAD_UX
23535 || type == TYPE_STORE_UX
23536 || type == TYPE_MFCR)
23537 return true;
23540 return false;
23543 /* The function returns true if INSN is cracked into 2 instructions
23544 by the processor (and therefore occupies 2 issue slots). */
23546 static bool
23547 is_cracked_insn (rtx insn)
23549 if (!insn || !NONDEBUG_INSN_P (insn)
23550 || GET_CODE (PATTERN (insn)) == USE
23551 || GET_CODE (PATTERN (insn)) == CLOBBER)
23552 return false;
23554 if (rs6000_sched_groups)
23556 enum attr_type type = get_attr_type (insn);
23557 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
23558 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
23559 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
23560 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
23561 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
23562 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
23563 || type == TYPE_IDIV || type == TYPE_LDIV
23564 || type == TYPE_INSERT_WORD)
23565 return true;
23568 return false;
23571 /* The function returns true if INSN can be issued only from
23572 the branch slot. */
23574 static bool
23575 is_branch_slot_insn (rtx insn)
23577 if (!insn || !NONDEBUG_INSN_P (insn)
23578 || GET_CODE (PATTERN (insn)) == USE
23579 || GET_CODE (PATTERN (insn)) == CLOBBER)
23580 return false;
23582 if (rs6000_sched_groups)
23584 enum attr_type type = get_attr_type (insn);
23585 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
23586 return true;
23587 return false;
23590 return false;
23593 /* The function returns true if out_inst sets a value that is
23594 used in the address generation computation of in_insn */
23595 static bool
23596 set_to_load_agen (rtx out_insn, rtx in_insn)
23598 rtx out_set, in_set;
23600 /* For performance reasons, only handle the simple case where
23601 both loads are a single_set. */
23602 out_set = single_set (out_insn);
23603 if (out_set)
23605 in_set = single_set (in_insn);
23606 if (in_set)
23607 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
23610 return false;
23613 /* The function returns true if the target storage location of
23614 out_insn is adjacent to the target storage location of in_insn */
23615 /* Return 1 if memory locations are adjacent. */
23617 static bool
23618 adjacent_mem_locations (rtx insn1, rtx insn2)
23621 rtx a = get_store_dest (PATTERN (insn1));
23622 rtx b = get_store_dest (PATTERN (insn2));
23624 if ((GET_CODE (XEXP (a, 0)) == REG
23625 || (GET_CODE (XEXP (a, 0)) == PLUS
23626 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
23627 && (GET_CODE (XEXP (b, 0)) == REG
23628 || (GET_CODE (XEXP (b, 0)) == PLUS
23629 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
23631 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
23632 rtx reg0, reg1;
23634 if (GET_CODE (XEXP (a, 0)) == PLUS)
23636 reg0 = XEXP (XEXP (a, 0), 0);
23637 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
23639 else
23640 reg0 = XEXP (a, 0);
23642 if (GET_CODE (XEXP (b, 0)) == PLUS)
23644 reg1 = XEXP (XEXP (b, 0), 0);
23645 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
23647 else
23648 reg1 = XEXP (b, 0);
23650 val_diff = val1 - val0;
23652 return ((REGNO (reg0) == REGNO (reg1))
23653 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
23654 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
23657 return false;
23660 /* A C statement (sans semicolon) to update the integer scheduling
23661 priority INSN_PRIORITY (INSN). Increase the priority to execute the
23662 INSN earlier, reduce the priority to execute INSN later. Do not
23663 define this macro if you do not need to adjust the scheduling
23664 priorities of insns. */
23666 static int
23667 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
23669 /* On machines (like the 750) which have asymmetric integer units,
23670 where one integer unit can do multiply and divides and the other
23671 can't, reduce the priority of multiply/divide so it is scheduled
23672 before other integer operations. */
23674 #if 0
23675 if (! INSN_P (insn))
23676 return priority;
23678 if (GET_CODE (PATTERN (insn)) == USE)
23679 return priority;
23681 switch (rs6000_cpu_attr) {
23682 case CPU_PPC750:
23683 switch (get_attr_type (insn))
23685 default:
23686 break;
23688 case TYPE_IMUL:
23689 case TYPE_IDIV:
23690 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
23691 priority, priority);
23692 if (priority >= 0 && priority < 0x01000000)
23693 priority >>= 3;
23694 break;
23697 #endif
23699 if (insn_must_be_first_in_group (insn)
23700 && reload_completed
23701 && current_sched_info->sched_max_insns_priority
23702 && rs6000_sched_restricted_insns_priority)
23705 /* Prioritize insns that can be dispatched only in the first
23706 dispatch slot. */
23707 if (rs6000_sched_restricted_insns_priority == 1)
23708 /* Attach highest priority to insn. This means that in
23709 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
23710 precede 'priority' (critical path) considerations. */
23711 return current_sched_info->sched_max_insns_priority;
23712 else if (rs6000_sched_restricted_insns_priority == 2)
23713 /* Increase priority of insn by a minimal amount. This means that in
23714 haifa-sched.c:ready_sort(), only 'priority' (critical path)
23715 considerations precede dispatch-slot restriction considerations. */
23716 return (priority + 1);
23719 if (rs6000_cpu == PROCESSOR_POWER6
23720 && ((load_store_pendulum == -2 && is_load_insn (insn))
23721 || (load_store_pendulum == 2 && is_store_insn (insn))))
23722 /* Attach highest priority to insn if the scheduler has just issued two
23723 stores and this instruction is a load, or two loads and this instruction
23724 is a store. Power6 wants loads and stores scheduled alternately
23725 when possible */
23726 return current_sched_info->sched_max_insns_priority;
23728 return priority;
23731 /* Return true if the instruction is nonpipelined on the Cell. */
23732 static bool
23733 is_nonpipeline_insn (rtx insn)
23735 enum attr_type type;
23736 if (!insn || !NONDEBUG_INSN_P (insn)
23737 || GET_CODE (PATTERN (insn)) == USE
23738 || GET_CODE (PATTERN (insn)) == CLOBBER)
23739 return false;
23741 type = get_attr_type (insn);
23742 if (type == TYPE_IMUL
23743 || type == TYPE_IMUL2
23744 || type == TYPE_IMUL3
23745 || type == TYPE_LMUL
23746 || type == TYPE_IDIV
23747 || type == TYPE_LDIV
23748 || type == TYPE_SDIV
23749 || type == TYPE_DDIV
23750 || type == TYPE_SSQRT
23751 || type == TYPE_DSQRT
23752 || type == TYPE_MFCR
23753 || type == TYPE_MFCRF
23754 || type == TYPE_MFJMPR)
23756 return true;
23758 return false;
23762 /* Return how many instructions the machine can issue per cycle. */
23764 static int
23765 rs6000_issue_rate (void)
23767 /* Unless scheduling for register pressure, use issue rate of 1 for
23768 first scheduling pass to decrease degradation. */
23769 if (!reload_completed && !flag_sched_pressure)
23770 return 1;
23772 switch (rs6000_cpu_attr) {
23773 case CPU_RIOS1: /* ? */
23774 case CPU_RS64A:
23775 case CPU_PPC601: /* ? */
23776 case CPU_PPC7450:
23777 return 3;
23778 case CPU_PPC440:
23779 case CPU_PPC603:
23780 case CPU_PPC750:
23781 case CPU_PPC7400:
23782 case CPU_PPC8540:
23783 case CPU_CELL:
23784 case CPU_PPCE300C2:
23785 case CPU_PPCE300C3:
23786 case CPU_PPCE500MC:
23787 case CPU_PPCE500MC64:
23788 case CPU_TITAN:
23789 return 2;
23790 case CPU_RIOS2:
23791 case CPU_PPC476:
23792 case CPU_PPC604:
23793 case CPU_PPC604E:
23794 case CPU_PPC620:
23795 case CPU_PPC630:
23796 return 4;
23797 case CPU_POWER4:
23798 case CPU_POWER5:
23799 case CPU_POWER6:
23800 case CPU_POWER7:
23801 return 5;
23802 default:
23803 return 1;
23807 /* Return how many instructions to look ahead for better insn
23808 scheduling. */
23810 static int
23811 rs6000_use_sched_lookahead (void)
23813 if (rs6000_cpu_attr == CPU_PPC8540)
23814 return 4;
23815 if (rs6000_cpu_attr == CPU_CELL)
23816 return (reload_completed ? 8 : 0);
23817 return 0;
23820 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
23821 static int
23822 rs6000_use_sched_lookahead_guard (rtx insn)
23824 if (rs6000_cpu_attr != CPU_CELL)
23825 return 1;
23827 if (insn == NULL_RTX || !INSN_P (insn))
23828 abort ();
23830 if (!reload_completed
23831 || is_nonpipeline_insn (insn)
23832 || is_microcoded_insn (insn))
23833 return 0;
23835 return 1;
23838 /* Determine is PAT refers to memory. */
23840 static bool
23841 is_mem_ref (rtx pat)
23843 const char * fmt;
23844 int i, j;
23845 bool ret = false;
23847 /* stack_tie does not produce any real memory traffic. */
23848 if (GET_CODE (pat) == UNSPEC
23849 && XINT (pat, 1) == UNSPEC_TIE)
23850 return false;
23852 if (GET_CODE (pat) == MEM)
23853 return true;
23855 /* Recursively process the pattern. */
23856 fmt = GET_RTX_FORMAT (GET_CODE (pat));
23858 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
23860 if (fmt[i] == 'e')
23861 ret |= is_mem_ref (XEXP (pat, i));
23862 else if (fmt[i] == 'E')
23863 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
23864 ret |= is_mem_ref (XVECEXP (pat, i, j));
23867 return ret;
23870 /* Determine if PAT is a PATTERN of a load insn. */
23872 static bool
23873 is_load_insn1 (rtx pat)
23875 if (!pat || pat == NULL_RTX)
23876 return false;
23878 if (GET_CODE (pat) == SET)
23879 return is_mem_ref (SET_SRC (pat));
23881 if (GET_CODE (pat) == PARALLEL)
23883 int i;
23885 for (i = 0; i < XVECLEN (pat, 0); i++)
23886 if (is_load_insn1 (XVECEXP (pat, 0, i)))
23887 return true;
23890 return false;
23893 /* Determine if INSN loads from memory. */
23895 static bool
23896 is_load_insn (rtx insn)
23898 if (!insn || !INSN_P (insn))
23899 return false;
23901 if (GET_CODE (insn) == CALL_INSN)
23902 return false;
23904 return is_load_insn1 (PATTERN (insn));
23907 /* Determine if PAT is a PATTERN of a store insn. */
23909 static bool
23910 is_store_insn1 (rtx pat)
23912 if (!pat || pat == NULL_RTX)
23913 return false;
23915 if (GET_CODE (pat) == SET)
23916 return is_mem_ref (SET_DEST (pat));
23918 if (GET_CODE (pat) == PARALLEL)
23920 int i;
23922 for (i = 0; i < XVECLEN (pat, 0); i++)
23923 if (is_store_insn1 (XVECEXP (pat, 0, i)))
23924 return true;
23927 return false;
23930 /* Determine if INSN stores to memory. */
23932 static bool
23933 is_store_insn (rtx insn)
23935 if (!insn || !INSN_P (insn))
23936 return false;
23938 return is_store_insn1 (PATTERN (insn));
23941 /* Return the dest of a store insn. */
23943 static rtx
23944 get_store_dest (rtx pat)
23946 gcc_assert (is_store_insn1 (pat));
23948 if (GET_CODE (pat) == SET)
23949 return SET_DEST (pat);
23950 else if (GET_CODE (pat) == PARALLEL)
23952 int i;
23954 for (i = 0; i < XVECLEN (pat, 0); i++)
23956 rtx inner_pat = XVECEXP (pat, 0, i);
23957 if (GET_CODE (inner_pat) == SET
23958 && is_mem_ref (SET_DEST (inner_pat)))
23959 return inner_pat;
23962 /* We shouldn't get here, because we should have either a simple
23963 store insn or a store with update which are covered above. */
23964 gcc_unreachable();
23967 /* Returns whether the dependence between INSN and NEXT is considered
23968 costly by the given target. */
23970 static bool
23971 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
23973 rtx insn;
23974 rtx next;
23976 /* If the flag is not enabled - no dependence is considered costly;
23977 allow all dependent insns in the same group.
23978 This is the most aggressive option. */
23979 if (rs6000_sched_costly_dep == no_dep_costly)
23980 return false;
23982 /* If the flag is set to 1 - a dependence is always considered costly;
23983 do not allow dependent instructions in the same group.
23984 This is the most conservative option. */
23985 if (rs6000_sched_costly_dep == all_deps_costly)
23986 return true;
23988 insn = DEP_PRO (dep);
23989 next = DEP_CON (dep);
23991 if (rs6000_sched_costly_dep == store_to_load_dep_costly
23992 && is_load_insn (next)
23993 && is_store_insn (insn))
23994 /* Prevent load after store in the same group. */
23995 return true;
23997 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
23998 && is_load_insn (next)
23999 && is_store_insn (insn)
24000 && DEP_TYPE (dep) == REG_DEP_TRUE)
24001 /* Prevent load after store in the same group if it is a true
24002 dependence. */
24003 return true;
24005 /* The flag is set to X; dependences with latency >= X are considered costly,
24006 and will not be scheduled in the same group. */
24007 if (rs6000_sched_costly_dep <= max_dep_latency
24008 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
24009 return true;
24011 return false;
24014 /* Return the next insn after INSN that is found before TAIL is reached,
24015 skipping any "non-active" insns - insns that will not actually occupy
24016 an issue slot. Return NULL_RTX if such an insn is not found. */
24018 static rtx
24019 get_next_active_insn (rtx insn, rtx tail)
24021 if (insn == NULL_RTX || insn == tail)
24022 return NULL_RTX;
24024 while (1)
24026 insn = NEXT_INSN (insn);
24027 if (insn == NULL_RTX || insn == tail)
24028 return NULL_RTX;
24030 if (CALL_P (insn)
24031 || JUMP_P (insn)
24032 || (NONJUMP_INSN_P (insn)
24033 && GET_CODE (PATTERN (insn)) != USE
24034 && GET_CODE (PATTERN (insn)) != CLOBBER
24035 && INSN_CODE (insn) != CODE_FOR_stack_tie))
24036 break;
24038 return insn;
24041 /* We are about to begin issuing insns for this clock cycle. */
24043 static int
24044 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
24045 rtx *ready ATTRIBUTE_UNUSED,
24046 int *pn_ready ATTRIBUTE_UNUSED,
24047 int clock_var ATTRIBUTE_UNUSED)
24049 int n_ready = *pn_ready;
24051 if (sched_verbose)
24052 fprintf (dump, "// rs6000_sched_reorder :\n");
24054 /* Reorder the ready list, if the second to last ready insn
24055 is a nonepipeline insn. */
24056 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
24058 if (is_nonpipeline_insn (ready[n_ready - 1])
24059 && (recog_memoized (ready[n_ready - 2]) > 0))
24060 /* Simply swap first two insns. */
24062 rtx tmp = ready[n_ready - 1];
24063 ready[n_ready - 1] = ready[n_ready - 2];
24064 ready[n_ready - 2] = tmp;
24068 if (rs6000_cpu == PROCESSOR_POWER6)
24069 load_store_pendulum = 0;
24071 return rs6000_issue_rate ();
24074 /* Like rs6000_sched_reorder, but called after issuing each insn. */
24076 static int
24077 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
24078 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
24080 if (sched_verbose)
24081 fprintf (dump, "// rs6000_sched_reorder2 :\n");
24083 /* For Power6, we need to handle some special cases to try and keep the
24084 store queue from overflowing and triggering expensive flushes.
24086 This code monitors how load and store instructions are being issued
24087 and skews the ready list one way or the other to increase the likelihood
24088 that a desired instruction is issued at the proper time.
24090 A couple of things are done. First, we maintain a "load_store_pendulum"
24091 to track the current state of load/store issue.
24093 - If the pendulum is at zero, then no loads or stores have been
24094 issued in the current cycle so we do nothing.
24096 - If the pendulum is 1, then a single load has been issued in this
24097 cycle and we attempt to locate another load in the ready list to
24098 issue with it.
24100 - If the pendulum is -2, then two stores have already been
24101 issued in this cycle, so we increase the priority of the first load
24102 in the ready list to increase it's likelihood of being chosen first
24103 in the next cycle.
24105 - If the pendulum is -1, then a single store has been issued in this
24106 cycle and we attempt to locate another store in the ready list to
24107 issue with it, preferring a store to an adjacent memory location to
24108 facilitate store pairing in the store queue.
24110 - If the pendulum is 2, then two loads have already been
24111 issued in this cycle, so we increase the priority of the first store
24112 in the ready list to increase it's likelihood of being chosen first
24113 in the next cycle.
24115 - If the pendulum < -2 or > 2, then do nothing.
24117 Note: This code covers the most common scenarios. There exist non
24118 load/store instructions which make use of the LSU and which
24119 would need to be accounted for to strictly model the behavior
24120 of the machine. Those instructions are currently unaccounted
24121 for to help minimize compile time overhead of this code.
24123 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
24125 int pos;
24126 int i;
24127 rtx tmp;
24129 if (is_store_insn (last_scheduled_insn))
24130 /* Issuing a store, swing the load_store_pendulum to the left */
24131 load_store_pendulum--;
24132 else if (is_load_insn (last_scheduled_insn))
24133 /* Issuing a load, swing the load_store_pendulum to the right */
24134 load_store_pendulum++;
24135 else
24136 return cached_can_issue_more;
24138 /* If the pendulum is balanced, or there is only one instruction on
24139 the ready list, then all is well, so return. */
24140 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
24141 return cached_can_issue_more;
24143 if (load_store_pendulum == 1)
24145 /* A load has been issued in this cycle. Scan the ready list
24146 for another load to issue with it */
24147 pos = *pn_ready-1;
24149 while (pos >= 0)
24151 if (is_load_insn (ready[pos]))
24153 /* Found a load. Move it to the head of the ready list,
24154 and adjust it's priority so that it is more likely to
24155 stay there */
24156 tmp = ready[pos];
24157 for (i=pos; i<*pn_ready-1; i++)
24158 ready[i] = ready[i + 1];
24159 ready[*pn_ready-1] = tmp;
24161 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
24162 INSN_PRIORITY (tmp)++;
24163 break;
24165 pos--;
24168 else if (load_store_pendulum == -2)
24170 /* Two stores have been issued in this cycle. Increase the
24171 priority of the first load in the ready list to favor it for
24172 issuing in the next cycle. */
24173 pos = *pn_ready-1;
24175 while (pos >= 0)
24177 if (is_load_insn (ready[pos])
24178 && !sel_sched_p ()
24179 && INSN_PRIORITY_KNOWN (ready[pos]))
24181 INSN_PRIORITY (ready[pos])++;
24183 /* Adjust the pendulum to account for the fact that a load
24184 was found and increased in priority. This is to prevent
24185 increasing the priority of multiple loads */
24186 load_store_pendulum--;
24188 break;
24190 pos--;
24193 else if (load_store_pendulum == -1)
24195 /* A store has been issued in this cycle. Scan the ready list for
24196 another store to issue with it, preferring a store to an adjacent
24197 memory location */
24198 int first_store_pos = -1;
24200 pos = *pn_ready-1;
24202 while (pos >= 0)
24204 if (is_store_insn (ready[pos]))
24206 /* Maintain the index of the first store found on the
24207 list */
24208 if (first_store_pos == -1)
24209 first_store_pos = pos;
24211 if (is_store_insn (last_scheduled_insn)
24212 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
24214 /* Found an adjacent store. Move it to the head of the
24215 ready list, and adjust it's priority so that it is
24216 more likely to stay there */
24217 tmp = ready[pos];
24218 for (i=pos; i<*pn_ready-1; i++)
24219 ready[i] = ready[i + 1];
24220 ready[*pn_ready-1] = tmp;
24222 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
24223 INSN_PRIORITY (tmp)++;
24225 first_store_pos = -1;
24227 break;
24230 pos--;
24233 if (first_store_pos >= 0)
24235 /* An adjacent store wasn't found, but a non-adjacent store was,
24236 so move the non-adjacent store to the front of the ready
24237 list, and adjust its priority so that it is more likely to
24238 stay there. */
24239 tmp = ready[first_store_pos];
24240 for (i=first_store_pos; i<*pn_ready-1; i++)
24241 ready[i] = ready[i + 1];
24242 ready[*pn_ready-1] = tmp;
24243 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
24244 INSN_PRIORITY (tmp)++;
24247 else if (load_store_pendulum == 2)
24249 /* Two loads have been issued in this cycle. Increase the priority
24250 of the first store in the ready list to favor it for issuing in
24251 the next cycle. */
24252 pos = *pn_ready-1;
24254 while (pos >= 0)
24256 if (is_store_insn (ready[pos])
24257 && !sel_sched_p ()
24258 && INSN_PRIORITY_KNOWN (ready[pos]))
24260 INSN_PRIORITY (ready[pos])++;
24262 /* Adjust the pendulum to account for the fact that a store
24263 was found and increased in priority. This is to prevent
24264 increasing the priority of multiple stores */
24265 load_store_pendulum++;
24267 break;
24269 pos--;
24274 return cached_can_issue_more;
24277 /* Return whether the presence of INSN causes a dispatch group termination
24278 of group WHICH_GROUP.
24280 If WHICH_GROUP == current_group, this function will return true if INSN
24281 causes the termination of the current group (i.e, the dispatch group to
24282 which INSN belongs). This means that INSN will be the last insn in the
24283 group it belongs to.
24285 If WHICH_GROUP == previous_group, this function will return true if INSN
24286 causes the termination of the previous group (i.e, the dispatch group that
24287 precedes the group to which INSN belongs). This means that INSN will be
24288 the first insn in the group it belongs to). */
24290 static bool
24291 insn_terminates_group_p (rtx insn, enum group_termination which_group)
24293 bool first, last;
24295 if (! insn)
24296 return false;
24298 first = insn_must_be_first_in_group (insn);
24299 last = insn_must_be_last_in_group (insn);
24301 if (first && last)
24302 return true;
24304 if (which_group == current_group)
24305 return last;
24306 else if (which_group == previous_group)
24307 return first;
24309 return false;
24313 static bool
24314 insn_must_be_first_in_group (rtx insn)
24316 enum attr_type type;
24318 if (!insn
24319 || GET_CODE (insn) == NOTE
24320 || DEBUG_INSN_P (insn)
24321 || GET_CODE (PATTERN (insn)) == USE
24322 || GET_CODE (PATTERN (insn)) == CLOBBER)
24323 return false;
24325 switch (rs6000_cpu)
24327 case PROCESSOR_POWER5:
24328 if (is_cracked_insn (insn))
24329 return true;
24330 case PROCESSOR_POWER4:
24331 if (is_microcoded_insn (insn))
24332 return true;
24334 if (!rs6000_sched_groups)
24335 return false;
24337 type = get_attr_type (insn);
24339 switch (type)
24341 case TYPE_MFCR:
24342 case TYPE_MFCRF:
24343 case TYPE_MTCR:
24344 case TYPE_DELAYED_CR:
24345 case TYPE_CR_LOGICAL:
24346 case TYPE_MTJMPR:
24347 case TYPE_MFJMPR:
24348 case TYPE_IDIV:
24349 case TYPE_LDIV:
24350 case TYPE_LOAD_L:
24351 case TYPE_STORE_C:
24352 case TYPE_ISYNC:
24353 case TYPE_SYNC:
24354 return true;
24355 default:
24356 break;
24358 break;
24359 case PROCESSOR_POWER6:
24360 type = get_attr_type (insn);
24362 switch (type)
24364 case TYPE_INSERT_DWORD:
24365 case TYPE_EXTS:
24366 case TYPE_CNTLZ:
24367 case TYPE_SHIFT:
24368 case TYPE_VAR_SHIFT_ROTATE:
24369 case TYPE_TRAP:
24370 case TYPE_IMUL:
24371 case TYPE_IMUL2:
24372 case TYPE_IMUL3:
24373 case TYPE_LMUL:
24374 case TYPE_IDIV:
24375 case TYPE_INSERT_WORD:
24376 case TYPE_DELAYED_COMPARE:
24377 case TYPE_IMUL_COMPARE:
24378 case TYPE_LMUL_COMPARE:
24379 case TYPE_FPCOMPARE:
24380 case TYPE_MFCR:
24381 case TYPE_MTCR:
24382 case TYPE_MFJMPR:
24383 case TYPE_MTJMPR:
24384 case TYPE_ISYNC:
24385 case TYPE_SYNC:
24386 case TYPE_LOAD_L:
24387 case TYPE_STORE_C:
24388 case TYPE_LOAD_U:
24389 case TYPE_LOAD_UX:
24390 case TYPE_LOAD_EXT_UX:
24391 case TYPE_STORE_U:
24392 case TYPE_STORE_UX:
24393 case TYPE_FPLOAD_U:
24394 case TYPE_FPLOAD_UX:
24395 case TYPE_FPSTORE_U:
24396 case TYPE_FPSTORE_UX:
24397 return true;
24398 default:
24399 break;
24401 break;
24402 case PROCESSOR_POWER7:
24403 type = get_attr_type (insn);
24405 switch (type)
24407 case TYPE_CR_LOGICAL:
24408 case TYPE_MFCR:
24409 case TYPE_MFCRF:
24410 case TYPE_MTCR:
24411 case TYPE_IDIV:
24412 case TYPE_LDIV:
24413 case TYPE_COMPARE:
24414 case TYPE_DELAYED_COMPARE:
24415 case TYPE_VAR_DELAYED_COMPARE:
24416 case TYPE_ISYNC:
24417 case TYPE_LOAD_L:
24418 case TYPE_STORE_C:
24419 case TYPE_LOAD_U:
24420 case TYPE_LOAD_UX:
24421 case TYPE_LOAD_EXT:
24422 case TYPE_LOAD_EXT_U:
24423 case TYPE_LOAD_EXT_UX:
24424 case TYPE_STORE_U:
24425 case TYPE_STORE_UX:
24426 case TYPE_FPLOAD_U:
24427 case TYPE_FPLOAD_UX:
24428 case TYPE_FPSTORE_U:
24429 case TYPE_FPSTORE_UX:
24430 case TYPE_MFJMPR:
24431 case TYPE_MTJMPR:
24432 return true;
24433 default:
24434 break;
24436 break;
24437 default:
24438 break;
24441 return false;
24444 static bool
24445 insn_must_be_last_in_group (rtx insn)
24447 enum attr_type type;
24449 if (!insn
24450 || GET_CODE (insn) == NOTE
24451 || DEBUG_INSN_P (insn)
24452 || GET_CODE (PATTERN (insn)) == USE
24453 || GET_CODE (PATTERN (insn)) == CLOBBER)
24454 return false;
24456 switch (rs6000_cpu) {
24457 case PROCESSOR_POWER4:
24458 case PROCESSOR_POWER5:
24459 if (is_microcoded_insn (insn))
24460 return true;
24462 if (is_branch_slot_insn (insn))
24463 return true;
24465 break;
24466 case PROCESSOR_POWER6:
24467 type = get_attr_type (insn);
24469 switch (type)
24471 case TYPE_EXTS:
24472 case TYPE_CNTLZ:
24473 case TYPE_SHIFT:
24474 case TYPE_VAR_SHIFT_ROTATE:
24475 case TYPE_TRAP:
24476 case TYPE_IMUL:
24477 case TYPE_IMUL2:
24478 case TYPE_IMUL3:
24479 case TYPE_LMUL:
24480 case TYPE_IDIV:
24481 case TYPE_DELAYED_COMPARE:
24482 case TYPE_IMUL_COMPARE:
24483 case TYPE_LMUL_COMPARE:
24484 case TYPE_FPCOMPARE:
24485 case TYPE_MFCR:
24486 case TYPE_MTCR:
24487 case TYPE_MFJMPR:
24488 case TYPE_MTJMPR:
24489 case TYPE_ISYNC:
24490 case TYPE_SYNC:
24491 case TYPE_LOAD_L:
24492 case TYPE_STORE_C:
24493 return true;
24494 default:
24495 break;
24497 break;
24498 case PROCESSOR_POWER7:
24499 type = get_attr_type (insn);
24501 switch (type)
24503 case TYPE_ISYNC:
24504 case TYPE_SYNC:
24505 case TYPE_LOAD_L:
24506 case TYPE_STORE_C:
24507 case TYPE_LOAD_EXT_U:
24508 case TYPE_LOAD_EXT_UX:
24509 case TYPE_STORE_UX:
24510 return true;
24511 default:
24512 break;
24514 break;
24515 default:
24516 break;
24519 return false;
24522 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
24523 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
24525 static bool
24526 is_costly_group (rtx *group_insns, rtx next_insn)
24528 int i;
24529 int issue_rate = rs6000_issue_rate ();
24531 for (i = 0; i < issue_rate; i++)
24533 sd_iterator_def sd_it;
24534 dep_t dep;
24535 rtx insn = group_insns[i];
24537 if (!insn)
24538 continue;
24540 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
24542 rtx next = DEP_CON (dep);
24544 if (next == next_insn
24545 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
24546 return true;
24550 return false;
24553 /* Utility of the function redefine_groups.
24554 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
24555 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
24556 to keep it "far" (in a separate group) from GROUP_INSNS, following
24557 one of the following schemes, depending on the value of the flag
24558 -minsert_sched_nops = X:
24559 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
24560 in order to force NEXT_INSN into a separate group.
24561 (2) X < sched_finish_regroup_exact: insert exactly X nops.
24562 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
24563 insertion (has a group just ended, how many vacant issue slots remain in the
24564 last group, and how many dispatch groups were encountered so far). */
24566 static int
24567 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
24568 rtx next_insn, bool *group_end, int can_issue_more,
24569 int *group_count)
24571 rtx nop;
24572 bool force;
24573 int issue_rate = rs6000_issue_rate ();
24574 bool end = *group_end;
24575 int i;
24577 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
24578 return can_issue_more;
24580 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
24581 return can_issue_more;
24583 force = is_costly_group (group_insns, next_insn);
24584 if (!force)
24585 return can_issue_more;
24587 if (sched_verbose > 6)
24588 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
24589 *group_count ,can_issue_more);
24591 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
24593 if (*group_end)
24594 can_issue_more = 0;
24596 /* Since only a branch can be issued in the last issue_slot, it is
24597 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
24598 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
24599 in this case the last nop will start a new group and the branch
24600 will be forced to the new group. */
24601 if (can_issue_more && !is_branch_slot_insn (next_insn))
24602 can_issue_more--;
24604 while (can_issue_more > 0)
24606 nop = gen_nop ();
24607 emit_insn_before (nop, next_insn);
24608 can_issue_more--;
24611 *group_end = true;
24612 return 0;
24615 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
24617 int n_nops = rs6000_sched_insert_nops;
24619 /* Nops can't be issued from the branch slot, so the effective
24620 issue_rate for nops is 'issue_rate - 1'. */
24621 if (can_issue_more == 0)
24622 can_issue_more = issue_rate;
24623 can_issue_more--;
24624 if (can_issue_more == 0)
24626 can_issue_more = issue_rate - 1;
24627 (*group_count)++;
24628 end = true;
24629 for (i = 0; i < issue_rate; i++)
24631 group_insns[i] = 0;
24635 while (n_nops > 0)
24637 nop = gen_nop ();
24638 emit_insn_before (nop, next_insn);
24639 if (can_issue_more == issue_rate - 1) /* new group begins */
24640 end = false;
24641 can_issue_more--;
24642 if (can_issue_more == 0)
24644 can_issue_more = issue_rate - 1;
24645 (*group_count)++;
24646 end = true;
24647 for (i = 0; i < issue_rate; i++)
24649 group_insns[i] = 0;
24652 n_nops--;
24655 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
24656 can_issue_more++;
24658 /* Is next_insn going to start a new group? */
24659 *group_end
24660 = (end
24661 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24662 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24663 || (can_issue_more < issue_rate &&
24664 insn_terminates_group_p (next_insn, previous_group)));
24665 if (*group_end && end)
24666 (*group_count)--;
24668 if (sched_verbose > 6)
24669 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
24670 *group_count, can_issue_more);
24671 return can_issue_more;
24674 return can_issue_more;
24677 /* This function tries to synch the dispatch groups that the compiler "sees"
24678 with the dispatch groups that the processor dispatcher is expected to
24679 form in practice. It tries to achieve this synchronization by forcing the
24680 estimated processor grouping on the compiler (as opposed to the function
24681 'pad_goups' which tries to force the scheduler's grouping on the processor).
24683 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
24684 examines the (estimated) dispatch groups that will be formed by the processor
24685 dispatcher. It marks these group boundaries to reflect the estimated
24686 processor grouping, overriding the grouping that the scheduler had marked.
24687 Depending on the value of the flag '-minsert-sched-nops' this function can
24688 force certain insns into separate groups or force a certain distance between
24689 them by inserting nops, for example, if there exists a "costly dependence"
24690 between the insns.
24692 The function estimates the group boundaries that the processor will form as
24693 follows: It keeps track of how many vacant issue slots are available after
24694 each insn. A subsequent insn will start a new group if one of the following
24695 4 cases applies:
24696 - no more vacant issue slots remain in the current dispatch group.
24697 - only the last issue slot, which is the branch slot, is vacant, but the next
24698 insn is not a branch.
24699 - only the last 2 or less issue slots, including the branch slot, are vacant,
24700 which means that a cracked insn (which occupies two issue slots) can't be
24701 issued in this group.
24702 - less than 'issue_rate' slots are vacant, and the next insn always needs to
24703 start a new group. */
24705 static int
24706 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24708 rtx insn, next_insn;
24709 int issue_rate;
24710 int can_issue_more;
24711 int slot, i;
24712 bool group_end;
24713 int group_count = 0;
24714 rtx *group_insns;
24716 /* Initialize. */
24717 issue_rate = rs6000_issue_rate ();
24718 group_insns = XALLOCAVEC (rtx, issue_rate);
24719 for (i = 0; i < issue_rate; i++)
24721 group_insns[i] = 0;
24723 can_issue_more = issue_rate;
24724 slot = 0;
24725 insn = get_next_active_insn (prev_head_insn, tail);
24726 group_end = false;
24728 while (insn != NULL_RTX)
24730 slot = (issue_rate - can_issue_more);
24731 group_insns[slot] = insn;
24732 can_issue_more =
24733 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24734 if (insn_terminates_group_p (insn, current_group))
24735 can_issue_more = 0;
24737 next_insn = get_next_active_insn (insn, tail);
24738 if (next_insn == NULL_RTX)
24739 return group_count + 1;
24741 /* Is next_insn going to start a new group? */
24742 group_end
24743 = (can_issue_more == 0
24744 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24745 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24746 || (can_issue_more < issue_rate &&
24747 insn_terminates_group_p (next_insn, previous_group)));
24749 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
24750 next_insn, &group_end, can_issue_more,
24751 &group_count);
24753 if (group_end)
24755 group_count++;
24756 can_issue_more = 0;
24757 for (i = 0; i < issue_rate; i++)
24759 group_insns[i] = 0;
24763 if (GET_MODE (next_insn) == TImode && can_issue_more)
24764 PUT_MODE (next_insn, VOIDmode);
24765 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
24766 PUT_MODE (next_insn, TImode);
24768 insn = next_insn;
24769 if (can_issue_more == 0)
24770 can_issue_more = issue_rate;
24771 } /* while */
24773 return group_count;
24776 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
24777 dispatch group boundaries that the scheduler had marked. Pad with nops
24778 any dispatch groups which have vacant issue slots, in order to force the
24779 scheduler's grouping on the processor dispatcher. The function
24780 returns the number of dispatch groups found. */
24782 static int
24783 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24785 rtx insn, next_insn;
24786 rtx nop;
24787 int issue_rate;
24788 int can_issue_more;
24789 int group_end;
24790 int group_count = 0;
24792 /* Initialize issue_rate. */
24793 issue_rate = rs6000_issue_rate ();
24794 can_issue_more = issue_rate;
24796 insn = get_next_active_insn (prev_head_insn, tail);
24797 next_insn = get_next_active_insn (insn, tail);
24799 while (insn != NULL_RTX)
24801 can_issue_more =
24802 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24804 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
24806 if (next_insn == NULL_RTX)
24807 break;
24809 if (group_end)
24811 /* If the scheduler had marked group termination at this location
24812 (between insn and next_insn), and neither insn nor next_insn will
24813 force group termination, pad the group with nops to force group
24814 termination. */
24815 if (can_issue_more
24816 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
24817 && !insn_terminates_group_p (insn, current_group)
24818 && !insn_terminates_group_p (next_insn, previous_group))
24820 if (!is_branch_slot_insn (next_insn))
24821 can_issue_more--;
24823 while (can_issue_more)
24825 nop = gen_nop ();
24826 emit_insn_before (nop, next_insn);
24827 can_issue_more--;
24831 can_issue_more = issue_rate;
24832 group_count++;
24835 insn = next_insn;
24836 next_insn = get_next_active_insn (insn, tail);
24839 return group_count;
24842 /* We're beginning a new block. Initialize data structures as necessary. */
24844 static void
24845 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
24846 int sched_verbose ATTRIBUTE_UNUSED,
24847 int max_ready ATTRIBUTE_UNUSED)
24849 last_scheduled_insn = NULL_RTX;
24850 load_store_pendulum = 0;
24853 /* The following function is called at the end of scheduling BB.
24854 After reload, it inserts nops at insn group bundling. */
24856 static void
24857 rs6000_sched_finish (FILE *dump, int sched_verbose)
24859 int n_groups;
24861 if (sched_verbose)
24862 fprintf (dump, "=== Finishing schedule.\n");
24864 if (reload_completed && rs6000_sched_groups)
24866 /* Do not run sched_finish hook when selective scheduling enabled. */
24867 if (sel_sched_p ())
24868 return;
24870 if (rs6000_sched_insert_nops == sched_finish_none)
24871 return;
24873 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
24874 n_groups = pad_groups (dump, sched_verbose,
24875 current_sched_info->prev_head,
24876 current_sched_info->next_tail);
24877 else
24878 n_groups = redefine_groups (dump, sched_verbose,
24879 current_sched_info->prev_head,
24880 current_sched_info->next_tail);
24882 if (sched_verbose >= 6)
24884 fprintf (dump, "ngroups = %d\n", n_groups);
24885 print_rtl (dump, current_sched_info->prev_head);
24886 fprintf (dump, "Done finish_sched\n");
24891 struct _rs6000_sched_context
24893 short cached_can_issue_more;
24894 rtx last_scheduled_insn;
24895 int load_store_pendulum;
24898 typedef struct _rs6000_sched_context rs6000_sched_context_def;
24899 typedef rs6000_sched_context_def *rs6000_sched_context_t;
24901 /* Allocate store for new scheduling context. */
24902 static void *
24903 rs6000_alloc_sched_context (void)
24905 return xmalloc (sizeof (rs6000_sched_context_def));
24908 /* If CLEAN_P is true then initializes _SC with clean data,
24909 and from the global context otherwise. */
24910 static void
24911 rs6000_init_sched_context (void *_sc, bool clean_p)
24913 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24915 if (clean_p)
24917 sc->cached_can_issue_more = 0;
24918 sc->last_scheduled_insn = NULL_RTX;
24919 sc->load_store_pendulum = 0;
24921 else
24923 sc->cached_can_issue_more = cached_can_issue_more;
24924 sc->last_scheduled_insn = last_scheduled_insn;
24925 sc->load_store_pendulum = load_store_pendulum;
24929 /* Sets the global scheduling context to the one pointed to by _SC. */
24930 static void
24931 rs6000_set_sched_context (void *_sc)
24933 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24935 gcc_assert (sc != NULL);
24937 cached_can_issue_more = sc->cached_can_issue_more;
24938 last_scheduled_insn = sc->last_scheduled_insn;
24939 load_store_pendulum = sc->load_store_pendulum;
24942 /* Free _SC. */
24943 static void
24944 rs6000_free_sched_context (void *_sc)
24946 gcc_assert (_sc != NULL);
24948 free (_sc);
24952 /* Length in units of the trampoline for entering a nested function. */
24955 rs6000_trampoline_size (void)
24957 int ret = 0;
24959 switch (DEFAULT_ABI)
24961 default:
24962 gcc_unreachable ();
24964 case ABI_AIX:
24965 ret = (TARGET_32BIT) ? 12 : 24;
24966 break;
24968 case ABI_DARWIN:
24969 case ABI_V4:
24970 ret = (TARGET_32BIT) ? 40 : 48;
24971 break;
24974 return ret;
24977 /* Emit RTL insns to initialize the variable parts of a trampoline.
24978 FNADDR is an RTX for the address of the function's pure code.
24979 CXT is an RTX for the static chain value for the function. */
24981 static void
24982 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
24984 int regsize = (TARGET_32BIT) ? 4 : 8;
24985 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
24986 rtx ctx_reg = force_reg (Pmode, cxt);
24987 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
24989 switch (DEFAULT_ABI)
24991 default:
24992 gcc_unreachable ();
24994 /* Under AIX, just build the 3 word function descriptor */
24995 case ABI_AIX:
24997 rtx fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
24998 rtx fn_reg = gen_reg_rtx (Pmode);
24999 rtx toc_reg = gen_reg_rtx (Pmode);
25001 /* Macro to shorten the code expansions below. */
25002 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
25004 m_tramp = replace_equiv_address (m_tramp, addr);
25006 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
25007 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
25008 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
25009 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
25010 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
25012 # undef MEM_PLUS
25014 break;
25016 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
25017 case ABI_DARWIN:
25018 case ABI_V4:
25019 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
25020 LCT_NORMAL, VOIDmode, 4,
25021 addr, Pmode,
25022 GEN_INT (rs6000_trampoline_size ()), SImode,
25023 fnaddr, Pmode,
25024 ctx_reg, Pmode);
25025 break;
25030 /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
25031 identifier as an argument, so the front end shouldn't look it up. */
25033 static bool
25034 rs6000_attribute_takes_identifier_p (const_tree attr_id)
25036 return is_attribute_p ("altivec", attr_id);
25039 /* Handle the "altivec" attribute. The attribute may have
25040 arguments as follows:
25042 __attribute__((altivec(vector__)))
25043 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
25044 __attribute__((altivec(bool__))) (always followed by 'unsigned')
25046 and may appear more than once (e.g., 'vector bool char') in a
25047 given declaration. */
25049 static tree
25050 rs6000_handle_altivec_attribute (tree *node,
25051 tree name ATTRIBUTE_UNUSED,
25052 tree args,
25053 int flags ATTRIBUTE_UNUSED,
25054 bool *no_add_attrs)
25056 tree type = *node, result = NULL_TREE;
25057 enum machine_mode mode;
25058 int unsigned_p;
25059 char altivec_type
25060 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
25061 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
25062 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
25063 : '?');
25065 while (POINTER_TYPE_P (type)
25066 || TREE_CODE (type) == FUNCTION_TYPE
25067 || TREE_CODE (type) == METHOD_TYPE
25068 || TREE_CODE (type) == ARRAY_TYPE)
25069 type = TREE_TYPE (type);
25071 mode = TYPE_MODE (type);
25073 /* Check for invalid AltiVec type qualifiers. */
25074 if (type == long_double_type_node)
25075 error ("use of %<long double%> in AltiVec types is invalid");
25076 else if (type == boolean_type_node)
25077 error ("use of boolean types in AltiVec types is invalid");
25078 else if (TREE_CODE (type) == COMPLEX_TYPE)
25079 error ("use of %<complex%> in AltiVec types is invalid");
25080 else if (DECIMAL_FLOAT_MODE_P (mode))
25081 error ("use of decimal floating point types in AltiVec types is invalid");
25082 else if (!TARGET_VSX)
25084 if (type == long_unsigned_type_node || type == long_integer_type_node)
25086 if (TARGET_64BIT)
25087 error ("use of %<long%> in AltiVec types is invalid for "
25088 "64-bit code without -mvsx");
25089 else if (rs6000_warn_altivec_long)
25090 warning (0, "use of %<long%> in AltiVec types is deprecated; "
25091 "use %<int%>");
25093 else if (type == long_long_unsigned_type_node
25094 || type == long_long_integer_type_node)
25095 error ("use of %<long long%> in AltiVec types is invalid without "
25096 "-mvsx");
25097 else if (type == double_type_node)
25098 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
25101 switch (altivec_type)
25103 case 'v':
25104 unsigned_p = TYPE_UNSIGNED (type);
25105 switch (mode)
25107 case DImode:
25108 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
25109 break;
25110 case SImode:
25111 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
25112 break;
25113 case HImode:
25114 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
25115 break;
25116 case QImode:
25117 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
25118 break;
25119 case SFmode: result = V4SF_type_node; break;
25120 case DFmode: result = V2DF_type_node; break;
25121 /* If the user says 'vector int bool', we may be handed the 'bool'
25122 attribute _before_ the 'vector' attribute, and so select the
25123 proper type in the 'b' case below. */
25124 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
25125 case V2DImode: case V2DFmode:
25126 result = type;
25127 default: break;
25129 break;
25130 case 'b':
25131 switch (mode)
25133 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
25134 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
25135 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
25136 case QImode: case V16QImode: result = bool_V16QI_type_node;
25137 default: break;
25139 break;
25140 case 'p':
25141 switch (mode)
25143 case V8HImode: result = pixel_V8HI_type_node;
25144 default: break;
25146 default: break;
25149 /* Propagate qualifiers attached to the element type
25150 onto the vector type. */
25151 if (result && result != type && TYPE_QUALS (type))
25152 result = build_qualified_type (result, TYPE_QUALS (type));
25154 *no_add_attrs = true; /* No need to hang on to the attribute. */
25156 if (result)
25157 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
25159 return NULL_TREE;
25162 /* AltiVec defines four built-in scalar types that serve as vector
25163 elements; we must teach the compiler how to mangle them. */
25165 static const char *
25166 rs6000_mangle_type (const_tree type)
25168 type = TYPE_MAIN_VARIANT (type);
25170 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
25171 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
25172 return NULL;
25174 if (type == bool_char_type_node) return "U6__boolc";
25175 if (type == bool_short_type_node) return "U6__bools";
25176 if (type == pixel_type_node) return "u7__pixel";
25177 if (type == bool_int_type_node) return "U6__booli";
25178 if (type == bool_long_type_node) return "U6__booll";
25180 /* Mangle IBM extended float long double as `g' (__float128) on
25181 powerpc*-linux where long-double-64 previously was the default. */
25182 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
25183 && TARGET_ELF
25184 && TARGET_LONG_DOUBLE_128
25185 && !TARGET_IEEEQUAD)
25186 return "g";
25188 /* For all other types, use normal C++ mangling. */
25189 return NULL;
25192 /* Handle a "longcall" or "shortcall" attribute; arguments as in
25193 struct attribute_spec.handler. */
25195 static tree
25196 rs6000_handle_longcall_attribute (tree *node, tree name,
25197 tree args ATTRIBUTE_UNUSED,
25198 int flags ATTRIBUTE_UNUSED,
25199 bool *no_add_attrs)
25201 if (TREE_CODE (*node) != FUNCTION_TYPE
25202 && TREE_CODE (*node) != FIELD_DECL
25203 && TREE_CODE (*node) != TYPE_DECL)
25205 warning (OPT_Wattributes, "%qE attribute only applies to functions",
25206 name);
25207 *no_add_attrs = true;
25210 return NULL_TREE;
25213 /* Set longcall attributes on all functions declared when
25214 rs6000_default_long_calls is true. */
25215 static void
25216 rs6000_set_default_type_attributes (tree type)
25218 if (rs6000_default_long_calls
25219 && (TREE_CODE (type) == FUNCTION_TYPE
25220 || TREE_CODE (type) == METHOD_TYPE))
25221 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
25222 NULL_TREE,
25223 TYPE_ATTRIBUTES (type));
25225 #if TARGET_MACHO
25226 darwin_set_default_type_attributes (type);
25227 #endif
25230 /* Return a reference suitable for calling a function with the
25231 longcall attribute. */
25234 rs6000_longcall_ref (rtx call_ref)
25236 const char *call_name;
25237 tree node;
25239 if (GET_CODE (call_ref) != SYMBOL_REF)
25240 return call_ref;
25242 /* System V adds '.' to the internal name, so skip them. */
25243 call_name = XSTR (call_ref, 0);
25244 if (*call_name == '.')
25246 while (*call_name == '.')
25247 call_name++;
25249 node = get_identifier (call_name);
25250 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
25253 return force_reg (Pmode, call_ref);
25256 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
25257 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
25258 #endif
25260 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
25261 struct attribute_spec.handler. */
25262 static tree
25263 rs6000_handle_struct_attribute (tree *node, tree name,
25264 tree args ATTRIBUTE_UNUSED,
25265 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
25267 tree *type = NULL;
25268 if (DECL_P (*node))
25270 if (TREE_CODE (*node) == TYPE_DECL)
25271 type = &TREE_TYPE (*node);
25273 else
25274 type = node;
25276 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
25277 || TREE_CODE (*type) == UNION_TYPE)))
25279 warning (OPT_Wattributes, "%qE attribute ignored", name);
25280 *no_add_attrs = true;
25283 else if ((is_attribute_p ("ms_struct", name)
25284 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
25285 || ((is_attribute_p ("gcc_struct", name)
25286 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
25288 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
25289 name);
25290 *no_add_attrs = true;
25293 return NULL_TREE;
25296 static bool
25297 rs6000_ms_bitfield_layout_p (const_tree record_type)
25299 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
25300 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
25301 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
25304 #ifdef USING_ELFOS_H
25306 /* A get_unnamed_section callback, used for switching to toc_section. */
25308 static void
25309 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
25311 if (DEFAULT_ABI == ABI_AIX
25312 && TARGET_MINIMAL_TOC
25313 && !TARGET_RELOCATABLE)
25315 if (!toc_initialized)
25317 toc_initialized = 1;
25318 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
25319 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
25320 fprintf (asm_out_file, "\t.tc ");
25321 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
25322 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
25323 fprintf (asm_out_file, "\n");
25325 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25326 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
25327 fprintf (asm_out_file, " = .+32768\n");
25329 else
25330 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25332 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
25333 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
25334 else
25336 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25337 if (!toc_initialized)
25339 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
25340 fprintf (asm_out_file, " = .+32768\n");
25341 toc_initialized = 1;
25346 /* Implement TARGET_ASM_INIT_SECTIONS. */
25348 static void
25349 rs6000_elf_asm_init_sections (void)
25351 toc_section
25352 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
25354 sdata2_section
25355 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
25356 SDATA2_SECTION_ASM_OP);
25359 /* Implement TARGET_SELECT_RTX_SECTION. */
25361 static section *
25362 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
25363 unsigned HOST_WIDE_INT align)
25365 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
25366 return toc_section;
25367 else
25368 return default_elf_select_rtx_section (mode, x, align);
25371 /* For a SYMBOL_REF, set generic flags and then perform some
25372 target-specific processing.
25374 When the AIX ABI is requested on a non-AIX system, replace the
25375 function name with the real name (with a leading .) rather than the
25376 function descriptor name. This saves a lot of overriding code to
25377 read the prefixes. */
25379 static void
25380 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
25382 default_encode_section_info (decl, rtl, first);
25384 if (first
25385 && TREE_CODE (decl) == FUNCTION_DECL
25386 && !TARGET_AIX
25387 && DEFAULT_ABI == ABI_AIX)
25389 rtx sym_ref = XEXP (rtl, 0);
25390 size_t len = strlen (XSTR (sym_ref, 0));
25391 char *str = XALLOCAVEC (char, len + 2);
25392 str[0] = '.';
25393 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
25394 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
25398 static inline bool
25399 compare_section_name (const char *section, const char *templ)
25401 int len;
25403 len = strlen (templ);
25404 return (strncmp (section, templ, len) == 0
25405 && (section[len] == 0 || section[len] == '.'));
25408 bool
25409 rs6000_elf_in_small_data_p (const_tree decl)
25411 if (rs6000_sdata == SDATA_NONE)
25412 return false;
25414 /* We want to merge strings, so we never consider them small data. */
25415 if (TREE_CODE (decl) == STRING_CST)
25416 return false;
25418 /* Functions are never in the small data area. */
25419 if (TREE_CODE (decl) == FUNCTION_DECL)
25420 return false;
25422 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
25424 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
25425 if (compare_section_name (section, ".sdata")
25426 || compare_section_name (section, ".sdata2")
25427 || compare_section_name (section, ".gnu.linkonce.s")
25428 || compare_section_name (section, ".sbss")
25429 || compare_section_name (section, ".sbss2")
25430 || compare_section_name (section, ".gnu.linkonce.sb")
25431 || strcmp (section, ".PPC.EMB.sdata0") == 0
25432 || strcmp (section, ".PPC.EMB.sbss0") == 0)
25433 return true;
25435 else
25437 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
25439 if (size > 0
25440 && size <= g_switch_value
25441 /* If it's not public, and we're not going to reference it there,
25442 there's no need to put it in the small data section. */
25443 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
25444 return true;
25447 return false;
25450 #endif /* USING_ELFOS_H */
25452 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
25454 static bool
25455 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
25457 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
25460 /* Return a REG that occurs in ADDR with coefficient 1.
25461 ADDR can be effectively incremented by incrementing REG.
25463 r0 is special and we must not select it as an address
25464 register by this routine since our caller will try to
25465 increment the returned register via an "la" instruction. */
25468 find_addr_reg (rtx addr)
25470 while (GET_CODE (addr) == PLUS)
25472 if (GET_CODE (XEXP (addr, 0)) == REG
25473 && REGNO (XEXP (addr, 0)) != 0)
25474 addr = XEXP (addr, 0);
25475 else if (GET_CODE (XEXP (addr, 1)) == REG
25476 && REGNO (XEXP (addr, 1)) != 0)
25477 addr = XEXP (addr, 1);
25478 else if (CONSTANT_P (XEXP (addr, 0)))
25479 addr = XEXP (addr, 1);
25480 else if (CONSTANT_P (XEXP (addr, 1)))
25481 addr = XEXP (addr, 0);
25482 else
25483 gcc_unreachable ();
25485 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
25486 return addr;
25489 void
25490 rs6000_fatal_bad_address (rtx op)
25492 fatal_insn ("bad address", op);
25495 #if TARGET_MACHO
25497 typedef struct branch_island_d {
25498 tree function_name;
25499 tree label_name;
25500 int line_number;
25501 } branch_island;
25503 DEF_VEC_O(branch_island);
25504 DEF_VEC_ALLOC_O(branch_island,gc);
25506 static VEC(branch_island,gc) *branch_islands;
25508 /* Remember to generate a branch island for far calls to the given
25509 function. */
25511 static void
25512 add_compiler_branch_island (tree label_name, tree function_name,
25513 int line_number)
25515 branch_island *bi = VEC_safe_push (branch_island, gc, branch_islands, NULL);
25517 bi->function_name = function_name;
25518 bi->label_name = label_name;
25519 bi->line_number = line_number;
25522 /* Generate far-jump branch islands for everything recorded in
25523 branch_islands. Invoked immediately after the last instruction of
25524 the epilogue has been emitted; the branch islands must be appended
25525 to, and contiguous with, the function body. Mach-O stubs are
25526 generated in machopic_output_stub(). */
25528 static void
25529 macho_branch_islands (void)
25531 char tmp_buf[512];
25533 while (!VEC_empty (branch_island, branch_islands))
25535 branch_island *bi = VEC_last (branch_island, branch_islands);
25536 const char *label = IDENTIFIER_POINTER (bi->label_name);
25537 const char *name = IDENTIFIER_POINTER (bi->function_name);
25538 char name_buf[512];
25539 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
25540 if (name[0] == '*' || name[0] == '&')
25541 strcpy (name_buf, name+1);
25542 else
25544 name_buf[0] = '_';
25545 strcpy (name_buf+1, name);
25547 strcpy (tmp_buf, "\n");
25548 strcat (tmp_buf, label);
25549 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25550 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25551 dbxout_stabd (N_SLINE, bi->line_number);
25552 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25553 if (flag_pic)
25555 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
25556 strcat (tmp_buf, label);
25557 strcat (tmp_buf, "_pic\n");
25558 strcat (tmp_buf, label);
25559 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
25561 strcat (tmp_buf, "\taddis r11,r11,ha16(");
25562 strcat (tmp_buf, name_buf);
25563 strcat (tmp_buf, " - ");
25564 strcat (tmp_buf, label);
25565 strcat (tmp_buf, "_pic)\n");
25567 strcat (tmp_buf, "\tmtlr r0\n");
25569 strcat (tmp_buf, "\taddi r12,r11,lo16(");
25570 strcat (tmp_buf, name_buf);
25571 strcat (tmp_buf, " - ");
25572 strcat (tmp_buf, label);
25573 strcat (tmp_buf, "_pic)\n");
25575 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
25577 else
25579 strcat (tmp_buf, ":\nlis r12,hi16(");
25580 strcat (tmp_buf, name_buf);
25581 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
25582 strcat (tmp_buf, name_buf);
25583 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
25585 output_asm_insn (tmp_buf, 0);
25586 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25587 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25588 dbxout_stabd (N_SLINE, bi->line_number);
25589 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25590 VEC_pop (branch_island, branch_islands);
25594 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
25595 already there or not. */
25597 static int
25598 no_previous_def (tree function_name)
25600 branch_island *bi;
25601 unsigned ix;
25603 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25604 if (function_name == bi->function_name)
25605 return 0;
25606 return 1;
25609 /* GET_PREV_LABEL gets the label name from the previous definition of
25610 the function. */
25612 static tree
25613 get_prev_label (tree function_name)
25615 branch_island *bi;
25616 unsigned ix;
25618 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25619 if (function_name == bi->function_name)
25620 return bi->label_name;
25621 return NULL_TREE;
25624 /* INSN is either a function call or a millicode call. It may have an
25625 unconditional jump in its delay slot.
25627 CALL_DEST is the routine we are calling. */
25629 char *
25630 output_call (rtx insn, rtx *operands, int dest_operand_number,
25631 int cookie_operand_number)
25633 static char buf[256];
25634 if (darwin_emit_branch_islands
25635 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
25636 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
25638 tree labelname;
25639 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
25641 if (no_previous_def (funname))
25643 rtx label_rtx = gen_label_rtx ();
25644 char *label_buf, temp_buf[256];
25645 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
25646 CODE_LABEL_NUMBER (label_rtx));
25647 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
25648 labelname = get_identifier (label_buf);
25649 add_compiler_branch_island (labelname, funname, insn_line (insn));
25651 else
25652 labelname = get_prev_label (funname);
25654 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
25655 instruction will reach 'foo', otherwise link as 'bl L42'".
25656 "L42" should be a 'branch island', that will do a far jump to
25657 'foo'. Branch islands are generated in
25658 macho_branch_islands(). */
25659 sprintf (buf, "jbsr %%z%d,%.246s",
25660 dest_operand_number, IDENTIFIER_POINTER (labelname));
25662 else
25663 sprintf (buf, "bl %%z%d", dest_operand_number);
25664 return buf;
25667 /* Generate PIC and indirect symbol stubs. */
25669 void
25670 machopic_output_stub (FILE *file, const char *symb, const char *stub)
25672 unsigned int length;
25673 char *symbol_name, *lazy_ptr_name;
25674 char *local_label_0;
25675 static int label = 0;
25677 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
25678 symb = (*targetm.strip_name_encoding) (symb);
25681 length = strlen (symb);
25682 symbol_name = XALLOCAVEC (char, length + 32);
25683 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
25685 lazy_ptr_name = XALLOCAVEC (char, length + 32);
25686 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
25688 if (flag_pic == 2)
25689 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
25690 else
25691 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
25693 if (flag_pic == 2)
25695 fprintf (file, "\t.align 5\n");
25697 fprintf (file, "%s:\n", stub);
25698 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25700 label++;
25701 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
25702 sprintf (local_label_0, "\"L%011d$spb\"", label);
25704 fprintf (file, "\tmflr r0\n");
25705 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
25706 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
25707 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
25708 lazy_ptr_name, local_label_0);
25709 fprintf (file, "\tmtlr r0\n");
25710 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
25711 (TARGET_64BIT ? "ldu" : "lwzu"),
25712 lazy_ptr_name, local_label_0);
25713 fprintf (file, "\tmtctr r12\n");
25714 fprintf (file, "\tbctr\n");
25716 else
25718 fprintf (file, "\t.align 4\n");
25720 fprintf (file, "%s:\n", stub);
25721 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25723 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
25724 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
25725 (TARGET_64BIT ? "ldu" : "lwzu"),
25726 lazy_ptr_name);
25727 fprintf (file, "\tmtctr r12\n");
25728 fprintf (file, "\tbctr\n");
25731 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
25732 fprintf (file, "%s:\n", lazy_ptr_name);
25733 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25734 fprintf (file, "%sdyld_stub_binding_helper\n",
25735 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
25738 /* Legitimize PIC addresses. If the address is already
25739 position-independent, we return ORIG. Newly generated
25740 position-independent addresses go into a reg. This is REG if non
25741 zero, otherwise we allocate register(s) as necessary. */
25743 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
25746 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
25747 rtx reg)
25749 rtx base, offset;
25751 if (reg == NULL && ! reload_in_progress && ! reload_completed)
25752 reg = gen_reg_rtx (Pmode);
25754 if (GET_CODE (orig) == CONST)
25756 rtx reg_temp;
25758 if (GET_CODE (XEXP (orig, 0)) == PLUS
25759 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
25760 return orig;
25762 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
25764 /* Use a different reg for the intermediate value, as
25765 it will be marked UNCHANGING. */
25766 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
25767 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
25768 Pmode, reg_temp);
25769 offset =
25770 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
25771 Pmode, reg);
25773 if (GET_CODE (offset) == CONST_INT)
25775 if (SMALL_INT (offset))
25776 return plus_constant (base, INTVAL (offset));
25777 else if (! reload_in_progress && ! reload_completed)
25778 offset = force_reg (Pmode, offset);
25779 else
25781 rtx mem = force_const_mem (Pmode, orig);
25782 return machopic_legitimize_pic_address (mem, Pmode, reg);
25785 return gen_rtx_PLUS (Pmode, base, offset);
25788 /* Fall back on generic machopic code. */
25789 return machopic_legitimize_pic_address (orig, mode, reg);
25792 /* Output a .machine directive for the Darwin assembler, and call
25793 the generic start_file routine. */
25795 static void
25796 rs6000_darwin_file_start (void)
25798 static const struct
25800 const char *arg;
25801 const char *name;
25802 int if_set;
25803 } mapping[] = {
25804 { "ppc64", "ppc64", MASK_64BIT },
25805 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
25806 { "power4", "ppc970", 0 },
25807 { "G5", "ppc970", 0 },
25808 { "7450", "ppc7450", 0 },
25809 { "7400", "ppc7400", MASK_ALTIVEC },
25810 { "G4", "ppc7400", 0 },
25811 { "750", "ppc750", 0 },
25812 { "740", "ppc750", 0 },
25813 { "G3", "ppc750", 0 },
25814 { "604e", "ppc604e", 0 },
25815 { "604", "ppc604", 0 },
25816 { "603e", "ppc603", 0 },
25817 { "603", "ppc603", 0 },
25818 { "601", "ppc601", 0 },
25819 { NULL, "ppc", 0 } };
25820 const char *cpu_id = "";
25821 size_t i;
25823 rs6000_file_start ();
25824 darwin_file_start ();
25826 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
25827 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
25828 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
25829 && rs6000_select[i].string[0] != '\0')
25830 cpu_id = rs6000_select[i].string;
25832 /* Look through the mapping array. Pick the first name that either
25833 matches the argument, has a bit set in IF_SET that is also set
25834 in the target flags, or has a NULL name. */
25836 i = 0;
25837 while (mapping[i].arg != NULL
25838 && strcmp (mapping[i].arg, cpu_id) != 0
25839 && (mapping[i].if_set & target_flags) == 0)
25840 i++;
25842 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
25845 #endif /* TARGET_MACHO */
25847 #if TARGET_ELF
25848 static int
25849 rs6000_elf_reloc_rw_mask (void)
25851 if (flag_pic)
25852 return 3;
25853 else if (DEFAULT_ABI == ABI_AIX)
25854 return 2;
25855 else
25856 return 0;
25859 /* Record an element in the table of global constructors. SYMBOL is
25860 a SYMBOL_REF of the function to be called; PRIORITY is a number
25861 between 0 and MAX_INIT_PRIORITY.
25863 This differs from default_named_section_asm_out_constructor in
25864 that we have special handling for -mrelocatable. */
25866 static void
25867 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
25869 const char *section = ".ctors";
25870 char buf[16];
25872 if (priority != DEFAULT_INIT_PRIORITY)
25874 sprintf (buf, ".ctors.%.5u",
25875 /* Invert the numbering so the linker puts us in the proper
25876 order; constructors are run from right to left, and the
25877 linker sorts in increasing order. */
25878 MAX_INIT_PRIORITY - priority);
25879 section = buf;
25882 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25883 assemble_align (POINTER_SIZE);
25885 if (TARGET_RELOCATABLE)
25887 fputs ("\t.long (", asm_out_file);
25888 output_addr_const (asm_out_file, symbol);
25889 fputs (")@fixup\n", asm_out_file);
25891 else
25892 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25895 static void
25896 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
25898 const char *section = ".dtors";
25899 char buf[16];
25901 if (priority != DEFAULT_INIT_PRIORITY)
25903 sprintf (buf, ".dtors.%.5u",
25904 /* Invert the numbering so the linker puts us in the proper
25905 order; constructors are run from right to left, and the
25906 linker sorts in increasing order. */
25907 MAX_INIT_PRIORITY - priority);
25908 section = buf;
25911 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25912 assemble_align (POINTER_SIZE);
25914 if (TARGET_RELOCATABLE)
25916 fputs ("\t.long (", asm_out_file);
25917 output_addr_const (asm_out_file, symbol);
25918 fputs (")@fixup\n", asm_out_file);
25920 else
25921 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25924 void
25925 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
25927 if (TARGET_64BIT)
25929 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
25930 ASM_OUTPUT_LABEL (file, name);
25931 fputs (DOUBLE_INT_ASM_OP, file);
25932 rs6000_output_function_entry (file, name);
25933 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
25934 if (DOT_SYMBOLS)
25936 fputs ("\t.size\t", file);
25937 assemble_name (file, name);
25938 fputs (",24\n\t.type\t.", file);
25939 assemble_name (file, name);
25940 fputs (",@function\n", file);
25941 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
25943 fputs ("\t.globl\t.", file);
25944 assemble_name (file, name);
25945 putc ('\n', file);
25948 else
25949 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25950 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25951 rs6000_output_function_entry (file, name);
25952 fputs (":\n", file);
25953 return;
25956 if (TARGET_RELOCATABLE
25957 && !TARGET_SECURE_PLT
25958 && (get_pool_size () != 0 || crtl->profile)
25959 && uses_TOC ())
25961 char buf[256];
25963 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
25965 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
25966 fprintf (file, "\t.long ");
25967 assemble_name (file, buf);
25968 putc ('-', file);
25969 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
25970 assemble_name (file, buf);
25971 putc ('\n', file);
25974 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25975 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25977 if (DEFAULT_ABI == ABI_AIX)
25979 const char *desc_name, *orig_name;
25981 orig_name = (*targetm.strip_name_encoding) (name);
25982 desc_name = orig_name;
25983 while (*desc_name == '.')
25984 desc_name++;
25986 if (TREE_PUBLIC (decl))
25987 fprintf (file, "\t.globl %s\n", desc_name);
25989 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25990 fprintf (file, "%s:\n", desc_name);
25991 fprintf (file, "\t.long %s\n", orig_name);
25992 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
25993 if (DEFAULT_ABI == ABI_AIX)
25994 fputs ("\t.long 0\n", file);
25995 fprintf (file, "\t.previous\n");
25997 ASM_OUTPUT_LABEL (file, name);
26000 static void
26001 rs6000_elf_file_end (void)
26003 #ifdef HAVE_AS_GNU_ATTRIBUTE
26004 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
26006 if (rs6000_passes_float)
26007 fprintf (asm_out_file, "\t.gnu_attribute 4, %d\n",
26008 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
26009 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
26010 : 2));
26011 if (rs6000_passes_vector)
26012 fprintf (asm_out_file, "\t.gnu_attribute 8, %d\n",
26013 (TARGET_ALTIVEC_ABI ? 2
26014 : TARGET_SPE_ABI ? 3
26015 : 1));
26016 if (rs6000_returns_struct)
26017 fprintf (asm_out_file, "\t.gnu_attribute 12, %d\n",
26018 aix_struct_return ? 2 : 1);
26020 #endif
26021 #ifdef POWERPC_LINUX
26022 if (TARGET_32BIT)
26023 file_end_indicate_exec_stack ();
26024 #endif
26026 #endif
26028 #if TARGET_XCOFF
26029 static void
26030 rs6000_xcoff_asm_output_anchor (rtx symbol)
26032 char buffer[100];
26034 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
26035 SYMBOL_REF_BLOCK_OFFSET (symbol));
26036 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
26039 static void
26040 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
26042 fputs (GLOBAL_ASM_OP, stream);
26043 RS6000_OUTPUT_BASENAME (stream, name);
26044 putc ('\n', stream);
26047 /* A get_unnamed_decl callback, used for read-only sections. PTR
26048 points to the section string variable. */
26050 static void
26051 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
26053 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
26054 *(const char *const *) directive,
26055 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
26058 /* Likewise for read-write sections. */
26060 static void
26061 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
26063 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
26064 *(const char *const *) directive,
26065 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
26068 /* A get_unnamed_section callback, used for switching to toc_section. */
26070 static void
26071 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
26073 if (TARGET_MINIMAL_TOC)
26075 /* toc_section is always selected at least once from
26076 rs6000_xcoff_file_start, so this is guaranteed to
26077 always be defined once and only once in each file. */
26078 if (!toc_initialized)
26080 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
26081 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
26082 toc_initialized = 1;
26084 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
26085 (TARGET_32BIT ? "" : ",3"));
26087 else
26088 fputs ("\t.toc\n", asm_out_file);
26091 /* Implement TARGET_ASM_INIT_SECTIONS. */
26093 static void
26094 rs6000_xcoff_asm_init_sections (void)
26096 read_only_data_section
26097 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
26098 &xcoff_read_only_section_name);
26100 private_data_section
26101 = get_unnamed_section (SECTION_WRITE,
26102 rs6000_xcoff_output_readwrite_section_asm_op,
26103 &xcoff_private_data_section_name);
26105 read_only_private_data_section
26106 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
26107 &xcoff_private_data_section_name);
26109 toc_section
26110 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
26112 readonly_data_section = read_only_data_section;
26113 exception_section = data_section;
26116 static int
26117 rs6000_xcoff_reloc_rw_mask (void)
26119 return 3;
26122 static void
26123 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
26124 tree decl ATTRIBUTE_UNUSED)
26126 int smclass;
26127 static const char * const suffix[3] = { "PR", "RO", "RW" };
26129 if (flags & SECTION_CODE)
26130 smclass = 0;
26131 else if (flags & SECTION_WRITE)
26132 smclass = 2;
26133 else
26134 smclass = 1;
26136 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
26137 (flags & SECTION_CODE) ? "." : "",
26138 name, suffix[smclass], flags & SECTION_ENTSIZE);
26141 static section *
26142 rs6000_xcoff_select_section (tree decl, int reloc,
26143 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
26145 if (decl_readonly_section (decl, reloc))
26147 if (TREE_PUBLIC (decl))
26148 return read_only_data_section;
26149 else
26150 return read_only_private_data_section;
26152 else
26154 if (TREE_PUBLIC (decl))
26155 return data_section;
26156 else
26157 return private_data_section;
26161 static void
26162 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
26164 const char *name;
26166 /* Use select_section for private and uninitialized data. */
26167 if (!TREE_PUBLIC (decl)
26168 || DECL_COMMON (decl)
26169 || DECL_INITIAL (decl) == NULL_TREE
26170 || DECL_INITIAL (decl) == error_mark_node
26171 || (flag_zero_initialized_in_bss
26172 && initializer_zerop (DECL_INITIAL (decl))))
26173 return;
26175 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
26176 name = (*targetm.strip_name_encoding) (name);
26177 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
26180 /* Select section for constant in constant pool.
26182 On RS/6000, all constants are in the private read-only data area.
26183 However, if this is being placed in the TOC it must be output as a
26184 toc entry. */
26186 static section *
26187 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
26188 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
26190 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
26191 return toc_section;
26192 else
26193 return read_only_private_data_section;
26196 /* Remove any trailing [DS] or the like from the symbol name. */
26198 static const char *
26199 rs6000_xcoff_strip_name_encoding (const char *name)
26201 size_t len;
26202 if (*name == '*')
26203 name++;
26204 len = strlen (name);
26205 if (name[len - 1] == ']')
26206 return ggc_alloc_string (name, len - 4);
26207 else
26208 return name;
26211 /* Section attributes. AIX is always PIC. */
26213 static unsigned int
26214 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
26216 unsigned int align;
26217 unsigned int flags = default_section_type_flags (decl, name, reloc);
26219 /* Align to at least UNIT size. */
26220 if (flags & SECTION_CODE)
26221 align = MIN_UNITS_PER_WORD;
26222 else
26223 /* Increase alignment of large objects if not already stricter. */
26224 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
26225 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
26226 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
26228 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
26231 /* Output at beginning of assembler file.
26233 Initialize the section names for the RS/6000 at this point.
26235 Specify filename, including full path, to assembler.
26237 We want to go into the TOC section so at least one .toc will be emitted.
26238 Also, in order to output proper .bs/.es pairs, we need at least one static
26239 [RW] section emitted.
26241 Finally, declare mcount when profiling to make the assembler happy. */
26243 static void
26244 rs6000_xcoff_file_start (void)
26246 rs6000_gen_section_name (&xcoff_bss_section_name,
26247 main_input_filename, ".bss_");
26248 rs6000_gen_section_name (&xcoff_private_data_section_name,
26249 main_input_filename, ".rw_");
26250 rs6000_gen_section_name (&xcoff_read_only_section_name,
26251 main_input_filename, ".ro_");
26253 fputs ("\t.file\t", asm_out_file);
26254 output_quoted_string (asm_out_file, main_input_filename);
26255 fputc ('\n', asm_out_file);
26256 if (write_symbols != NO_DEBUG)
26257 switch_to_section (private_data_section);
26258 switch_to_section (text_section);
26259 if (profile_flag)
26260 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
26261 rs6000_file_start ();
26264 /* Output at end of assembler file.
26265 On the RS/6000, referencing data should automatically pull in text. */
26267 static void
26268 rs6000_xcoff_file_end (void)
26270 switch_to_section (text_section);
26271 fputs ("_section_.text:\n", asm_out_file);
26272 switch_to_section (data_section);
26273 fputs (TARGET_32BIT
26274 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
26275 asm_out_file);
26277 #endif /* TARGET_XCOFF */
26279 /* Compute a (partial) cost for rtx X. Return true if the complete
26280 cost has been computed, and false if subexpressions should be
26281 scanned. In either case, *TOTAL contains the cost result. */
26283 static bool
26284 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
26285 bool speed)
26287 enum machine_mode mode = GET_MODE (x);
26289 switch (code)
26291 /* On the RS/6000, if it is valid in the insn, it is free. */
26292 case CONST_INT:
26293 if (((outer_code == SET
26294 || outer_code == PLUS
26295 || outer_code == MINUS)
26296 && (satisfies_constraint_I (x)
26297 || satisfies_constraint_L (x)))
26298 || (outer_code == AND
26299 && (satisfies_constraint_K (x)
26300 || (mode == SImode
26301 ? satisfies_constraint_L (x)
26302 : satisfies_constraint_J (x))
26303 || mask_operand (x, mode)
26304 || (mode == DImode
26305 && mask64_operand (x, DImode))))
26306 || ((outer_code == IOR || outer_code == XOR)
26307 && (satisfies_constraint_K (x)
26308 || (mode == SImode
26309 ? satisfies_constraint_L (x)
26310 : satisfies_constraint_J (x))))
26311 || outer_code == ASHIFT
26312 || outer_code == ASHIFTRT
26313 || outer_code == LSHIFTRT
26314 || outer_code == ROTATE
26315 || outer_code == ROTATERT
26316 || outer_code == ZERO_EXTRACT
26317 || (outer_code == MULT
26318 && satisfies_constraint_I (x))
26319 || ((outer_code == DIV || outer_code == UDIV
26320 || outer_code == MOD || outer_code == UMOD)
26321 && exact_log2 (INTVAL (x)) >= 0)
26322 || (outer_code == COMPARE
26323 && (satisfies_constraint_I (x)
26324 || satisfies_constraint_K (x)))
26325 || ((outer_code == EQ || outer_code == NE)
26326 && (satisfies_constraint_I (x)
26327 || satisfies_constraint_K (x)
26328 || (mode == SImode
26329 ? satisfies_constraint_L (x)
26330 : satisfies_constraint_J (x))))
26331 || (outer_code == GTU
26332 && satisfies_constraint_I (x))
26333 || (outer_code == LTU
26334 && satisfies_constraint_P (x)))
26336 *total = 0;
26337 return true;
26339 else if ((outer_code == PLUS
26340 && reg_or_add_cint_operand (x, VOIDmode))
26341 || (outer_code == MINUS
26342 && reg_or_sub_cint_operand (x, VOIDmode))
26343 || ((outer_code == SET
26344 || outer_code == IOR
26345 || outer_code == XOR)
26346 && (INTVAL (x)
26347 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
26349 *total = COSTS_N_INSNS (1);
26350 return true;
26352 /* FALLTHRU */
26354 case CONST_DOUBLE:
26355 if (mode == DImode && code == CONST_DOUBLE)
26357 if ((outer_code == IOR || outer_code == XOR)
26358 && CONST_DOUBLE_HIGH (x) == 0
26359 && (CONST_DOUBLE_LOW (x)
26360 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
26362 *total = 0;
26363 return true;
26365 else if ((outer_code == AND && and64_2_operand (x, DImode))
26366 || ((outer_code == SET
26367 || outer_code == IOR
26368 || outer_code == XOR)
26369 && CONST_DOUBLE_HIGH (x) == 0))
26371 *total = COSTS_N_INSNS (1);
26372 return true;
26375 /* FALLTHRU */
26377 case CONST:
26378 case HIGH:
26379 case SYMBOL_REF:
26380 case MEM:
26381 /* When optimizing for size, MEM should be slightly more expensive
26382 than generating address, e.g., (plus (reg) (const)).
26383 L1 cache latency is about two instructions. */
26384 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
26385 return true;
26387 case LABEL_REF:
26388 *total = 0;
26389 return true;
26391 case PLUS:
26392 case MINUS:
26393 if (FLOAT_MODE_P (mode))
26394 *total = rs6000_cost->fp;
26395 else
26396 *total = COSTS_N_INSNS (1);
26397 return false;
26399 case MULT:
26400 if (GET_CODE (XEXP (x, 1)) == CONST_INT
26401 && satisfies_constraint_I (XEXP (x, 1)))
26403 if (INTVAL (XEXP (x, 1)) >= -256
26404 && INTVAL (XEXP (x, 1)) <= 255)
26405 *total = rs6000_cost->mulsi_const9;
26406 else
26407 *total = rs6000_cost->mulsi_const;
26409 else if (mode == SFmode)
26410 *total = rs6000_cost->fp;
26411 else if (FLOAT_MODE_P (mode))
26412 *total = rs6000_cost->dmul;
26413 else if (mode == DImode)
26414 *total = rs6000_cost->muldi;
26415 else
26416 *total = rs6000_cost->mulsi;
26417 return false;
26419 case FMA:
26420 if (mode == SFmode)
26421 *total = rs6000_cost->fp;
26422 else
26423 *total = rs6000_cost->dmul;
26424 break;
26426 case DIV:
26427 case MOD:
26428 if (FLOAT_MODE_P (mode))
26430 *total = mode == DFmode ? rs6000_cost->ddiv
26431 : rs6000_cost->sdiv;
26432 return false;
26434 /* FALLTHRU */
26436 case UDIV:
26437 case UMOD:
26438 if (GET_CODE (XEXP (x, 1)) == CONST_INT
26439 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
26441 if (code == DIV || code == MOD)
26442 /* Shift, addze */
26443 *total = COSTS_N_INSNS (2);
26444 else
26445 /* Shift */
26446 *total = COSTS_N_INSNS (1);
26448 else
26450 if (GET_MODE (XEXP (x, 1)) == DImode)
26451 *total = rs6000_cost->divdi;
26452 else
26453 *total = rs6000_cost->divsi;
26455 /* Add in shift and subtract for MOD. */
26456 if (code == MOD || code == UMOD)
26457 *total += COSTS_N_INSNS (2);
26458 return false;
26460 case CTZ:
26461 case FFS:
26462 *total = COSTS_N_INSNS (4);
26463 return false;
26465 case POPCOUNT:
26466 *total = COSTS_N_INSNS (TARGET_POPCNTD ? 1 : 6);
26467 return false;
26469 case PARITY:
26470 *total = COSTS_N_INSNS (TARGET_CMPB ? 2 : 6);
26471 return false;
26473 case NOT:
26474 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
26476 *total = 0;
26477 return false;
26479 /* FALLTHRU */
26481 case AND:
26482 case CLZ:
26483 case IOR:
26484 case XOR:
26485 case ZERO_EXTRACT:
26486 *total = COSTS_N_INSNS (1);
26487 return false;
26489 case ASHIFT:
26490 case ASHIFTRT:
26491 case LSHIFTRT:
26492 case ROTATE:
26493 case ROTATERT:
26494 /* Handle mul_highpart. */
26495 if (outer_code == TRUNCATE
26496 && GET_CODE (XEXP (x, 0)) == MULT)
26498 if (mode == DImode)
26499 *total = rs6000_cost->muldi;
26500 else
26501 *total = rs6000_cost->mulsi;
26502 return true;
26504 else if (outer_code == AND)
26505 *total = 0;
26506 else
26507 *total = COSTS_N_INSNS (1);
26508 return false;
26510 case SIGN_EXTEND:
26511 case ZERO_EXTEND:
26512 if (GET_CODE (XEXP (x, 0)) == MEM)
26513 *total = 0;
26514 else
26515 *total = COSTS_N_INSNS (1);
26516 return false;
26518 case COMPARE:
26519 case NEG:
26520 case ABS:
26521 if (!FLOAT_MODE_P (mode))
26523 *total = COSTS_N_INSNS (1);
26524 return false;
26526 /* FALLTHRU */
26528 case FLOAT:
26529 case UNSIGNED_FLOAT:
26530 case FIX:
26531 case UNSIGNED_FIX:
26532 case FLOAT_TRUNCATE:
26533 *total = rs6000_cost->fp;
26534 return false;
26536 case FLOAT_EXTEND:
26537 if (mode == DFmode)
26538 *total = 0;
26539 else
26540 *total = rs6000_cost->fp;
26541 return false;
26543 case UNSPEC:
26544 switch (XINT (x, 1))
26546 case UNSPEC_FRSP:
26547 *total = rs6000_cost->fp;
26548 return true;
26550 default:
26551 break;
26553 break;
26555 case CALL:
26556 case IF_THEN_ELSE:
26557 if (!speed)
26559 *total = COSTS_N_INSNS (1);
26560 return true;
26562 else if (FLOAT_MODE_P (mode)
26563 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
26565 *total = rs6000_cost->fp;
26566 return false;
26568 break;
26570 case EQ:
26571 case GTU:
26572 case LTU:
26573 /* Carry bit requires mode == Pmode.
26574 NEG or PLUS already counted so only add one. */
26575 if (mode == Pmode
26576 && (outer_code == NEG || outer_code == PLUS))
26578 *total = COSTS_N_INSNS (1);
26579 return true;
26581 if (outer_code == SET)
26583 if (XEXP (x, 1) == const0_rtx)
26585 if (TARGET_ISEL && !TARGET_MFCRF)
26586 *total = COSTS_N_INSNS (8);
26587 else
26588 *total = COSTS_N_INSNS (2);
26589 return true;
26591 else if (mode == Pmode)
26593 *total = COSTS_N_INSNS (3);
26594 return false;
26597 /* FALLTHRU */
26599 case GT:
26600 case LT:
26601 case UNORDERED:
26602 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
26604 if (TARGET_ISEL && !TARGET_MFCRF)
26605 *total = COSTS_N_INSNS (8);
26606 else
26607 *total = COSTS_N_INSNS (2);
26608 return true;
26610 /* CC COMPARE. */
26611 if (outer_code == COMPARE)
26613 *total = 0;
26614 return true;
26616 break;
26618 default:
26619 break;
26622 return false;
26625 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
26627 static bool
26628 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
26629 bool speed)
26631 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
26633 fprintf (stderr,
26634 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
26635 "total = %d, speed = %s, x:\n",
26636 ret ? "complete" : "scan inner",
26637 GET_RTX_NAME (code),
26638 GET_RTX_NAME (outer_code),
26639 *total,
26640 speed ? "true" : "false");
26642 debug_rtx (x);
26644 return ret;
26647 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
26649 static int
26650 rs6000_debug_address_cost (rtx x, bool speed)
26652 int ret = TARGET_ADDRESS_COST (x, speed);
26654 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
26655 ret, speed ? "true" : "false");
26656 debug_rtx (x);
26658 return ret;
26662 /* A C expression returning the cost of moving data from a register of class
26663 CLASS1 to one of CLASS2. */
26665 static int
26666 rs6000_register_move_cost (enum machine_mode mode,
26667 reg_class_t from, reg_class_t to)
26669 int ret;
26671 /* Moves from/to GENERAL_REGS. */
26672 if (reg_classes_intersect_p (to, GENERAL_REGS)
26673 || reg_classes_intersect_p (from, GENERAL_REGS))
26675 if (! reg_classes_intersect_p (to, GENERAL_REGS))
26676 from = to;
26678 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
26679 ret = (rs6000_memory_move_cost (mode, from, false)
26680 + rs6000_memory_move_cost (mode, GENERAL_REGS, false));
26682 /* It's more expensive to move CR_REGS than CR0_REGS because of the
26683 shift. */
26684 else if (from == CR_REGS)
26685 ret = 4;
26687 /* Power6 has slower LR/CTR moves so make them more expensive than
26688 memory in order to bias spills to memory .*/
26689 else if (rs6000_cpu == PROCESSOR_POWER6
26690 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
26691 ret = 6 * hard_regno_nregs[0][mode];
26693 else
26694 /* A move will cost one instruction per GPR moved. */
26695 ret = 2 * hard_regno_nregs[0][mode];
26698 /* If we have VSX, we can easily move between FPR or Altivec registers. */
26699 else if (VECTOR_UNIT_VSX_P (mode)
26700 && reg_classes_intersect_p (to, VSX_REGS)
26701 && reg_classes_intersect_p (from, VSX_REGS))
26702 ret = 2 * hard_regno_nregs[32][mode];
26704 /* Moving between two similar registers is just one instruction. */
26705 else if (reg_classes_intersect_p (to, from))
26706 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
26708 /* Everything else has to go through GENERAL_REGS. */
26709 else
26710 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
26711 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
26713 if (TARGET_DEBUG_COST)
26714 fprintf (stderr,
26715 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
26716 ret, GET_MODE_NAME (mode), reg_class_names[from],
26717 reg_class_names[to]);
26719 return ret;
26722 /* A C expressions returning the cost of moving data of MODE from a register to
26723 or from memory. */
26725 static int
26726 rs6000_memory_move_cost (enum machine_mode mode, reg_class_t rclass,
26727 bool in ATTRIBUTE_UNUSED)
26729 int ret;
26731 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
26732 ret = 4 * hard_regno_nregs[0][mode];
26733 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
26734 ret = 4 * hard_regno_nregs[32][mode];
26735 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
26736 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
26737 else
26738 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
26740 if (TARGET_DEBUG_COST)
26741 fprintf (stderr,
26742 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
26743 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
26745 return ret;
26748 /* Returns a code for a target-specific builtin that implements
26749 reciprocal of the function, or NULL_TREE if not available. */
26751 static tree
26752 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
26753 bool sqrt ATTRIBUTE_UNUSED)
26755 if (optimize_insn_for_size_p ())
26756 return NULL_TREE;
26758 if (md_fn)
26759 switch (fn)
26761 case VSX_BUILTIN_XVSQRTDP:
26762 if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode))
26763 return NULL_TREE;
26765 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
26767 case VSX_BUILTIN_XVSQRTSP:
26768 if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode))
26769 return NULL_TREE;
26771 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V4SF];
26773 default:
26774 return NULL_TREE;
26777 else
26778 switch (fn)
26780 case BUILT_IN_SQRT:
26781 if (!RS6000_RECIP_AUTO_RSQRTE_P (DFmode))
26782 return NULL_TREE;
26784 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRT];
26786 case BUILT_IN_SQRTF:
26787 if (!RS6000_RECIP_AUTO_RSQRTE_P (SFmode))
26788 return NULL_TREE;
26790 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
26792 default:
26793 return NULL_TREE;
26797 /* Load up a constant. If the mode is a vector mode, splat the value across
26798 all of the vector elements. */
26800 static rtx
26801 rs6000_load_constant_and_splat (enum machine_mode mode, REAL_VALUE_TYPE dconst)
26803 rtx reg;
26805 if (mode == SFmode || mode == DFmode)
26807 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, mode);
26808 reg = force_reg (mode, d);
26810 else if (mode == V4SFmode)
26812 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, SFmode);
26813 rtvec v = gen_rtvec (4, d, d, d, d);
26814 reg = gen_reg_rtx (mode);
26815 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26817 else if (mode == V2DFmode)
26819 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, DFmode);
26820 rtvec v = gen_rtvec (2, d, d);
26821 reg = gen_reg_rtx (mode);
26822 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26824 else
26825 gcc_unreachable ();
26827 return reg;
26830 /* Generate an FMA instruction. */
26832 static void
26833 rs6000_emit_madd (rtx target, rtx m1, rtx m2, rtx a)
26835 enum machine_mode mode = GET_MODE (target);
26836 rtx dst;
26838 dst = expand_ternary_op (mode, fma_optab, m1, m2, a, target, 0);
26839 gcc_assert (dst != NULL);
26841 if (dst != target)
26842 emit_move_insn (target, dst);
26845 /* Generate a FMSUB instruction: dst = fma(m1, m2, -a). */
26847 static void
26848 rs6000_emit_msub (rtx target, rtx m1, rtx m2, rtx a)
26850 enum machine_mode mode = GET_MODE (target);
26851 rtx dst;
26853 /* Altivec does not support fms directly;
26854 generate in terms of fma in that case. */
26855 if (optab_handler (fms_optab, mode) != CODE_FOR_nothing)
26856 dst = expand_ternary_op (mode, fms_optab, m1, m2, a, target, 0);
26857 else
26859 a = expand_unop (mode, neg_optab, a, NULL_RTX, 0);
26860 dst = expand_ternary_op (mode, fma_optab, m1, m2, a, target, 0);
26862 gcc_assert (dst != NULL);
26864 if (dst != target)
26865 emit_move_insn (target, dst);
26868 /* Generate a FNMSUB instruction: dst = -fma(m1, m2, -a). */
26870 static void
26871 rs6000_emit_nmsub (rtx dst, rtx m1, rtx m2, rtx a)
26873 enum machine_mode mode = GET_MODE (dst);
26874 rtx r;
26876 /* This is a tad more complicated, since the fnma_optab is for
26877 a different expression: fma(-m1, m2, a), which is the same
26878 thing except in the case of signed zeros.
26880 Fortunately we know that if FMA is supported that FNMSUB is
26881 also supported in the ISA. Just expand it directly. */
26883 gcc_assert (optab_handler (fma_optab, mode) != CODE_FOR_nothing);
26885 r = gen_rtx_NEG (mode, a);
26886 r = gen_rtx_FMA (mode, m1, m2, r);
26887 r = gen_rtx_NEG (mode, r);
26888 emit_insn (gen_rtx_SET (VOIDmode, dst, r));
26891 /* Newton-Raphson approximation of floating point divide with just 2 passes
26892 (either single precision floating point, or newer machines with higher
26893 accuracy estimates). Support both scalar and vector divide. Assumes no
26894 trapping math and finite arguments. */
26896 static void
26897 rs6000_emit_swdiv_high_precision (rtx dst, rtx n, rtx d)
26899 enum machine_mode mode = GET_MODE (dst);
26900 rtx x0, e0, e1, y1, u0, v0;
26901 enum insn_code code = optab_handler (smul_optab, mode);
26902 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26903 rtx one = rs6000_load_constant_and_splat (mode, dconst1);
26905 gcc_assert (code != CODE_FOR_nothing);
26907 /* x0 = 1./d estimate */
26908 x0 = gen_reg_rtx (mode);
26909 emit_insn (gen_rtx_SET (VOIDmode, x0,
26910 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26911 UNSPEC_FRES)));
26913 e0 = gen_reg_rtx (mode);
26914 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - (d * x0) */
26916 e1 = gen_reg_rtx (mode);
26917 rs6000_emit_madd (e1, e0, e0, e0); /* e1 = (e0 * e0) + e0 */
26919 y1 = gen_reg_rtx (mode);
26920 rs6000_emit_madd (y1, e1, x0, x0); /* y1 = (e1 * x0) + x0 */
26922 u0 = gen_reg_rtx (mode);
26923 emit_insn (gen_mul (u0, n, y1)); /* u0 = n * y1 */
26925 v0 = gen_reg_rtx (mode);
26926 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - (d * u0) */
26928 rs6000_emit_madd (dst, v0, y1, u0); /* dst = (v0 * y1) + u0 */
26931 /* Newton-Raphson approximation of floating point divide that has a low
26932 precision estimate. Assumes no trapping math and finite arguments. */
26934 static void
26935 rs6000_emit_swdiv_low_precision (rtx dst, rtx n, rtx d)
26937 enum machine_mode mode = GET_MODE (dst);
26938 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
26939 enum insn_code code = optab_handler (smul_optab, mode);
26940 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26942 gcc_assert (code != CODE_FOR_nothing);
26944 one = rs6000_load_constant_and_splat (mode, dconst1);
26946 /* x0 = 1./d estimate */
26947 x0 = gen_reg_rtx (mode);
26948 emit_insn (gen_rtx_SET (VOIDmode, x0,
26949 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26950 UNSPEC_FRES)));
26952 e0 = gen_reg_rtx (mode);
26953 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - d * x0 */
26955 y1 = gen_reg_rtx (mode);
26956 rs6000_emit_madd (y1, e0, x0, x0); /* y1 = x0 + e0 * x0 */
26958 e1 = gen_reg_rtx (mode);
26959 emit_insn (gen_mul (e1, e0, e0)); /* e1 = e0 * e0 */
26961 y2 = gen_reg_rtx (mode);
26962 rs6000_emit_madd (y2, e1, y1, y1); /* y2 = y1 + e1 * y1 */
26964 e2 = gen_reg_rtx (mode);
26965 emit_insn (gen_mul (e2, e1, e1)); /* e2 = e1 * e1 */
26967 y3 = gen_reg_rtx (mode);
26968 rs6000_emit_madd (y3, e2, y2, y2); /* y3 = y2 + e2 * y2 */
26970 u0 = gen_reg_rtx (mode);
26971 emit_insn (gen_mul (u0, n, y3)); /* u0 = n * y3 */
26973 v0 = gen_reg_rtx (mode);
26974 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - d * u0 */
26976 rs6000_emit_madd (dst, v0, y3, u0); /* dst = u0 + v0 * y3 */
26979 /* Newton-Raphson approximation of floating point divide DST = N/D. If NOTE_P,
26980 add a reg_note saying that this was a division. Support both scalar and
26981 vector divide. Assumes no trapping math and finite arguments. */
26983 void
26984 rs6000_emit_swdiv (rtx dst, rtx n, rtx d, bool note_p)
26986 enum machine_mode mode = GET_MODE (dst);
26988 if (RS6000_RECIP_HIGH_PRECISION_P (mode))
26989 rs6000_emit_swdiv_high_precision (dst, n, d);
26990 else
26991 rs6000_emit_swdiv_low_precision (dst, n, d);
26993 if (note_p)
26994 add_reg_note (get_last_insn (), REG_EQUAL, gen_rtx_DIV (mode, n, d));
26997 /* Newton-Raphson approximation of single/double-precision floating point
26998 rsqrt. Assumes no trapping math and finite arguments. */
27000 void
27001 rs6000_emit_swrsqrt (rtx dst, rtx src)
27003 enum machine_mode mode = GET_MODE (src);
27004 rtx x0 = gen_reg_rtx (mode);
27005 rtx y = gen_reg_rtx (mode);
27006 int passes = (TARGET_RECIP_PRECISION) ? 2 : 3;
27007 REAL_VALUE_TYPE dconst3_2;
27008 int i;
27009 rtx halfthree;
27010 enum insn_code code = optab_handler (smul_optab, mode);
27011 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
27013 gcc_assert (code != CODE_FOR_nothing);
27015 /* Load up the constant 1.5 either as a scalar, or as a vector. */
27016 real_from_integer (&dconst3_2, VOIDmode, 3, 0, 0);
27017 SET_REAL_EXP (&dconst3_2, REAL_EXP (&dconst3_2) - 1);
27019 halfthree = rs6000_load_constant_and_splat (mode, dconst3_2);
27021 /* x0 = rsqrt estimate */
27022 emit_insn (gen_rtx_SET (VOIDmode, x0,
27023 gen_rtx_UNSPEC (mode, gen_rtvec (1, src),
27024 UNSPEC_RSQRT)));
27026 /* y = 0.5 * src = 1.5 * src - src -> fewer constants */
27027 rs6000_emit_msub (y, src, halfthree, src);
27029 for (i = 0; i < passes; i++)
27031 rtx x1 = gen_reg_rtx (mode);
27032 rtx u = gen_reg_rtx (mode);
27033 rtx v = gen_reg_rtx (mode);
27035 /* x1 = x0 * (1.5 - y * (x0 * x0)) */
27036 emit_insn (gen_mul (u, x0, x0));
27037 rs6000_emit_nmsub (v, y, u, halfthree);
27038 emit_insn (gen_mul (x1, x0, v));
27039 x0 = x1;
27042 emit_move_insn (dst, x0);
27043 return;
27046 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
27047 (Power7) targets. DST is the target, and SRC is the argument operand. */
27049 void
27050 rs6000_emit_popcount (rtx dst, rtx src)
27052 enum machine_mode mode = GET_MODE (dst);
27053 rtx tmp1, tmp2;
27055 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
27056 if (TARGET_POPCNTD)
27058 if (mode == SImode)
27059 emit_insn (gen_popcntdsi2 (dst, src));
27060 else
27061 emit_insn (gen_popcntddi2 (dst, src));
27062 return;
27065 tmp1 = gen_reg_rtx (mode);
27067 if (mode == SImode)
27069 emit_insn (gen_popcntbsi2 (tmp1, src));
27070 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
27071 NULL_RTX, 0);
27072 tmp2 = force_reg (SImode, tmp2);
27073 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
27075 else
27077 emit_insn (gen_popcntbdi2 (tmp1, src));
27078 tmp2 = expand_mult (DImode, tmp1,
27079 GEN_INT ((HOST_WIDE_INT)
27080 0x01010101 << 32 | 0x01010101),
27081 NULL_RTX, 0);
27082 tmp2 = force_reg (DImode, tmp2);
27083 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
27088 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
27089 target, and SRC is the argument operand. */
27091 void
27092 rs6000_emit_parity (rtx dst, rtx src)
27094 enum machine_mode mode = GET_MODE (dst);
27095 rtx tmp;
27097 tmp = gen_reg_rtx (mode);
27099 /* Use the PPC ISA 2.05 prtyw/prtyd instruction if we can. */
27100 if (TARGET_CMPB)
27102 if (mode == SImode)
27104 emit_insn (gen_popcntbsi2 (tmp, src));
27105 emit_insn (gen_paritysi2_cmpb (dst, tmp));
27107 else
27109 emit_insn (gen_popcntbdi2 (tmp, src));
27110 emit_insn (gen_paritydi2_cmpb (dst, tmp));
27112 return;
27115 if (mode == SImode)
27117 /* Is mult+shift >= shift+xor+shift+xor? */
27118 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
27120 rtx tmp1, tmp2, tmp3, tmp4;
27122 tmp1 = gen_reg_rtx (SImode);
27123 emit_insn (gen_popcntbsi2 (tmp1, src));
27125 tmp2 = gen_reg_rtx (SImode);
27126 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
27127 tmp3 = gen_reg_rtx (SImode);
27128 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
27130 tmp4 = gen_reg_rtx (SImode);
27131 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
27132 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
27134 else
27135 rs6000_emit_popcount (tmp, src);
27136 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
27138 else
27140 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
27141 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
27143 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
27145 tmp1 = gen_reg_rtx (DImode);
27146 emit_insn (gen_popcntbdi2 (tmp1, src));
27148 tmp2 = gen_reg_rtx (DImode);
27149 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
27150 tmp3 = gen_reg_rtx (DImode);
27151 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
27153 tmp4 = gen_reg_rtx (DImode);
27154 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
27155 tmp5 = gen_reg_rtx (DImode);
27156 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
27158 tmp6 = gen_reg_rtx (DImode);
27159 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
27160 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
27162 else
27163 rs6000_emit_popcount (tmp, src);
27164 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
27168 /* Return an RTX representing where to find the function value of a
27169 function returning MODE. */
27170 static rtx
27171 rs6000_complex_function_value (enum machine_mode mode)
27173 unsigned int regno;
27174 rtx r1, r2;
27175 enum machine_mode inner = GET_MODE_INNER (mode);
27176 unsigned int inner_bytes = GET_MODE_SIZE (inner);
27178 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
27179 regno = FP_ARG_RETURN;
27180 else
27182 regno = GP_ARG_RETURN;
27184 /* 32-bit is OK since it'll go in r3/r4. */
27185 if (TARGET_32BIT && inner_bytes >= 4)
27186 return gen_rtx_REG (mode, regno);
27189 if (inner_bytes >= 8)
27190 return gen_rtx_REG (mode, regno);
27192 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
27193 const0_rtx);
27194 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
27195 GEN_INT (inner_bytes));
27196 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
27199 /* Target hook for TARGET_FUNCTION_VALUE.
27201 On the SPE, both FPs and vectors are returned in r3.
27203 On RS/6000 an integer value is in r3 and a floating-point value is in
27204 fp1, unless -msoft-float. */
27207 rs6000_function_value (const_tree valtype,
27208 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
27209 bool outgoing ATTRIBUTE_UNUSED)
27211 enum machine_mode mode;
27212 unsigned int regno;
27214 /* Special handling for structs in darwin64. */
27215 if (TARGET_MACHO
27216 && rs6000_darwin64_struct_check_p (TYPE_MODE (valtype), valtype))
27218 CUMULATIVE_ARGS valcum;
27219 rtx valret;
27221 valcum.words = 0;
27222 valcum.fregno = FP_ARG_MIN_REG;
27223 valcum.vregno = ALTIVEC_ARG_MIN_REG;
27224 /* Do a trial code generation as if this were going to be passed as
27225 an argument; if any part goes in memory, we return NULL. */
27226 valret = rs6000_darwin64_record_arg (&valcum, valtype, true, /* retval= */ true);
27227 if (valret)
27228 return valret;
27229 /* Otherwise fall through to standard ABI rules. */
27232 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
27234 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
27235 return gen_rtx_PARALLEL (DImode,
27236 gen_rtvec (2,
27237 gen_rtx_EXPR_LIST (VOIDmode,
27238 gen_rtx_REG (SImode, GP_ARG_RETURN),
27239 const0_rtx),
27240 gen_rtx_EXPR_LIST (VOIDmode,
27241 gen_rtx_REG (SImode,
27242 GP_ARG_RETURN + 1),
27243 GEN_INT (4))));
27245 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
27247 return gen_rtx_PARALLEL (DCmode,
27248 gen_rtvec (4,
27249 gen_rtx_EXPR_LIST (VOIDmode,
27250 gen_rtx_REG (SImode, GP_ARG_RETURN),
27251 const0_rtx),
27252 gen_rtx_EXPR_LIST (VOIDmode,
27253 gen_rtx_REG (SImode,
27254 GP_ARG_RETURN + 1),
27255 GEN_INT (4)),
27256 gen_rtx_EXPR_LIST (VOIDmode,
27257 gen_rtx_REG (SImode,
27258 GP_ARG_RETURN + 2),
27259 GEN_INT (8)),
27260 gen_rtx_EXPR_LIST (VOIDmode,
27261 gen_rtx_REG (SImode,
27262 GP_ARG_RETURN + 3),
27263 GEN_INT (12))));
27266 mode = TYPE_MODE (valtype);
27267 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
27268 || POINTER_TYPE_P (valtype))
27269 mode = TARGET_32BIT ? SImode : DImode;
27271 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
27272 /* _Decimal128 must use an even/odd register pair. */
27273 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
27274 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
27275 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
27276 regno = FP_ARG_RETURN;
27277 else if (TREE_CODE (valtype) == COMPLEX_TYPE
27278 && targetm.calls.split_complex_arg)
27279 return rs6000_complex_function_value (mode);
27280 else if (TREE_CODE (valtype) == VECTOR_TYPE
27281 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
27282 && ALTIVEC_VECTOR_MODE (mode))
27283 regno = ALTIVEC_ARG_RETURN;
27284 else if (TREE_CODE (valtype) == VECTOR_TYPE
27285 && TARGET_VSX && TARGET_ALTIVEC_ABI
27286 && VSX_VECTOR_MODE (mode))
27287 regno = ALTIVEC_ARG_RETURN;
27288 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
27289 && (mode == DFmode || mode == DCmode
27290 || mode == TFmode || mode == TCmode))
27291 return spe_build_register_parallel (mode, GP_ARG_RETURN);
27292 else
27293 regno = GP_ARG_RETURN;
27295 return gen_rtx_REG (mode, regno);
27298 /* Define how to find the value returned by a library function
27299 assuming the value has mode MODE. */
27301 rs6000_libcall_value (enum machine_mode mode)
27303 unsigned int regno;
27305 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
27307 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
27308 return gen_rtx_PARALLEL (DImode,
27309 gen_rtvec (2,
27310 gen_rtx_EXPR_LIST (VOIDmode,
27311 gen_rtx_REG (SImode, GP_ARG_RETURN),
27312 const0_rtx),
27313 gen_rtx_EXPR_LIST (VOIDmode,
27314 gen_rtx_REG (SImode,
27315 GP_ARG_RETURN + 1),
27316 GEN_INT (4))));
27319 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
27320 /* _Decimal128 must use an even/odd register pair. */
27321 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
27322 else if (SCALAR_FLOAT_MODE_P (mode)
27323 && TARGET_HARD_FLOAT && TARGET_FPRS
27324 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
27325 regno = FP_ARG_RETURN;
27326 else if (ALTIVEC_VECTOR_MODE (mode)
27327 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
27328 regno = ALTIVEC_ARG_RETURN;
27329 else if (VSX_VECTOR_MODE (mode)
27330 && TARGET_VSX && TARGET_ALTIVEC_ABI)
27331 regno = ALTIVEC_ARG_RETURN;
27332 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
27333 return rs6000_complex_function_value (mode);
27334 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
27335 && (mode == DFmode || mode == DCmode
27336 || mode == TFmode || mode == TCmode))
27337 return spe_build_register_parallel (mode, GP_ARG_RETURN);
27338 else
27339 regno = GP_ARG_RETURN;
27341 return gen_rtx_REG (mode, regno);
27345 /* Given FROM and TO register numbers, say whether this elimination is allowed.
27346 Frame pointer elimination is automatically handled.
27348 For the RS/6000, if frame pointer elimination is being done, we would like
27349 to convert ap into fp, not sp.
27351 We need r30 if -mminimal-toc was specified, and there are constant pool
27352 references. */
27354 bool
27355 rs6000_can_eliminate (const int from, const int to)
27357 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
27358 ? ! frame_pointer_needed
27359 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
27360 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
27361 : true);
27364 /* Define the offset between two registers, FROM to be eliminated and its
27365 replacement TO, at the start of a routine. */
27366 HOST_WIDE_INT
27367 rs6000_initial_elimination_offset (int from, int to)
27369 rs6000_stack_t *info = rs6000_stack_info ();
27370 HOST_WIDE_INT offset;
27372 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
27373 offset = info->push_p ? 0 : -info->total_size;
27374 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
27376 offset = info->push_p ? 0 : -info->total_size;
27377 if (FRAME_GROWS_DOWNWARD)
27378 offset += info->fixed_size + info->vars_size + info->parm_size;
27380 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
27381 offset = FRAME_GROWS_DOWNWARD
27382 ? info->fixed_size + info->vars_size + info->parm_size
27383 : 0;
27384 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
27385 offset = info->total_size;
27386 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
27387 offset = info->push_p ? info->total_size : 0;
27388 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
27389 offset = 0;
27390 else
27391 gcc_unreachable ();
27393 return offset;
27396 static rtx
27397 rs6000_dwarf_register_span (rtx reg)
27399 rtx parts[8];
27400 int i, words;
27401 unsigned regno = REGNO (reg);
27402 enum machine_mode mode = GET_MODE (reg);
27404 if (TARGET_SPE
27405 && regno < 32
27406 && (SPE_VECTOR_MODE (GET_MODE (reg))
27407 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
27408 && mode != SFmode && mode != SDmode && mode != SCmode)))
27410 else
27411 return NULL_RTX;
27413 regno = REGNO (reg);
27415 /* The duality of the SPE register size wreaks all kinds of havoc.
27416 This is a way of distinguishing r0 in 32-bits from r0 in
27417 64-bits. */
27418 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
27419 gcc_assert (words <= 4);
27420 for (i = 0; i < words; i++, regno++)
27422 if (BYTES_BIG_ENDIAN)
27424 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
27425 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
27427 else
27429 parts[2 * i] = gen_rtx_REG (SImode, regno);
27430 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
27434 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
27437 /* Fill in sizes for SPE register high parts in table used by unwinder. */
27439 static void
27440 rs6000_init_dwarf_reg_sizes_extra (tree address)
27442 if (TARGET_SPE)
27444 int i;
27445 enum machine_mode mode = TYPE_MODE (char_type_node);
27446 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
27447 rtx mem = gen_rtx_MEM (BLKmode, addr);
27448 rtx value = gen_int_mode (4, mode);
27450 for (i = 1201; i < 1232; i++)
27452 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
27453 HOST_WIDE_INT offset
27454 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
27456 emit_move_insn (adjust_address (mem, mode, offset), value);
27461 /* Map internal gcc register numbers to DWARF2 register numbers. */
27463 unsigned int
27464 rs6000_dbx_register_number (unsigned int regno)
27466 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
27467 return regno;
27468 if (regno == MQ_REGNO)
27469 return 100;
27470 if (regno == LR_REGNO)
27471 return 108;
27472 if (regno == CTR_REGNO)
27473 return 109;
27474 if (CR_REGNO_P (regno))
27475 return regno - CR0_REGNO + 86;
27476 if (regno == CA_REGNO)
27477 return 101; /* XER */
27478 if (ALTIVEC_REGNO_P (regno))
27479 return regno - FIRST_ALTIVEC_REGNO + 1124;
27480 if (regno == VRSAVE_REGNO)
27481 return 356;
27482 if (regno == VSCR_REGNO)
27483 return 67;
27484 if (regno == SPE_ACC_REGNO)
27485 return 99;
27486 if (regno == SPEFSCR_REGNO)
27487 return 612;
27488 /* SPE high reg number. We get these values of regno from
27489 rs6000_dwarf_register_span. */
27490 gcc_assert (regno >= 1200 && regno < 1232);
27491 return regno;
27494 /* target hook eh_return_filter_mode */
27495 static enum machine_mode
27496 rs6000_eh_return_filter_mode (void)
27498 return TARGET_32BIT ? SImode : word_mode;
27501 /* Target hook for scalar_mode_supported_p. */
27502 static bool
27503 rs6000_scalar_mode_supported_p (enum machine_mode mode)
27505 if (DECIMAL_FLOAT_MODE_P (mode))
27506 return default_decimal_float_supported_p ();
27507 else
27508 return default_scalar_mode_supported_p (mode);
27511 /* Target hook for vector_mode_supported_p. */
27512 static bool
27513 rs6000_vector_mode_supported_p (enum machine_mode mode)
27516 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
27517 return true;
27519 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
27520 return true;
27522 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
27523 return true;
27525 else
27526 return false;
27529 /* Target hook for invalid_arg_for_unprototyped_fn. */
27530 static const char *
27531 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
27533 return (!rs6000_darwin64_abi
27534 && typelist == 0
27535 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
27536 && (funcdecl == NULL_TREE
27537 || (TREE_CODE (funcdecl) == FUNCTION_DECL
27538 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
27539 ? N_("AltiVec argument passed to unprototyped function")
27540 : NULL;
27543 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
27544 setup by using __stack_chk_fail_local hidden function instead of
27545 calling __stack_chk_fail directly. Otherwise it is better to call
27546 __stack_chk_fail directly. */
27548 static tree
27549 rs6000_stack_protect_fail (void)
27551 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
27552 ? default_hidden_stack_protect_fail ()
27553 : default_external_stack_protect_fail ();
27556 void
27557 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
27558 int num_operands ATTRIBUTE_UNUSED)
27560 if (rs6000_warn_cell_microcode)
27562 const char *temp;
27563 int insn_code_number = recog_memoized (insn);
27564 location_t location = locator_location (INSN_LOCATOR (insn));
27566 /* Punt on insns we cannot recognize. */
27567 if (insn_code_number < 0)
27568 return;
27570 temp = get_insn_template (insn_code_number, insn);
27572 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
27573 warning_at (location, OPT_mwarn_cell_microcode,
27574 "emitting microcode insn %s\t[%s] #%d",
27575 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27576 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
27577 warning_at (location, OPT_mwarn_cell_microcode,
27578 "emitting conditional microcode insn %s\t[%s] #%d",
27579 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27584 /* Mask options that we want to support inside of attribute((target)) and
27585 #pragma GCC target operations. Note, we do not include things like
27586 64/32-bit, endianess, hard/soft floating point, etc. that would have
27587 different calling sequences. */
27589 struct rs6000_opt_mask {
27590 const char *name; /* option name */
27591 int mask; /* mask to set */
27592 bool invert; /* invert sense of mask */
27593 bool valid_target; /* option is a target option */
27596 static struct rs6000_opt_mask const rs6000_opt_masks[] =
27598 { "altivec", MASK_ALTIVEC, false, true },
27599 { "cmpb", MASK_CMPB, false, true },
27600 { "dlmzb", MASK_DLMZB, false, true },
27601 { "fprnd", MASK_FPRND, false, true },
27602 { "hard-dfp", MASK_DFP, false, true },
27603 { "isel", MASK_ISEL, false, true },
27604 { "mfcrf", MASK_MFCRF, false, true },
27605 { "mfpgpr", MASK_MFPGPR, false, true },
27606 { "mulhw", MASK_MULHW, false, true },
27607 { "multiple", MASK_MULTIPLE, false, true },
27608 { "update", MASK_NO_UPDATE, true , true },
27609 { "popcntb", MASK_POPCNTB, false, true },
27610 { "popcntd", MASK_POPCNTD, false, true },
27611 { "powerpc-gfxopt", MASK_PPC_GFXOPT, false, true },
27612 { "powerpc-gpopt", MASK_PPC_GPOPT, false, true },
27613 { "recip-precision", MASK_RECIP_PRECISION, false, true },
27614 { "string", MASK_STRING, false, true },
27615 { "vsx", MASK_VSX, false, true },
27616 #ifdef MASK_64BIT
27617 #if TARGET_AIX_OS
27618 { "aix64", MASK_64BIT, false, false },
27619 { "aix32", MASK_64BIT, true, false },
27620 #else
27621 { "64", MASK_64BIT, false, false },
27622 { "32", MASK_64BIT, true, false },
27623 #endif
27624 #endif
27625 #ifdef MASK_EABI
27626 { "eabi", MASK_EABI, false, false },
27627 #endif
27628 #ifdef MASK_LITTLE_ENDIAN
27629 { "little", MASK_LITTLE_ENDIAN, false, false },
27630 { "big", MASK_LITTLE_ENDIAN, true, false },
27631 #endif
27632 #ifdef MASK_RELOCATABLE
27633 { "relocatable", MASK_RELOCATABLE, false, false },
27634 #endif
27635 #ifdef MASK_STRICT_ALIGN
27636 { "strict-align", MASK_STRICT_ALIGN, false, false },
27637 #endif
27638 { "power", MASK_POWER, false, false },
27639 { "power2", MASK_POWER2, false, false },
27640 { "powerpc", MASK_POWERPC, false, false },
27641 { "soft-float", MASK_SOFT_FLOAT, false, false },
27642 { "string", MASK_STRING, false, false },
27645 /* Option variables that we want to support inside attribute((target)) and
27646 #pragma GCC target operations. */
27648 struct rs6000_opt_var {
27649 const char *name; /* option name */
27650 size_t global_offset; /* offset of the option in global_options. */
27651 size_t target_offset; /* offset of the option in target optiosn. */
27654 static struct rs6000_opt_var const rs6000_opt_vars[] =
27656 { "friz",
27657 offsetof (struct gcc_options, x_TARGET_FRIZ),
27658 offsetof (struct cl_target_option, x_TARGET_FRIZ), },
27659 { "avoid-indexed-addresses",
27660 offsetof (struct gcc_options, x_TARGET_AVOID_XFORM),
27661 offsetof (struct cl_target_option, x_TARGET_AVOID_XFORM) },
27662 { "paired",
27663 offsetof (struct gcc_options, x_rs6000_paired_float),
27664 offsetof (struct cl_target_option, x_rs6000_paired_float), },
27665 { "longcall",
27666 offsetof (struct gcc_options, x_rs6000_default_long_calls),
27667 offsetof (struct cl_target_option, x_rs6000_default_long_calls), },
27670 /* Inner function to handle attribute((target("..."))) and #pragma GCC target
27671 parsing. Return true if there were no errors. */
27673 static bool
27674 rs6000_inner_target_options (tree args, bool attr_p)
27676 bool ret = true;
27678 if (args == NULL_TREE)
27681 else if (TREE_CODE (args) == STRING_CST)
27683 char *p = ASTRDUP (TREE_STRING_POINTER (args));
27684 char *q;
27686 while ((q = strtok (p, ",")) != NULL)
27688 bool error_p = false;
27689 bool not_valid_p = false;
27690 const char *cpu_opt = NULL;
27692 p = NULL;
27693 if (strncmp (q, "cpu=", 4) == 0)
27695 int cpu_index = rs6000_cpu_name_lookup (q+4);
27696 if (cpu_index >= 0)
27697 rs6000_cpu_index = cpu_index;
27698 else
27700 error_p = true;
27701 cpu_opt = q+4;
27704 else if (strncmp (q, "tune=", 5) == 0)
27706 int tune_index = rs6000_cpu_name_lookup (q+5);
27707 if (tune_index >= 0)
27708 rs6000_tune_index = tune_index;
27709 else
27711 error_p = true;
27712 cpu_opt = q+5;
27715 else
27717 size_t i;
27718 bool invert = false;
27719 char *r = q;
27721 error_p = true;
27722 if (strncmp (r, "no-", 3) == 0)
27724 invert = true;
27725 r += 3;
27728 for (i = 0; i < ARRAY_SIZE (rs6000_opt_masks); i++)
27729 if (strcmp (r, rs6000_opt_masks[i].name) == 0)
27731 int mask = rs6000_opt_masks[i].mask;
27733 if (!rs6000_opt_masks[i].valid_target)
27734 not_valid_p = true;
27735 else
27737 error_p = false;
27738 target_flags_explicit |= mask;
27740 if (rs6000_opt_masks[i].invert)
27741 invert = !invert;
27743 if (invert)
27744 target_flags &= ~mask;
27745 else
27746 target_flags |= mask;
27748 break;
27751 if (error_p && !not_valid_p)
27753 for (i = 0; i < ARRAY_SIZE (rs6000_opt_vars); i++)
27754 if (strcmp (r, rs6000_opt_vars[i].name) == 0)
27756 size_t j = rs6000_opt_vars[i].global_offset;
27757 ((int *) &global_options)[j] = !invert;
27758 error_p = false;
27759 break;
27764 if (error_p)
27766 const char *eprefix, *esuffix;
27768 ret = false;
27769 if (attr_p)
27771 eprefix = "__attribute__((__target__(";
27772 esuffix = ")))";
27774 else
27776 eprefix = "#pragma GCC target ";
27777 esuffix = "";
27780 if (cpu_opt)
27781 error ("invalid cpu \"%s\" for %s\"%s\"%s", cpu_opt, eprefix,
27782 q, esuffix);
27783 else if (not_valid_p)
27784 error ("%s\"%s\"%s is not allowed", eprefix, q, esuffix);
27785 else
27786 error ("%s\"%s\"%s is invalid", eprefix, q, esuffix);
27791 else if (TREE_CODE (args) == TREE_LIST)
27795 tree value = TREE_VALUE (args);
27796 if (value)
27798 bool ret2 = rs6000_inner_target_options (value, attr_p);
27799 if (!ret2)
27800 ret = false;
27802 args = TREE_CHAIN (args);
27804 while (args != NULL_TREE);
27807 else
27808 gcc_unreachable ();
27810 return ret;
27813 /* Print out the target options as a list for -mdebug=target. */
27815 static void
27816 rs6000_debug_target_options (tree args, const char *prefix)
27818 if (args == NULL_TREE)
27819 fprintf (stderr, "%s<NULL>", prefix);
27821 else if (TREE_CODE (args) == STRING_CST)
27823 char *p = ASTRDUP (TREE_STRING_POINTER (args));
27824 char *q;
27826 while ((q = strtok (p, ",")) != NULL)
27828 p = NULL;
27829 fprintf (stderr, "%s\"%s\"", prefix, q);
27830 prefix = ", ";
27834 else if (TREE_CODE (args) == TREE_LIST)
27838 tree value = TREE_VALUE (args);
27839 if (value)
27841 rs6000_debug_target_options (value, prefix);
27842 prefix = ", ";
27844 args = TREE_CHAIN (args);
27846 while (args != NULL_TREE);
27849 else
27850 gcc_unreachable ();
27852 return;
27856 /* Hook to validate attribute((target("..."))). */
27858 static bool
27859 rs6000_valid_attribute_p (tree fndecl,
27860 tree ARG_UNUSED (name),
27861 tree args,
27862 int flags)
27864 struct cl_target_option cur_target;
27865 bool ret;
27866 tree old_optimize = build_optimization_node ();
27867 tree new_target, new_optimize;
27868 tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
27870 gcc_assert ((fndecl != NULL_TREE) && (args != NULL_TREE));
27872 if (TARGET_DEBUG_TARGET)
27874 tree tname = DECL_NAME (fndecl);
27875 fprintf (stderr, "\n==================== rs6000_valid_attribute_p:\n");
27876 if (tname)
27877 fprintf (stderr, "function: %.*s\n",
27878 (int) IDENTIFIER_LENGTH (tname),
27879 IDENTIFIER_POINTER (tname));
27880 else
27881 fprintf (stderr, "function: unknown\n");
27883 fprintf (stderr, "args:");
27884 rs6000_debug_target_options (args, " ");
27885 fprintf (stderr, "\n");
27887 if (flags)
27888 fprintf (stderr, "flags: 0x%x\n", flags);
27890 fprintf (stderr, "--------------------\n");
27893 old_optimize = build_optimization_node ();
27894 func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
27896 /* If the function changed the optimization levels as well as setting target
27897 options, start with the optimizations specified. */
27898 if (func_optimize && func_optimize != old_optimize)
27899 cl_optimization_restore (&global_options,
27900 TREE_OPTIMIZATION (func_optimize));
27902 /* The target attributes may also change some optimization flags, so update
27903 the optimization options if necessary. */
27904 cl_target_option_save (&cur_target, &global_options);
27905 rs6000_cpu_index = rs6000_tune_index = -1;
27906 ret = rs6000_inner_target_options (args, true);
27908 /* Set up any additional state. */
27909 if (ret)
27911 ret = rs6000_option_override_internal (false);
27912 new_target = build_target_option_node ();
27914 else
27915 new_target = NULL;
27917 new_optimize = build_optimization_node ();
27919 if (!new_target)
27920 ret = false;
27922 else if (fndecl)
27924 DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target;
27926 if (old_optimize != new_optimize)
27927 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
27930 cl_target_option_restore (&global_options, &cur_target);
27932 if (old_optimize != new_optimize)
27933 cl_optimization_restore (&global_options,
27934 TREE_OPTIMIZATION (old_optimize));
27936 return ret;
27940 /* Hook to validate the current #pragma GCC target and set the state, and
27941 update the macros based on what was changed. If ARGS is NULL, then
27942 POP_TARGET is used to reset the options. */
27944 bool
27945 rs6000_pragma_target_parse (tree args, tree pop_target)
27947 tree cur_tree;
27948 bool ret;
27950 if (TARGET_DEBUG_TARGET)
27952 fprintf (stderr, "\n==================== rs6000_pragma_target_parse\n");
27953 fprintf (stderr, "args:");
27954 rs6000_debug_target_options (args, " ");
27955 fprintf (stderr, "\n");
27957 if (pop_target)
27959 fprintf (stderr, "pop_target:\n");
27960 debug_tree (pop_target);
27962 else
27963 fprintf (stderr, "pop_target: <NULL>\n");
27965 fprintf (stderr, "--------------------\n");
27968 if (! args)
27970 ret = true;
27971 cur_tree = ((pop_target)
27972 ? pop_target
27973 : target_option_default_node);
27974 cl_target_option_restore (&global_options,
27975 TREE_TARGET_OPTION (cur_tree));
27977 else
27979 rs6000_cpu_index = rs6000_tune_index = -1;
27980 ret = rs6000_inner_target_options (args, false);
27981 cur_tree = build_target_option_node ();
27983 if (!cur_tree)
27984 ret = false;
27987 if (cur_tree)
27988 target_option_current_node = cur_tree;
27990 return ret;
27994 /* Remember the last target of rs6000_set_current_function. */
27995 static GTY(()) tree rs6000_previous_fndecl;
27997 /* Establish appropriate back-end context for processing the function
27998 FNDECL. The argument might be NULL to indicate processing at top
27999 level, outside of any function scope. */
28000 static void
28001 rs6000_set_current_function (tree fndecl)
28003 tree old_tree = (rs6000_previous_fndecl
28004 ? DECL_FUNCTION_SPECIFIC_TARGET (rs6000_previous_fndecl)
28005 : NULL_TREE);
28007 tree new_tree = (fndecl
28008 ? DECL_FUNCTION_SPECIFIC_TARGET (fndecl)
28009 : NULL_TREE);
28011 if (TARGET_DEBUG_TARGET)
28013 bool print_final = false;
28014 fprintf (stderr, "\n==================== rs6000_set_current_function");
28016 if (fndecl)
28017 fprintf (stderr, ", fndecl %s (%p)",
28018 (DECL_NAME (fndecl)
28019 ? IDENTIFIER_POINTER (DECL_NAME (fndecl))
28020 : "<unknown>"), (void *)fndecl);
28022 if (rs6000_previous_fndecl)
28023 fprintf (stderr, ", prev_fndecl (%p)", (void *)rs6000_previous_fndecl);
28025 fprintf (stderr, "\n");
28026 if (new_tree)
28028 fprintf (stderr, "\nnew fndecl target specific options:\n");
28029 debug_tree (new_tree);
28030 print_final = true;
28033 if (old_tree)
28035 fprintf (stderr, "\nold fndecl target specific options:\n");
28036 debug_tree (old_tree);
28037 print_final = true;
28040 if (print_final)
28041 fprintf (stderr, "--------------------\n");
28044 /* Only change the context if the function changes. This hook is called
28045 several times in the course of compiling a function, and we don't want to
28046 slow things down too much or call target_reinit when it isn't safe. */
28047 if (fndecl && fndecl != rs6000_previous_fndecl)
28049 rs6000_previous_fndecl = fndecl;
28050 if (old_tree == new_tree)
28053 else if (new_tree)
28055 cl_target_option_restore (&global_options,
28056 TREE_TARGET_OPTION (new_tree));
28057 target_reinit ();
28060 else if (old_tree)
28062 struct cl_target_option *def
28063 = TREE_TARGET_OPTION (target_option_current_node);
28065 cl_target_option_restore (&global_options, def);
28066 target_reinit ();
28072 /* Save the current options */
28074 static void
28075 rs6000_function_specific_save (struct cl_target_option *ptr)
28077 ptr->rs6000_target_flags_explicit = target_flags_explicit;
28080 /* Restore the current options */
28082 static void
28083 rs6000_function_specific_restore (struct cl_target_option *ptr)
28085 target_flags_explicit = ptr->rs6000_target_flags_explicit;
28086 (void) rs6000_option_override_internal (false);
28089 /* Print the current options */
28091 static void
28092 rs6000_function_specific_print (FILE *file, int indent,
28093 struct cl_target_option *ptr)
28095 size_t i;
28096 int flags = ptr->x_target_flags;
28098 /* Print the various mask options. */
28099 for (i = 0; i < ARRAY_SIZE (rs6000_opt_masks); i++)
28100 if ((flags & rs6000_opt_masks[i].mask) != 0)
28102 flags &= ~ rs6000_opt_masks[i].mask;
28103 fprintf (file, "%*s-m%s%s\n", indent, "",
28104 rs6000_opt_masks[i].invert ? "no-" : "",
28105 rs6000_opt_masks[i].name);
28108 /* Print the various options that are variables. */
28109 for (i = 0; i < ARRAY_SIZE (rs6000_opt_vars); i++)
28111 size_t j = rs6000_opt_vars[i].target_offset;
28112 if (((signed char *) ptr)[j])
28113 fprintf (file, "%*s-m%s\n", indent, "",
28114 rs6000_opt_vars[i].name);
28119 /* Hook to determine if one function can safely inline another. */
28121 static bool
28122 rs6000_can_inline_p (tree caller, tree callee)
28124 bool ret = false;
28125 tree caller_tree = DECL_FUNCTION_SPECIFIC_TARGET (caller);
28126 tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (callee);
28128 /* If callee has no option attributes, then it is ok to inline. */
28129 if (!callee_tree)
28130 ret = true;
28132 /* If caller has no option attributes, but callee does then it is not ok to
28133 inline. */
28134 else if (!caller_tree)
28135 ret = false;
28137 else
28139 struct cl_target_option *caller_opts = TREE_TARGET_OPTION (caller_tree);
28140 struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree);
28142 /* Callee's options should a subset of the caller's, i.e. a vsx function
28143 can inline an altivec function but a non-vsx function can't inline a
28144 vsx function. */
28145 if ((caller_opts->x_target_flags & callee_opts->x_target_flags)
28146 == callee_opts->x_target_flags)
28147 ret = true;
28150 if (TARGET_DEBUG_TARGET)
28151 fprintf (stderr, "rs6000_can_inline_p:, caller %s, callee %s, %s inline\n",
28152 (DECL_NAME (caller)
28153 ? IDENTIFIER_POINTER (DECL_NAME (caller))
28154 : "<unknown>"),
28155 (DECL_NAME (callee)
28156 ? IDENTIFIER_POINTER (DECL_NAME (callee))
28157 : "<unknown>"),
28158 (ret ? "can" : "cannot"));
28160 return ret;
28163 /* Allocate a stack temp and fixup the address so it meets the particular
28164 memory requirements (either offetable or REG+REG addressing). */
28167 rs6000_allocate_stack_temp (enum machine_mode mode,
28168 bool offsettable_p,
28169 bool reg_reg_p)
28171 rtx stack = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
28172 rtx addr = XEXP (stack, 0);
28173 int strict_p = (reload_in_progress || reload_completed);
28175 if (!legitimate_indirect_address_p (addr, strict_p))
28177 if (offsettable_p
28178 && !rs6000_legitimate_offset_address_p (mode, addr, strict_p))
28179 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
28181 else if (reg_reg_p && !legitimate_indexed_address_p (addr, strict_p))
28182 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
28185 return stack;
28188 /* Given a memory reference, if it is not a reg or reg+reg addressing, convert
28189 to such a form to deal with memory reference instructions like STFIWX that
28190 only take reg+reg addressing. */
28193 rs6000_address_for_fpconvert (rtx x)
28195 int strict_p = (reload_in_progress || reload_completed);
28196 rtx addr;
28198 gcc_assert (MEM_P (x));
28199 addr = XEXP (x, 0);
28200 if (! legitimate_indirect_address_p (addr, strict_p)
28201 && ! legitimate_indexed_address_p (addr, strict_p))
28203 if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)
28205 rtx reg = XEXP (addr, 0);
28206 HOST_WIDE_INT size = GET_MODE_SIZE (GET_MODE (x));
28207 rtx size_rtx = GEN_INT ((GET_CODE (addr) == PRE_DEC) ? -size : size);
28208 gcc_assert (REG_P (reg));
28209 emit_insn (gen_add3_insn (reg, reg, size_rtx));
28210 addr = reg;
28212 else if (GET_CODE (addr) == PRE_MODIFY)
28214 rtx reg = XEXP (addr, 0);
28215 rtx expr = XEXP (addr, 1);
28216 gcc_assert (REG_P (reg));
28217 gcc_assert (GET_CODE (expr) == PLUS);
28218 emit_insn (gen_add3_insn (reg, XEXP (expr, 0), XEXP (expr, 1)));
28219 addr = reg;
28222 x = replace_equiv_address (x, copy_addr_to_reg (addr));
28225 return x;
28228 /* Given a memory reference, if it is not in the form for altivec memory
28229 reference instructions (i.e. reg or reg+reg addressing with AND of -16),
28230 convert to the altivec format. */
28233 rs6000_address_for_altivec (rtx x)
28235 gcc_assert (MEM_P (x));
28236 if (!altivec_indexed_or_indirect_operand (x, GET_MODE (x)))
28238 rtx addr = XEXP (x, 0);
28239 int strict_p = (reload_in_progress || reload_completed);
28241 if (!legitimate_indexed_address_p (addr, strict_p)
28242 && !legitimate_indirect_address_p (addr, strict_p))
28243 addr = copy_to_mode_reg (Pmode, addr);
28245 addr = gen_rtx_AND (Pmode, addr, GEN_INT (-16));
28246 x = change_address (x, GET_MODE (x), addr);
28249 return x;
28253 #include "gt-rs6000.h"