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/>. */
25 #include "coretypes.h"
29 #include "hard-reg-set.h"
30 #include "insn-config.h"
31 #include "conditions.h"
32 #include "insn-attr.h"
42 #include "basic-block.h"
43 #include "integrate.h"
44 #include "diagnostic-core.h"
50 #include "target-def.h"
51 #include "langhooks.h"
53 #include "cfglayout.h"
55 #include "sched-int.h"
57 #include "tree-flow.h"
60 #include "tm-constrs.h"
62 #include "xcoffout.h" /* get declarations of xcoff_*_section_name */
65 #include "gstab.h" /* for N_SLINE */
68 #ifndef TARGET_NO_PROTOTYPE
69 #define TARGET_NO_PROTOTYPE 0
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
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;
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. */
129 /* Cache lr_save_p after expansion of builtin_eh_return. */
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;
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;
156 static const char *rs6000_abi_name;
157 static const char *rs6000_sdata_name;
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;
171 /* Counter for labels which are to be placed in .fixup. */
172 int fixuplabelno = 0;
175 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
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;
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 */
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. */
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. */
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
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
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. */
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. */
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
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
340 const struct processor_costs *rs6000_cost;
342 /* Processor costs (relative to an add) */
344 /* Instruction size costs on 32bit processors. */
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. */
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 */
382 /* Instruction costs on RIOS1 processors. */
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 */
401 /* Instruction costs on RIOS2 processors. */
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 */
420 /* Instruction costs on RS64A processors. */
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 */
439 /* Instruction costs on MPCCORE processors. */
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 */
458 /* Instruction costs on PPC403 processors. */
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 */
477 /* Instruction costs on PPC405 processors. */
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 */
496 /* Instruction costs on PPC440 processors. */
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 */
515 /* Instruction costs on PPC476 processors. */
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 */
534 /* Instruction costs on PPC601 processors. */
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 */
553 /* Instruction costs on PPC603 processors. */
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 */
572 /* Instruction costs on PPC604 processors. */
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 */
591 /* Instruction costs on PPC604e processors. */
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 */
610 /* Instruction costs on PPC620 processors. */
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 */
629 /* Instruction costs on PPC630 processors. */
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 */
648 /* Instruction costs on Cell processor. */
649 /* COSTS_N_INSNS (1) ~ one add. */
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 */
668 /* Instruction costs on PPC750 and PPC7400 processors. */
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 */
687 /* Instruction costs on PPC7450 processors. */
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 */
706 /* Instruction costs on PPC8540 processors. */
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 */
722 1, /* prefetch streams /*/
725 /* Instruction costs on E300C2 and E300C3 cores. */
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 */
741 1, /* prefetch streams /*/
744 /* Instruction costs on PPCE500MC processors. */
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 */
760 1, /* prefetch streams /*/
763 /* Instruction costs on PPCE500MC64 processors. */
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 */
779 1, /* prefetch streams /*/
782 /* Instruction costs on AppliedMicro Titan processors. */
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 */
798 1, /* prefetch streams /*/
801 /* Instruction costs on POWER4 and POWER5 processors. */
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 */
817 8, /* prefetch streams /*/
820 /* Instruction costs on POWER6 processors. */
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 */
836 16, /* prefetch streams */
839 /* Instruction costs on POWER7 processors. */
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 */
855 12, /* prefetch streams */
858 /* Instruction costs on POWER A2 processors. */
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 */
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,
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);
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,
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);
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)
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);
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);
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
1026 static int rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt,
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 *,
1109 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
1112 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
1113 const_tree, HOST_WIDE_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,
1119 static rtx rs6000_function_arg (CUMULATIVE_ARGS *, enum machine_mode,
1121 static unsigned int rs6000_function_arg_boundary (enum machine_mode,
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,
1127 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
1129 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
1131 static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree);
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);
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,
1148 static tree rs6000_stack_protect_fail (void);
1150 static rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, int, int,
1153 static rtx rs6000_debug_legitimize_reload_address (rtx, enum machine_mode, int,
1156 rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode, 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,
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,
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,
1184 static bool rs6000_debug_secondary_memory_needed (enum reg_class,
1188 bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class,
1190 = rs6000_secondary_memory_needed;
1192 static bool rs6000_cannot_change_mode_class (enum machine_mode,
1195 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode,
1199 bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode,
1202 = rs6000_cannot_change_mode_class;
1204 static reg_class_t rs6000_secondary_reload (bool, rtx, reg_class_t,
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. */
1223 enum machine_mode key_mode;
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
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",
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",
1269 /* SPE registers. */
1270 "spe_acc", "spefscr",
1271 /* Soft frame pointer. */
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",
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",
1295 /* SPE registers. */
1296 "spe_acc", "spefscr",
1297 /* Soft frame pointer. */
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 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute },
1308 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1309 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1310 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1311 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1312 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1313 SUBTARGET_ATTRIBUTE_TABLE,
1315 { NULL, 0, 0, false, false, false, NULL }
1318 /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */
1319 static const struct default_options rs6000_option_optimization_table[] =
1321 { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
1322 { OPT_LEVELS_NONE, 0, NULL, 0 }
1325 #ifndef MASK_STRICT_ALIGN
1326 #define MASK_STRICT_ALIGN 0
1328 #ifndef TARGET_PROFILE_KERNEL
1329 #define TARGET_PROFILE_KERNEL 0
1332 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1333 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1335 /* Initialize the GCC target structure. */
1336 #undef TARGET_ATTRIBUTE_TABLE
1337 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1338 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1339 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1340 #undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P
1341 #define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P rs6000_attribute_takes_identifier_p
1343 #undef TARGET_ASM_ALIGNED_DI_OP
1344 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1346 /* Default unaligned ops are only provided for ELF. Find the ops needed
1347 for non-ELF systems. */
1348 #ifndef OBJECT_FORMAT_ELF
1350 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1352 #undef TARGET_ASM_UNALIGNED_HI_OP
1353 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1354 #undef TARGET_ASM_UNALIGNED_SI_OP
1355 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1356 #undef TARGET_ASM_UNALIGNED_DI_OP
1357 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1360 #undef TARGET_ASM_UNALIGNED_HI_OP
1361 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1362 #undef TARGET_ASM_UNALIGNED_SI_OP
1363 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1364 #undef TARGET_ASM_UNALIGNED_DI_OP
1365 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1366 #undef TARGET_ASM_ALIGNED_DI_OP
1367 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1371 /* This hook deals with fixups for relocatable code and DI-mode objects
1373 #undef TARGET_ASM_INTEGER
1374 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1376 #ifdef HAVE_GAS_HIDDEN
1377 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1378 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1381 #undef TARGET_HAVE_TLS
1382 #define TARGET_HAVE_TLS HAVE_AS_TLS
1384 #undef TARGET_CANNOT_FORCE_CONST_MEM
1385 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1387 #undef TARGET_DELEGITIMIZE_ADDRESS
1388 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1390 #undef TARGET_ASM_FUNCTION_PROLOGUE
1391 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1392 #undef TARGET_ASM_FUNCTION_EPILOGUE
1393 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1395 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
1396 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA rs6000_output_addr_const_extra
1398 #undef TARGET_LEGITIMIZE_ADDRESS
1399 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1401 #undef TARGET_SCHED_VARIABLE_ISSUE
1402 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1404 #undef TARGET_SCHED_ISSUE_RATE
1405 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1406 #undef TARGET_SCHED_ADJUST_COST
1407 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1408 #undef TARGET_SCHED_ADJUST_PRIORITY
1409 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1410 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1411 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1412 #undef TARGET_SCHED_INIT
1413 #define TARGET_SCHED_INIT rs6000_sched_init
1414 #undef TARGET_SCHED_FINISH
1415 #define TARGET_SCHED_FINISH rs6000_sched_finish
1416 #undef TARGET_SCHED_REORDER
1417 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1418 #undef TARGET_SCHED_REORDER2
1419 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1421 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1422 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1424 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1425 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1427 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1428 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1429 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1430 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1431 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1432 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1433 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1434 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1436 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1437 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1438 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1439 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1440 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1441 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1442 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1443 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1444 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1445 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1446 #undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
1447 #define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT \
1448 rs6000_builtin_support_vector_misalignment
1449 #undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE
1450 #define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1451 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
1452 #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
1453 rs6000_builtin_vectorization_cost
1454 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
1455 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE \
1456 rs6000_preferred_simd_mode
1458 #undef TARGET_INIT_BUILTINS
1459 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1460 #undef TARGET_BUILTIN_DECL
1461 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1463 #undef TARGET_EXPAND_BUILTIN
1464 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1466 #undef TARGET_MANGLE_TYPE
1467 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1469 #undef TARGET_INIT_LIBFUNCS
1470 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1473 #undef TARGET_BINDS_LOCAL_P
1474 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1477 #undef TARGET_MS_BITFIELD_LAYOUT_P
1478 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1480 #undef TARGET_ASM_OUTPUT_MI_THUNK
1481 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1483 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1484 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1486 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1487 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1489 #undef TARGET_INVALID_WITHIN_DOLOOP
1490 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1492 #undef TARGET_REGISTER_MOVE_COST
1493 #define TARGET_REGISTER_MOVE_COST rs6000_register_move_cost
1494 #undef TARGET_MEMORY_MOVE_COST
1495 #define TARGET_MEMORY_MOVE_COST rs6000_memory_move_cost
1496 #undef TARGET_RTX_COSTS
1497 #define TARGET_RTX_COSTS rs6000_rtx_costs
1498 #undef TARGET_ADDRESS_COST
1499 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1501 #undef TARGET_DWARF_REGISTER_SPAN
1502 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1504 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1505 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1507 /* On rs6000, function arguments are promoted, as are function return
1509 #undef TARGET_PROMOTE_FUNCTION_MODE
1510 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1512 #undef TARGET_RETURN_IN_MEMORY
1513 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1515 #undef TARGET_SETUP_INCOMING_VARARGS
1516 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1518 /* Always strict argument naming on rs6000. */
1519 #undef TARGET_STRICT_ARGUMENT_NAMING
1520 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1521 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1522 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1523 #undef TARGET_SPLIT_COMPLEX_ARG
1524 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1525 #undef TARGET_MUST_PASS_IN_STACK
1526 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1527 #undef TARGET_PASS_BY_REFERENCE
1528 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1529 #undef TARGET_ARG_PARTIAL_BYTES
1530 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1531 #undef TARGET_FUNCTION_ARG_ADVANCE
1532 #define TARGET_FUNCTION_ARG_ADVANCE rs6000_function_arg_advance
1533 #undef TARGET_FUNCTION_ARG
1534 #define TARGET_FUNCTION_ARG rs6000_function_arg
1535 #undef TARGET_FUNCTION_ARG_BOUNDARY
1536 #define TARGET_FUNCTION_ARG_BOUNDARY rs6000_function_arg_boundary
1538 #undef TARGET_BUILD_BUILTIN_VA_LIST
1539 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1541 #undef TARGET_EXPAND_BUILTIN_VA_START
1542 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1544 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1545 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1547 #undef TARGET_EH_RETURN_FILTER_MODE
1548 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1550 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1551 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1553 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1554 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1556 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1557 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1559 #undef TARGET_HANDLE_OPTION
1560 #define TARGET_HANDLE_OPTION rs6000_handle_option
1562 #undef TARGET_ASM_LOOP_ALIGN_MAX_SKIP
1563 #define TARGET_ASM_LOOP_ALIGN_MAX_SKIP rs6000_loop_align_max_skip
1565 #undef TARGET_OPTION_OVERRIDE
1566 #define TARGET_OPTION_OVERRIDE rs6000_option_override
1568 #undef TARGET_OPTION_INIT_STRUCT
1569 #define TARGET_OPTION_INIT_STRUCT rs6000_option_init_struct
1571 #undef TARGET_OPTION_DEFAULT_PARAMS
1572 #define TARGET_OPTION_DEFAULT_PARAMS rs6000_option_default_params
1574 #undef TARGET_OPTION_OPTIMIZATION_TABLE
1575 #define TARGET_OPTION_OPTIMIZATION_TABLE rs6000_option_optimization_table
1577 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1578 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1579 rs6000_builtin_vectorized_function
1581 #undef TARGET_DEFAULT_TARGET_FLAGS
1582 #define TARGET_DEFAULT_TARGET_FLAGS \
1585 #undef TARGET_STACK_PROTECT_FAIL
1586 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1588 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1589 The PowerPC architecture requires only weak consistency among
1590 processors--that is, memory accesses between processors need not be
1591 sequentially consistent and memory accesses among processors can occur
1592 in any order. The ability to order memory accesses weakly provides
1593 opportunities for more efficient use of the system bus. Unless a
1594 dependency exists, the 604e allows read operations to precede store
1596 #undef TARGET_RELAXED_ORDERING
1597 #define TARGET_RELAXED_ORDERING true
1600 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1601 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1604 /* Use a 32-bit anchor range. This leads to sequences like:
1606 addis tmp,anchor,high
1609 where tmp itself acts as an anchor, and can be shared between
1610 accesses to the same 64k page. */
1611 #undef TARGET_MIN_ANCHOR_OFFSET
1612 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1613 #undef TARGET_MAX_ANCHOR_OFFSET
1614 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1615 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1616 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1618 #undef TARGET_BUILTIN_RECIPROCAL
1619 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1621 #undef TARGET_EXPAND_TO_RTL_HOOK
1622 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1624 #undef TARGET_INSTANTIATE_DECLS
1625 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1627 #undef TARGET_SECONDARY_RELOAD
1628 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1630 #undef TARGET_IRA_COVER_CLASSES
1631 #define TARGET_IRA_COVER_CLASSES rs6000_ira_cover_classes
1633 #undef TARGET_LEGITIMATE_ADDRESS_P
1634 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1636 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
1637 #define TARGET_MODE_DEPENDENT_ADDRESS_P rs6000_mode_dependent_address_p
1639 #undef TARGET_CAN_ELIMINATE
1640 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1642 #undef TARGET_CONDITIONAL_REGISTER_USAGE
1643 #define TARGET_CONDITIONAL_REGISTER_USAGE rs6000_conditional_register_usage
1645 #undef TARGET_TRAMPOLINE_INIT
1646 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1648 #undef TARGET_FUNCTION_VALUE
1649 #define TARGET_FUNCTION_VALUE rs6000_function_value
1651 #undef TARGET_OPTION_VALID_ATTRIBUTE_P
1652 #define TARGET_OPTION_VALID_ATTRIBUTE_P rs6000_valid_attribute_p
1654 #undef TARGET_OPTION_SAVE
1655 #define TARGET_OPTION_SAVE rs6000_function_specific_save
1657 #undef TARGET_OPTION_RESTORE
1658 #define TARGET_OPTION_RESTORE rs6000_function_specific_restore
1660 #undef TARGET_OPTION_PRINT
1661 #define TARGET_OPTION_PRINT rs6000_function_specific_print
1663 #undef TARGET_CAN_INLINE_P
1664 #define TARGET_CAN_INLINE_P rs6000_can_inline_p
1666 #undef TARGET_SET_CURRENT_FUNCTION
1667 #define TARGET_SET_CURRENT_FUNCTION rs6000_set_current_function
1669 struct gcc_target targetm = TARGET_INITIALIZER;
1672 /* Simplifications for entries below. */
1675 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
1676 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
1679 /* Some OSs don't support saving the high part of 64-bit registers on context
1680 switch. Other OSs don't support saving Altivec registers. On those OSs, we
1681 don't touch the MASK_POWERPC64 or MASK_ALTIVEC settings; if the user wants
1682 either, the user must explicitly specify them and we won't interfere with
1683 the user's specification. */
1686 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
1687 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
1688 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
1689 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
1690 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
1691 | MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE
1692 | MASK_RECIP_PRECISION)
1695 /* Masks for instructions set at various powerpc ISAs. */
1697 ISA_2_1_MASKS = MASK_MFCRF,
1698 ISA_2_2_MASKS = (ISA_2_1_MASKS | MASK_POPCNTB),
1699 ISA_2_4_MASKS = (ISA_2_2_MASKS | MASK_FPRND),
1701 /* For ISA 2.05, do not add MFPGPR, since it isn't in ISA 2.06, and don't add
1702 ALTIVEC, since in general it isn't a win on power6. In ISA 2.04, fsel,
1703 fre, fsqrt, etc. were no longer documented as optional. Group masks by
1704 server and embedded. */
1705 ISA_2_5_MASKS_EMBEDDED = (ISA_2_2_MASKS | MASK_CMPB | MASK_RECIP_PRECISION
1706 | MASK_PPC_GFXOPT | MASK_PPC_GPOPT),
1707 ISA_2_5_MASKS_SERVER = (ISA_2_5_MASKS_EMBEDDED | MASK_DFP),
1709 /* For ISA 2.06, don't add ISEL, since in general it isn't a win, but
1710 altivec is a win so enable it. */
1711 ISA_2_6_MASKS_EMBEDDED = (ISA_2_5_MASKS_EMBEDDED | MASK_POPCNTD),
1712 ISA_2_6_MASKS_SERVER = (ISA_2_5_MASKS_SERVER | MASK_POPCNTD | MASK_ALTIVEC
1716 /* This table occasionally claims that a processor does not support a
1717 particular feature even though it does, but the feature is slower than the
1718 alternative. Thus, it shouldn't be relied on as a complete description of
1719 the processor's support.
1721 Please keep this list in order, and don't forget to update the documentation
1722 in invoke.texi when adding a new processor or flag. */
1726 const char *const name; /* Canonical processor name. */
1727 const enum processor_type processor; /* Processor type enum value. */
1728 const int target_enable; /* Target flags to enable. */
1731 static struct rs6000_ptt const processor_target_table[] =
1733 {"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1734 {"403", PROCESSOR_PPC403,
1735 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
1736 {"405", PROCESSOR_PPC405,
1737 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1738 {"405fp", PROCESSOR_PPC405,
1739 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1740 {"440", PROCESSOR_PPC440,
1741 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1742 {"440fp", PROCESSOR_PPC440,
1743 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1744 {"464", PROCESSOR_PPC440,
1745 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1746 {"464fp", PROCESSOR_PPC440,
1747 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1748 {"476", PROCESSOR_PPC476,
1749 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_PPC_GFXOPT | MASK_MFCRF
1750 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
1751 {"476fp", PROCESSOR_PPC476,
1752 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB
1753 | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
1754 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
1755 {"601", PROCESSOR_PPC601,
1756 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
1757 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1758 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1759 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1760 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1761 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1762 {"620", PROCESSOR_PPC620,
1763 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1764 {"630", PROCESSOR_PPC630,
1765 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1766 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1767 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
1768 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
1769 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1770 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1771 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1772 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1773 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
1775 /* 8548 has a dummy entry for now. */
1776 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
1778 {"a2", PROCESSOR_PPCA2,
1779 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_POPCNTB
1780 | MASK_CMPB | MASK_NO_UPDATE },
1781 {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1782 {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK},
1783 {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT
1785 {"e500mc64", PROCESSOR_PPCE500MC64, POWERPC_BASE_MASK | MASK_POWERPC64
1786 | MASK_PPC_GFXOPT | MASK_ISEL},
1787 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1788 {"970", PROCESSOR_POWER4,
1789 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1790 {"cell", PROCESSOR_CELL,
1791 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1792 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
1793 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1794 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1795 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
1796 {"G5", PROCESSOR_POWER4,
1797 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1798 {"titan", PROCESSOR_TITAN,
1799 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1800 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1801 {"power2", PROCESSOR_POWER,
1802 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
1803 {"power3", PROCESSOR_PPC630,
1804 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1805 {"power4", PROCESSOR_POWER4,
1806 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1808 {"power5", PROCESSOR_POWER5,
1809 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1810 | MASK_MFCRF | MASK_POPCNTB},
1811 {"power5+", PROCESSOR_POWER5,
1812 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1813 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
1814 {"power6", PROCESSOR_POWER6,
1815 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1816 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
1817 | MASK_RECIP_PRECISION},
1818 {"power6x", PROCESSOR_POWER6,
1819 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1820 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
1821 | MASK_MFPGPR | MASK_RECIP_PRECISION},
1822 {"power7", PROCESSOR_POWER7, /* Don't add MASK_ISEL by default */
1823 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
1824 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD
1825 | MASK_VSX | MASK_RECIP_PRECISION},
1826 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
1827 {"powerpc64", PROCESSOR_POWERPC64,
1828 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1829 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1830 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1831 {"rios2", PROCESSOR_RIOS2,
1832 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
1833 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1834 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1835 {"rs64", PROCESSOR_RS64A,
1836 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
1839 /* Look up a processor name for -mcpu=xxx and -mtune=xxx. Return -1 if the
1843 rs6000_cpu_name_lookup (const char *name)
1849 for (i = 0; i < ARRAY_SIZE (processor_target_table); i++)
1850 if (! strcmp (name, processor_target_table[i].name))
1858 /* Return number of consecutive hard regs needed starting at reg REGNO
1859 to hold something of mode MODE.
1860 This is ordinarily the length in words of a value of mode MODE
1861 but can be less for certain modes in special long registers.
1863 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1864 scalar instructions. The upper 32 bits are only available to the
1867 POWER and PowerPC GPRs hold 32 bits worth;
1868 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1871 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1873 unsigned HOST_WIDE_INT reg_size;
1875 if (FP_REGNO_P (regno))
1876 reg_size = (VECTOR_MEM_VSX_P (mode)
1877 ? UNITS_PER_VSX_WORD
1878 : UNITS_PER_FP_WORD);
1880 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1881 reg_size = UNITS_PER_SPE_WORD;
1883 else if (ALTIVEC_REGNO_P (regno))
1884 reg_size = UNITS_PER_ALTIVEC_WORD;
1886 /* The value returned for SCmode in the E500 double case is 2 for
1887 ABI compatibility; storing an SCmode value in a single register
1888 would require function_arg and rs6000_spe_function_arg to handle
1889 SCmode so as to pass the value correctly in a pair of
1891 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1892 && !DECIMAL_FLOAT_MODE_P (mode))
1893 reg_size = UNITS_PER_FP_WORD;
1896 reg_size = UNITS_PER_WORD;
1898 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1901 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1904 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1906 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1908 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1909 implementations. Don't allow an item to be split between a FP register
1910 and an Altivec register. */
1911 if (VECTOR_MEM_VSX_P (mode))
1913 if (FP_REGNO_P (regno))
1914 return FP_REGNO_P (last_regno);
1916 if (ALTIVEC_REGNO_P (regno))
1917 return ALTIVEC_REGNO_P (last_regno);
1920 /* The GPRs can hold any mode, but values bigger than one register
1921 cannot go past R31. */
1922 if (INT_REGNO_P (regno))
1923 return INT_REGNO_P (last_regno);
1925 /* The float registers (except for VSX vector modes) can only hold floating
1926 modes and DImode. This excludes the 32-bit decimal float mode for
1928 if (FP_REGNO_P (regno))
1930 if (SCALAR_FLOAT_MODE_P (mode)
1931 && (mode != TDmode || (regno % 2) == 0)
1932 && FP_REGNO_P (last_regno))
1935 if (GET_MODE_CLASS (mode) == MODE_INT
1936 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1939 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1940 && PAIRED_VECTOR_MODE (mode))
1946 /* The CR register can only hold CC modes. */
1947 if (CR_REGNO_P (regno))
1948 return GET_MODE_CLASS (mode) == MODE_CC;
1950 if (CA_REGNO_P (regno))
1951 return mode == BImode;
1953 /* AltiVec only in AldyVec registers. */
1954 if (ALTIVEC_REGNO_P (regno))
1955 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1957 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1958 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1961 /* We cannot put TImode anywhere except general register and it must be able
1962 to fit within the register set. In the future, allow TImode in the
1963 Altivec or VSX registers. */
1965 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1968 /* Print interesting facts about registers. */
1970 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1974 for (r = first_regno; r <= last_regno; ++r)
1976 const char *comma = "";
1979 if (first_regno == last_regno)
1980 fprintf (stderr, "%s:\t", reg_name);
1982 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1985 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1986 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1990 fprintf (stderr, ",\n\t");
1995 if (rs6000_hard_regno_nregs[m][r] > 1)
1996 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
1997 rs6000_hard_regno_nregs[m][r]);
1999 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
2004 if (call_used_regs[r])
2008 fprintf (stderr, ",\n\t");
2013 len += fprintf (stderr, "%s%s", comma, "call-used");
2021 fprintf (stderr, ",\n\t");
2026 len += fprintf (stderr, "%s%s", comma, "fixed");
2032 fprintf (stderr, ",\n\t");
2036 fprintf (stderr, "%sregno = %d\n", comma, r);
2040 #define DEBUG_FMT_D "%-32s= %d\n"
2041 #define DEBUG_FMT_S "%-32s= %s\n"
2043 /* Print various interesting information with -mdebug=reg. */
2045 rs6000_debug_reg_global (void)
2047 static const char *const tf[2] = { "false", "true" };
2048 const char *nl = (const char *)0;
2050 char costly_num[20];
2052 const char *costly_str;
2053 const char *nop_str;
2054 const char *trace_str;
2055 const char *abi_str;
2056 const char *cmodel_str;
2058 /* Map enum rs6000_vector to string. */
2059 static const char *rs6000_debug_vector_unit[] = {
2068 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
2069 LAST_VIRTUAL_REGISTER);
2070 rs6000_debug_reg_print (0, 31, "gr");
2071 rs6000_debug_reg_print (32, 63, "fp");
2072 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
2075 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
2076 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
2077 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
2078 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
2079 rs6000_debug_reg_print (CA_REGNO, CA_REGNO, "ca");
2080 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
2081 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
2082 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
2083 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
2087 "d reg_class = %s\n"
2088 "f reg_class = %s\n"
2089 "v reg_class = %s\n"
2090 "wa reg_class = %s\n"
2091 "wd reg_class = %s\n"
2092 "wf reg_class = %s\n"
2093 "ws reg_class = %s\n\n",
2094 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
2095 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
2096 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
2097 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
2098 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
2099 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
2100 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
2102 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2103 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
2106 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
2108 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
2109 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
2115 if (rs6000_recip_control)
2117 fprintf (stderr, "\nReciprocal mask = 0x%x\n", rs6000_recip_control);
2119 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2120 if (rs6000_recip_bits[m])
2123 "Reciprocal estimate mode: %-5s divide: %s rsqrt: %s\n",
2125 (RS6000_RECIP_AUTO_RE_P (m)
2127 : (RS6000_RECIP_HAVE_RE_P (m) ? "have" : "none")),
2128 (RS6000_RECIP_AUTO_RSQRTE_P (m)
2130 : (RS6000_RECIP_HAVE_RSQRTE_P (m) ? "have" : "none")));
2133 fputs ("\n", stderr);
2136 if (rs6000_cpu_index >= 0)
2137 fprintf (stderr, DEBUG_FMT_S, "cpu",
2138 processor_target_table[rs6000_cpu_index].name);
2140 if (rs6000_tune_index >= 0)
2141 fprintf (stderr, DEBUG_FMT_S, "tune",
2142 processor_target_table[rs6000_tune_index].name);
2144 switch (rs6000_sched_costly_dep)
2146 case max_dep_latency:
2147 costly_str = "max_dep_latency";
2151 costly_str = "no_dep_costly";
2154 case all_deps_costly:
2155 costly_str = "all_deps_costly";
2158 case true_store_to_load_dep_costly:
2159 costly_str = "true_store_to_load_dep_costly";
2162 case store_to_load_dep_costly:
2163 costly_str = "store_to_load_dep_costly";
2167 costly_str = costly_num;
2168 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
2172 fprintf (stderr, DEBUG_FMT_S, "sched_costly_dep", costly_str);
2174 switch (rs6000_sched_insert_nops)
2176 case sched_finish_regroup_exact:
2177 nop_str = "sched_finish_regroup_exact";
2180 case sched_finish_pad_groups:
2181 nop_str = "sched_finish_pad_groups";
2184 case sched_finish_none:
2185 nop_str = "sched_finish_none";
2190 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
2194 fprintf (stderr, DEBUG_FMT_S, "sched_insert_nops", nop_str);
2196 switch (rs6000_sdata)
2203 fprintf (stderr, DEBUG_FMT_S, "sdata", "data");
2207 fprintf (stderr, DEBUG_FMT_S, "sdata", "sysv");
2211 fprintf (stderr, DEBUG_FMT_S, "sdata", "eabi");
2216 switch (rs6000_traceback)
2218 case traceback_default: trace_str = "default"; break;
2219 case traceback_none: trace_str = "none"; break;
2220 case traceback_part: trace_str = "part"; break;
2221 case traceback_full: trace_str = "full"; break;
2222 default: trace_str = "unknown"; break;
2225 fprintf (stderr, DEBUG_FMT_S, "traceback", trace_str);
2227 switch (rs6000_current_cmodel)
2229 case CMODEL_SMALL: cmodel_str = "small"; break;
2230 case CMODEL_MEDIUM: cmodel_str = "medium"; break;
2231 case CMODEL_LARGE: cmodel_str = "large"; break;
2232 default: cmodel_str = "unknown"; break;
2235 fprintf (stderr, DEBUG_FMT_S, "cmodel", cmodel_str);
2237 switch (rs6000_current_abi)
2239 case ABI_NONE: abi_str = "none"; break;
2240 case ABI_AIX: abi_str = "aix"; break;
2241 case ABI_V4: abi_str = "V4"; break;
2242 case ABI_DARWIN: abi_str = "darwin"; break;
2243 default: abi_str = "unknown"; break;
2246 fprintf (stderr, DEBUG_FMT_S, "abi", abi_str);
2248 if (rs6000_altivec_abi)
2249 fprintf (stderr, DEBUG_FMT_S, "altivec_abi", "true");
2252 fprintf (stderr, DEBUG_FMT_S, "spe_abi", "true");
2254 if (rs6000_darwin64_abi)
2255 fprintf (stderr, DEBUG_FMT_S, "darwin64_abi", "true");
2257 if (rs6000_float_gprs)
2258 fprintf (stderr, DEBUG_FMT_S, "float_gprs", "true");
2260 fprintf (stderr, DEBUG_FMT_S, "always_hint", tf[!!rs6000_always_hint]);
2261 fprintf (stderr, DEBUG_FMT_S, "align_branch",
2262 tf[!!rs6000_align_branch_targets]);
2263 fprintf (stderr, DEBUG_FMT_D, "tls_size", rs6000_tls_size);
2264 fprintf (stderr, DEBUG_FMT_D, "long_double_size",
2265 rs6000_long_double_type_size);
2266 fprintf (stderr, DEBUG_FMT_D, "sched_restricted_insns_priority",
2267 (int)rs6000_sched_restricted_insns_priority);
2270 /* Initialize the various global tables that are based on register size. */
2272 rs6000_init_hard_regno_mode_ok (bool global_init_p)
2278 /* Precalculate REGNO_REG_CLASS. */
2279 rs6000_regno_regclass[0] = GENERAL_REGS;
2280 for (r = 1; r < 32; ++r)
2281 rs6000_regno_regclass[r] = BASE_REGS;
2283 for (r = 32; r < 64; ++r)
2284 rs6000_regno_regclass[r] = FLOAT_REGS;
2286 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
2287 rs6000_regno_regclass[r] = NO_REGS;
2289 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
2290 rs6000_regno_regclass[r] = ALTIVEC_REGS;
2292 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
2293 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
2294 rs6000_regno_regclass[r] = CR_REGS;
2296 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
2297 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
2298 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
2299 rs6000_regno_regclass[CA_REGNO] = CA_REGS;
2300 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
2301 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
2302 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
2303 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
2304 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
2305 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
2307 /* Precalculate vector information, this must be set up before the
2308 rs6000_hard_regno_nregs_internal below. */
2309 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2311 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
2312 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
2313 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
2316 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
2317 rs6000_constraints[c] = NO_REGS;
2319 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
2320 believes it can use native alignment or still uses 128-bit alignment. */
2321 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
2332 /* V2DF mode, VSX only. */
2335 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
2336 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
2337 rs6000_vector_align[V2DFmode] = align64;
2340 /* V4SF mode, either VSX or Altivec. */
2343 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
2344 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
2345 rs6000_vector_align[V4SFmode] = align32;
2347 else if (TARGET_ALTIVEC)
2349 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
2350 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
2351 rs6000_vector_align[V4SFmode] = align32;
2354 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
2358 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
2359 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
2360 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
2361 rs6000_vector_align[V4SImode] = align32;
2362 rs6000_vector_align[V8HImode] = align32;
2363 rs6000_vector_align[V16QImode] = align32;
2367 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
2368 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
2369 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
2373 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
2374 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
2375 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
2379 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
2380 Altivec doesn't have 64-bit support. */
2383 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
2384 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
2385 rs6000_vector_align[V2DImode] = align64;
2388 /* DFmode, see if we want to use the VSX unit. */
2389 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
2391 rs6000_vector_unit[DFmode] = VECTOR_VSX;
2392 rs6000_vector_mem[DFmode]
2393 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
2394 rs6000_vector_align[DFmode] = align64;
2397 /* TODO add SPE and paired floating point vector support. */
2399 /* Register class constaints for the constraints that depend on compile
2401 if (TARGET_HARD_FLOAT && TARGET_FPRS)
2402 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
2404 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
2405 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
2409 /* At present, we just use VSX_REGS, but we have different constraints
2410 based on the use, in case we want to fine tune the default register
2411 class used. wa = any VSX register, wf = register class to use for
2412 V4SF, wd = register class to use for V2DF, and ws = register classs to
2413 use for DF scalars. */
2414 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
2415 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
2416 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
2417 rs6000_constraints[RS6000_CONSTRAINT_ws] = (TARGET_VSX_SCALAR_MEMORY
2423 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
2425 /* Set up the reload helper functions. */
2426 if (TARGET_VSX || TARGET_ALTIVEC)
2430 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
2431 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
2432 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
2433 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
2434 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
2435 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
2436 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
2437 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
2438 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
2439 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
2440 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
2441 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
2445 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
2446 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
2447 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
2448 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
2449 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
2450 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
2451 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
2452 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
2453 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
2454 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
2455 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
2456 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
2460 /* Precalculate HARD_REGNO_NREGS. */
2461 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2462 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2463 rs6000_hard_regno_nregs[m][r]
2464 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
2466 /* Precalculate HARD_REGNO_MODE_OK. */
2467 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2468 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2469 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
2470 rs6000_hard_regno_mode_ok_p[m][r] = true;
2472 /* Precalculate CLASS_MAX_NREGS sizes. */
2473 for (c = 0; c < LIM_REG_CLASSES; ++c)
2477 if (TARGET_VSX && VSX_REG_CLASS_P (c))
2478 reg_size = UNITS_PER_VSX_WORD;
2480 else if (c == ALTIVEC_REGS)
2481 reg_size = UNITS_PER_ALTIVEC_WORD;
2483 else if (c == FLOAT_REGS)
2484 reg_size = UNITS_PER_FP_WORD;
2487 reg_size = UNITS_PER_WORD;
2489 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2490 rs6000_class_max_nregs[m][c]
2491 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
2494 if (TARGET_E500_DOUBLE)
2495 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
2497 /* Calculate which modes to automatically generate code to use a the
2498 reciprocal divide and square root instructions. In the future, possibly
2499 automatically generate the instructions even if the user did not specify
2500 -mrecip. The older machines double precision reciprocal sqrt estimate is
2501 not accurate enough. */
2502 memset (rs6000_recip_bits, 0, sizeof (rs6000_recip_bits));
2504 rs6000_recip_bits[SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2506 rs6000_recip_bits[DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2507 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2508 rs6000_recip_bits[V4SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2509 if (VECTOR_UNIT_VSX_P (V2DFmode))
2510 rs6000_recip_bits[V2DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2512 if (TARGET_FRSQRTES)
2513 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2515 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2516 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2517 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2518 if (VECTOR_UNIT_VSX_P (V2DFmode))
2519 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2521 if (rs6000_recip_control)
2523 if (!flag_finite_math_only)
2524 warning (0, "-mrecip requires -ffinite-math or -ffast-math");
2525 if (flag_trapping_math)
2526 warning (0, "-mrecip requires -fno-trapping-math or -ffast-math");
2527 if (!flag_reciprocal_math)
2528 warning (0, "-mrecip requires -freciprocal-math or -ffast-math");
2529 if (flag_finite_math_only && !flag_trapping_math && flag_reciprocal_math)
2531 if (RS6000_RECIP_HAVE_RE_P (SFmode)
2532 && (rs6000_recip_control & RECIP_SF_DIV) != 0)
2533 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2535 if (RS6000_RECIP_HAVE_RE_P (DFmode)
2536 && (rs6000_recip_control & RECIP_DF_DIV) != 0)
2537 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2539 if (RS6000_RECIP_HAVE_RE_P (V4SFmode)
2540 && (rs6000_recip_control & RECIP_V4SF_DIV) != 0)
2541 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2543 if (RS6000_RECIP_HAVE_RE_P (V2DFmode)
2544 && (rs6000_recip_control & RECIP_V2DF_DIV) != 0)
2545 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2547 if (RS6000_RECIP_HAVE_RSQRTE_P (SFmode)
2548 && (rs6000_recip_control & RECIP_SF_RSQRT) != 0)
2549 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2551 if (RS6000_RECIP_HAVE_RSQRTE_P (DFmode)
2552 && (rs6000_recip_control & RECIP_DF_RSQRT) != 0)
2553 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2555 if (RS6000_RECIP_HAVE_RSQRTE_P (V4SFmode)
2556 && (rs6000_recip_control & RECIP_V4SF_RSQRT) != 0)
2557 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2559 if (RS6000_RECIP_HAVE_RSQRTE_P (V2DFmode)
2560 && (rs6000_recip_control & RECIP_V2DF_RSQRT) != 0)
2561 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2565 if (global_init_p || TARGET_DEBUG_TARGET)
2567 if (TARGET_DEBUG_REG)
2568 rs6000_debug_reg_global ();
2570 if (TARGET_DEBUG_COST || TARGET_DEBUG_REG)
2572 "SImode variable mult cost = %d\n"
2573 "SImode constant mult cost = %d\n"
2574 "SImode short constant mult cost = %d\n"
2575 "DImode multipliciation cost = %d\n"
2576 "SImode division cost = %d\n"
2577 "DImode division cost = %d\n"
2578 "Simple fp operation cost = %d\n"
2579 "DFmode multiplication cost = %d\n"
2580 "SFmode division cost = %d\n"
2581 "DFmode division cost = %d\n"
2582 "cache line size = %d\n"
2583 "l1 cache size = %d\n"
2584 "l2 cache size = %d\n"
2585 "simultaneous prefetches = %d\n"
2588 rs6000_cost->mulsi_const,
2589 rs6000_cost->mulsi_const9,
2597 rs6000_cost->cache_line_size,
2598 rs6000_cost->l1_cache_size,
2599 rs6000_cost->l2_cache_size,
2600 rs6000_cost->simultaneous_prefetches);
2605 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2608 darwin_rs6000_override_options (void)
2610 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2612 rs6000_altivec_abi = 1;
2613 TARGET_ALTIVEC_VRSAVE = 1;
2615 if (DEFAULT_ABI == ABI_DARWIN
2617 darwin_one_byte_bool = 1;
2619 if (TARGET_64BIT && ! TARGET_POWERPC64)
2621 target_flags |= MASK_POWERPC64;
2622 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2626 rs6000_default_long_calls = 1;
2627 target_flags |= MASK_SOFT_FLOAT;
2630 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2632 if (!flag_mkernel && !flag_apple_kext
2634 && ! (target_flags_explicit & MASK_ALTIVEC))
2635 target_flags |= MASK_ALTIVEC;
2637 /* Unless the user (not the configurer) has explicitly overridden
2638 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2639 G4 unless targetting the kernel. */
2642 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2643 && ! (target_flags_explicit & MASK_ALTIVEC)
2644 && ! rs6000_select[1].string)
2646 target_flags |= MASK_ALTIVEC;
2651 /* If not otherwise specified by a target, make 'long double' equivalent to
2654 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2655 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2658 /* Override command line options. Mostly we process the processor type and
2659 sometimes adjust other TARGET_ options. */
2662 rs6000_option_override_internal (bool global_init_p)
2665 const char *default_cpu = OPTION_TARGET_CPU_DEFAULT;
2669 struct cl_target_option *main_target_opt
2670 = ((global_init_p || target_option_default_node == NULL)
2671 ? NULL : TREE_TARGET_OPTION (target_option_default_node));
2673 /* Numerous experiment shows that IRA based loop pressure
2674 calculation works better for RTL loop invariant motion on targets
2675 with enough (>= 32) registers. It is an expensive optimization.
2676 So it is on only for peak performance. */
2677 if (optimize >= 3 && global_init_p)
2678 flag_ira_loop_pressure = 1;
2680 /* Set the pointer size. */
2683 rs6000_pmode = (int)DImode;
2684 rs6000_pointer_size = 64;
2688 rs6000_pmode = (int)SImode;
2689 rs6000_pointer_size = 32;
2692 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2693 #ifdef OS_MISSING_POWERPC64
2694 if (OS_MISSING_POWERPC64)
2695 set_masks &= ~MASK_POWERPC64;
2697 #ifdef OS_MISSING_ALTIVEC
2698 if (OS_MISSING_ALTIVEC)
2699 set_masks &= ~MASK_ALTIVEC;
2702 /* Don't override by the processor default if given explicitly. */
2703 set_masks &= ~target_flags_explicit;
2705 /* Identify the processor type. */
2708 if (TARGET_POWERPC64)
2709 default_cpu = "powerpc64";
2710 else if (TARGET_POWERPC)
2711 default_cpu = "powerpc";
2714 /* Process the -mcpu=<xxx> and -mtune=<xxx> argument. If the user changed
2715 the cpu in a target attribute or pragma, but did not specify a tuning
2716 option, use the cpu for the tuning option rather than the option specified
2717 with -mtune on the command line. */
2718 if (rs6000_cpu_index > 0)
2719 cpu_index = rs6000_cpu_index;
2720 else if (main_target_opt != NULL && main_target_opt->x_rs6000_cpu_index > 0)
2721 rs6000_cpu_index = cpu_index = main_target_opt->x_rs6000_cpu_index;
2723 rs6000_cpu_index = cpu_index = rs6000_cpu_name_lookup (default_cpu);
2725 if (rs6000_tune_index > 0)
2726 tune_index = rs6000_tune_index;
2728 rs6000_tune_index = tune_index = cpu_index;
2732 target_flags &= ~set_masks;
2733 target_flags |= (processor_target_table[cpu_index].target_enable
2737 rs6000_cpu = ((tune_index >= 0)
2738 ? processor_target_table[tune_index].processor
2740 ? PROCESSOR_DEFAULT64
2741 : PROCESSOR_DEFAULT));
2743 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2744 || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64)
2747 error ("AltiVec not supported in this target");
2749 error ("SPE not supported in this target");
2752 /* Disable Cell microcode if we are optimizing for the Cell
2753 and not optimizing for size. */
2754 if (rs6000_gen_cell_microcode == -1)
2755 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2758 /* If we are optimizing big endian systems for space and it's OK to
2759 use instructions that would be microcoded on the Cell, use the
2760 load/store multiple and string instructions. */
2761 if (BYTES_BIG_ENDIAN && optimize_size && rs6000_gen_cell_microcode)
2762 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2764 /* Don't allow -mmultiple or -mstring on little endian systems
2765 unless the cpu is a 750, because the hardware doesn't support the
2766 instructions used in little endian mode, and causes an alignment
2767 trap. The 750 does not cause an alignment trap (except when the
2768 target is unaligned). */
2770 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2772 if (TARGET_MULTIPLE)
2774 target_flags &= ~MASK_MULTIPLE;
2775 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2776 warning (0, "-mmultiple is not supported on little endian systems");
2781 target_flags &= ~MASK_STRING;
2782 if ((target_flags_explicit & MASK_STRING) != 0)
2783 warning (0, "-mstring is not supported on little endian systems");
2787 /* Add some warnings for VSX. */
2790 const char *msg = NULL;
2791 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2792 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2794 if (target_flags_explicit & MASK_VSX)
2795 msg = N_("-mvsx requires hardware floating point");
2797 target_flags &= ~ MASK_VSX;
2799 else if (TARGET_PAIRED_FLOAT)
2800 msg = N_("-mvsx and -mpaired are incompatible");
2801 /* The hardware will allow VSX and little endian, but until we make sure
2802 things like vector select, etc. work don't allow VSX on little endian
2803 systems at this point. */
2804 else if (!BYTES_BIG_ENDIAN)
2805 msg = N_("-mvsx used with little endian code");
2806 else if (TARGET_AVOID_XFORM > 0)
2807 msg = N_("-mvsx needs indexed addressing");
2808 else if (!TARGET_ALTIVEC && (target_flags_explicit & MASK_ALTIVEC))
2810 if (target_flags_explicit & MASK_VSX)
2811 msg = N_("-mvsx and -mno-altivec are incompatible");
2813 msg = N_("-mno-altivec disables vsx");
2819 target_flags &= ~ MASK_VSX;
2820 target_flags_explicit |= MASK_VSX;
2824 /* For the newer switches (vsx, dfp, etc.) set some of the older options,
2825 unless the user explicitly used the -mno-<option> to disable the code. */
2827 target_flags |= (ISA_2_6_MASKS_SERVER & ~target_flags_explicit);
2828 else if (TARGET_POPCNTD)
2829 target_flags |= (ISA_2_6_MASKS_EMBEDDED & ~target_flags_explicit);
2830 else if (TARGET_DFP)
2831 target_flags |= (ISA_2_5_MASKS_SERVER & ~target_flags_explicit);
2832 else if (TARGET_CMPB)
2833 target_flags |= (ISA_2_5_MASKS_EMBEDDED & ~target_flags_explicit);
2834 else if (TARGET_FPRND)
2835 target_flags |= (ISA_2_4_MASKS & ~target_flags_explicit);
2836 else if (TARGET_POPCNTB)
2837 target_flags |= (ISA_2_2_MASKS & ~target_flags_explicit);
2838 else if (TARGET_ALTIVEC)
2839 target_flags |= (MASK_PPC_GFXOPT & ~target_flags_explicit);
2841 /* E500mc does "better" if we inline more aggressively. Respect the
2842 user's opinion, though. */
2843 if (rs6000_block_move_inline_limit == 0
2844 && (rs6000_cpu == PROCESSOR_PPCE500MC
2845 || rs6000_cpu == PROCESSOR_PPCE500MC64))
2846 rs6000_block_move_inline_limit = 128;
2848 /* store_one_arg depends on expand_block_move to handle at least the
2849 size of reg_parm_stack_space. */
2850 if (rs6000_block_move_inline_limit < (TARGET_POWERPC64 ? 64 : 32))
2851 rs6000_block_move_inline_limit = (TARGET_POWERPC64 ? 64 : 32);
2855 /* If the appropriate debug option is enabled, replace the target hooks
2856 with debug versions that call the real version and then prints
2857 debugging information. */
2858 if (TARGET_DEBUG_COST)
2860 targetm.rtx_costs = rs6000_debug_rtx_costs;
2861 targetm.address_cost = rs6000_debug_address_cost;
2862 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2865 if (TARGET_DEBUG_ADDR)
2867 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2868 targetm.legitimize_address = rs6000_debug_legitimize_address;
2869 rs6000_secondary_reload_class_ptr
2870 = rs6000_debug_secondary_reload_class;
2871 rs6000_secondary_memory_needed_ptr
2872 = rs6000_debug_secondary_memory_needed;
2873 rs6000_cannot_change_mode_class_ptr
2874 = rs6000_debug_cannot_change_mode_class;
2875 rs6000_preferred_reload_class_ptr
2876 = rs6000_debug_preferred_reload_class;
2877 rs6000_legitimize_reload_address_ptr
2878 = rs6000_debug_legitimize_reload_address;
2879 rs6000_mode_dependent_address_ptr
2880 = rs6000_debug_mode_dependent_address;
2883 if (rs6000_veclibabi_name)
2885 if (strcmp (rs6000_veclibabi_name, "mass") == 0)
2886 rs6000_veclib_handler = rs6000_builtin_vectorized_libmass;
2889 error ("unknown vectorization library ABI type (%s) for "
2890 "-mveclibabi= switch", rs6000_veclibabi_name);
2896 if (!rs6000_explicit_options.long_double)
2898 if (main_target_opt != NULL
2899 && (main_target_opt->x_rs6000_long_double_type_size
2900 != RS6000_DEFAULT_LONG_DOUBLE_SIZE))
2901 error ("target attribute or pragma changes long double size");
2903 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2906 #ifndef POWERPC_LINUX
2907 if (!rs6000_explicit_options.ieee)
2908 rs6000_ieeequad = 1;
2911 /* Disable VSX and Altivec silently if the user switched cpus to power7 in a
2912 target attribute or pragma which automatically enables both options,
2913 unless the altivec ABI was set. This is set by default for 64-bit, but
2915 if (main_target_opt != NULL && !main_target_opt->x_rs6000_altivec_abi)
2916 target_flags &= ~((MASK_VSX | MASK_ALTIVEC) & ~target_flags_explicit);
2918 /* Enable Altivec ABI for AIX -maltivec. */
2919 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2921 if (main_target_opt != NULL && !main_target_opt->x_rs6000_altivec_abi)
2922 error ("target attribute or pragma changes AltiVec ABI");
2924 rs6000_altivec_abi = 1;
2927 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2928 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2929 be explicitly overridden in either case. */
2932 if (!rs6000_explicit_options.altivec_abi
2933 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2935 if (main_target_opt != NULL &&
2936 !main_target_opt->x_rs6000_altivec_abi)
2937 error ("target attribute or pragma changes AltiVec ABI");
2939 rs6000_altivec_abi = 1;
2942 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2943 if (!rs6000_explicit_options.vrsave)
2944 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2947 /* Set the Darwin64 ABI as default for 64-bit Darwin.
2948 So far, the only darwin64 targets are also MACH-O. */
2950 && DEFAULT_ABI == ABI_DARWIN
2953 if (main_target_opt != NULL && !main_target_opt->x_rs6000_darwin64_abi)
2954 error ("target attribute or pragma changes darwin64 ABI");
2957 rs6000_darwin64_abi = 1;
2958 /* Default to natural alignment, for better performance. */
2959 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2963 /* Place FP constants in the constant pool instead of TOC
2964 if section anchors enabled. */
2965 if (flag_section_anchors)
2966 TARGET_NO_FP_IN_TOC = 1;
2968 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2969 SUBTARGET_OVERRIDE_OPTIONS;
2971 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2972 SUBSUBTARGET_OVERRIDE_OPTIONS;
2974 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2975 SUB3TARGET_OVERRIDE_OPTIONS;
2978 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC
2979 || rs6000_cpu == PROCESSOR_PPCE500MC64)
2981 /* The e500 and e500mc do not have string instructions, and we set
2982 MASK_STRING above when optimizing for size. */
2983 if ((target_flags & MASK_STRING) != 0)
2984 target_flags = target_flags & ~MASK_STRING;
2986 else if (rs6000_select[1].string != NULL)
2988 /* For the powerpc-eabispe configuration, we set all these by
2989 default, so let's unset them if we manually set another
2990 CPU that is not the E500. */
2991 if (main_target_opt != NULL
2992 && ((main_target_opt->x_rs6000_spe_abi != rs6000_spe_abi)
2993 || (main_target_opt->x_rs6000_spe != rs6000_spe)
2994 || (main_target_opt->x_rs6000_float_gprs != rs6000_float_gprs)))
2995 error ("target attribute or pragma changes SPE ABI");
2998 if (!rs6000_explicit_options.spe_abi)
3000 if (!rs6000_explicit_options.spe)
3002 if (!rs6000_explicit_options.float_gprs)
3003 rs6000_float_gprs = 0;
3005 if (!(target_flags_explicit & MASK_ISEL))
3006 target_flags &= ~MASK_ISEL;
3009 /* Detect invalid option combinations with E500. */
3012 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
3013 && rs6000_cpu != PROCESSOR_POWER5
3014 && rs6000_cpu != PROCESSOR_POWER6
3015 && rs6000_cpu != PROCESSOR_POWER7
3016 && rs6000_cpu != PROCESSOR_PPCA2
3017 && rs6000_cpu != PROCESSOR_CELL);
3018 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
3019 || rs6000_cpu == PROCESSOR_POWER5
3020 || rs6000_cpu == PROCESSOR_POWER7);
3021 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
3022 || rs6000_cpu == PROCESSOR_POWER5
3023 || rs6000_cpu == PROCESSOR_POWER6
3024 || rs6000_cpu == PROCESSOR_POWER7
3025 || rs6000_cpu == PROCESSOR_PPCE500MC
3026 || rs6000_cpu == PROCESSOR_PPCE500MC64);
3028 /* Allow debug switches to override the above settings. These are set to -1
3029 in rs6000.opt to indicate the user hasn't directly set the switch. */
3030 if (TARGET_ALWAYS_HINT >= 0)
3031 rs6000_always_hint = TARGET_ALWAYS_HINT;
3033 if (TARGET_SCHED_GROUPS >= 0)
3034 rs6000_sched_groups = TARGET_SCHED_GROUPS;
3036 if (TARGET_ALIGN_BRANCH_TARGETS >= 0)
3037 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
3039 rs6000_sched_restricted_insns_priority
3040 = (rs6000_sched_groups ? 1 : 0);
3042 /* Handle -msched-costly-dep option. */
3043 rs6000_sched_costly_dep
3044 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
3046 if (rs6000_sched_costly_dep_str)
3048 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
3049 rs6000_sched_costly_dep = no_dep_costly;
3050 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
3051 rs6000_sched_costly_dep = all_deps_costly;
3052 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
3053 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
3054 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
3055 rs6000_sched_costly_dep = store_to_load_dep_costly;
3057 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
3058 atoi (rs6000_sched_costly_dep_str));
3061 /* Handle -minsert-sched-nops option. */
3062 rs6000_sched_insert_nops
3063 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
3065 if (rs6000_sched_insert_nops_str)
3067 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
3068 rs6000_sched_insert_nops = sched_finish_none;
3069 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
3070 rs6000_sched_insert_nops = sched_finish_pad_groups;
3071 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
3072 rs6000_sched_insert_nops = sched_finish_regroup_exact;
3074 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
3075 atoi (rs6000_sched_insert_nops_str));
3080 #ifdef TARGET_REGNAMES
3081 /* If the user desires alternate register names, copy in the
3082 alternate names now. */
3083 if (TARGET_REGNAMES)
3084 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
3087 /* Set aix_struct_return last, after the ABI is determined.
3088 If -maix-struct-return or -msvr4-struct-return was explicitly
3089 used, don't override with the ABI default. */
3090 if (!rs6000_explicit_options.aix_struct_ret)
3091 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
3094 /* IBM XL compiler defaults to unsigned bitfields. */
3095 if (TARGET_XL_COMPAT)
3096 flag_signed_bitfields = 0;
3099 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
3100 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
3103 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
3105 /* We can only guarantee the availability of DI pseudo-ops when
3106 assembling for 64-bit targets. */
3109 targetm.asm_out.aligned_op.di = NULL;
3110 targetm.asm_out.unaligned_op.di = NULL;
3114 /* Set branch target alignment, if not optimizing for size. */
3117 /* Cell wants to be aligned 8byte for dual issue. Titan wants to be
3118 aligned 8byte to avoid misprediction by the branch predictor. */
3119 if (rs6000_cpu == PROCESSOR_TITAN
3120 || rs6000_cpu == PROCESSOR_CELL)
3122 if (align_functions <= 0)
3123 align_functions = 8;
3124 if (align_jumps <= 0)
3126 if (align_loops <= 0)
3129 if (rs6000_align_branch_targets)
3131 if (align_functions <= 0)
3132 align_functions = 16;
3133 if (align_jumps <= 0)
3135 if (align_loops <= 0)
3137 can_override_loop_align = 1;
3141 if (align_jumps_max_skip <= 0)
3142 align_jumps_max_skip = 15;
3143 if (align_loops_max_skip <= 0)
3144 align_loops_max_skip = 15;
3147 /* Arrange to save and restore machine status around nested functions. */
3148 init_machine_status = rs6000_init_machine_status;
3150 /* We should always be splitting complex arguments, but we can't break
3151 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
3152 if (DEFAULT_ABI != ABI_AIX)
3153 targetm.calls.split_complex_arg = NULL;
3156 /* Initialize rs6000_cost with the appropriate target costs. */
3158 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
3162 case PROCESSOR_RIOS1:
3163 rs6000_cost = &rios1_cost;
3166 case PROCESSOR_RIOS2:
3167 rs6000_cost = &rios2_cost;
3170 case PROCESSOR_RS64A:
3171 rs6000_cost = &rs64a_cost;
3174 case PROCESSOR_MPCCORE:
3175 rs6000_cost = &mpccore_cost;
3178 case PROCESSOR_PPC403:
3179 rs6000_cost = &ppc403_cost;
3182 case PROCESSOR_PPC405:
3183 rs6000_cost = &ppc405_cost;
3186 case PROCESSOR_PPC440:
3187 rs6000_cost = &ppc440_cost;
3190 case PROCESSOR_PPC476:
3191 rs6000_cost = &ppc476_cost;
3194 case PROCESSOR_PPC601:
3195 rs6000_cost = &ppc601_cost;
3198 case PROCESSOR_PPC603:
3199 rs6000_cost = &ppc603_cost;
3202 case PROCESSOR_PPC604:
3203 rs6000_cost = &ppc604_cost;
3206 case PROCESSOR_PPC604e:
3207 rs6000_cost = &ppc604e_cost;
3210 case PROCESSOR_PPC620:
3211 rs6000_cost = &ppc620_cost;
3214 case PROCESSOR_PPC630:
3215 rs6000_cost = &ppc630_cost;
3218 case PROCESSOR_CELL:
3219 rs6000_cost = &ppccell_cost;
3222 case PROCESSOR_PPC750:
3223 case PROCESSOR_PPC7400:
3224 rs6000_cost = &ppc750_cost;
3227 case PROCESSOR_PPC7450:
3228 rs6000_cost = &ppc7450_cost;
3231 case PROCESSOR_PPC8540:
3232 rs6000_cost = &ppc8540_cost;
3235 case PROCESSOR_PPCE300C2:
3236 case PROCESSOR_PPCE300C3:
3237 rs6000_cost = &ppce300c2c3_cost;
3240 case PROCESSOR_PPCE500MC:
3241 rs6000_cost = &ppce500mc_cost;
3244 case PROCESSOR_PPCE500MC64:
3245 rs6000_cost = &ppce500mc64_cost;
3248 case PROCESSOR_TITAN:
3249 rs6000_cost = &titan_cost;
3252 case PROCESSOR_POWER4:
3253 case PROCESSOR_POWER5:
3254 rs6000_cost = &power4_cost;
3257 case PROCESSOR_POWER6:
3258 rs6000_cost = &power6_cost;
3261 case PROCESSOR_POWER7:
3262 rs6000_cost = &power7_cost;
3265 case PROCESSOR_PPCA2:
3266 rs6000_cost = &ppca2_cost;
3275 maybe_set_param_value (PARAM_SIMULTANEOUS_PREFETCHES,
3276 rs6000_cost->simultaneous_prefetches,
3277 global_options.x_param_values,
3278 global_options_set.x_param_values);
3279 maybe_set_param_value (PARAM_L1_CACHE_SIZE, rs6000_cost->l1_cache_size,
3280 global_options.x_param_values,
3281 global_options_set.x_param_values);
3282 maybe_set_param_value (PARAM_L1_CACHE_LINE_SIZE,
3283 rs6000_cost->cache_line_size,
3284 global_options.x_param_values,
3285 global_options_set.x_param_values);
3286 maybe_set_param_value (PARAM_L2_CACHE_SIZE, rs6000_cost->l2_cache_size,
3287 global_options.x_param_values,
3288 global_options_set.x_param_values);
3290 /* If using typedef char *va_list, signal that
3291 __builtin_va_start (&ap, 0) can be optimized to
3292 ap = __builtin_next_arg (0). */
3293 if (DEFAULT_ABI != ABI_V4)
3294 targetm.expand_builtin_va_start = NULL;
3297 /* Set up single/double float flags.
3298 If TARGET_HARD_FLOAT is set, but neither single or double is set,
3299 then set both flags. */
3300 if (TARGET_HARD_FLOAT && TARGET_FPRS
3301 && rs6000_single_float == 0 && rs6000_double_float == 0)
3302 rs6000_single_float = rs6000_double_float = 1;
3304 /* Reset single and double FP flags if target is E500. */
3307 rs6000_single_float = rs6000_double_float = 0;
3308 if (TARGET_E500_SINGLE)
3309 rs6000_single_float = 1;
3310 if (TARGET_E500_DOUBLE)
3311 rs6000_single_float = rs6000_double_float = 1;
3314 if (main_target_opt)
3316 if (main_target_opt->x_rs6000_single_float != rs6000_single_float)
3317 error ("target attribute or pragma changes single precision floating "
3319 if (main_target_opt->x_rs6000_double_float != rs6000_double_float)
3320 error ("target attribute or pragma changes double precision floating "
3324 /* If not explicitly specified via option, decide whether to generate indexed
3325 load/store instructions. */
3326 if (TARGET_AVOID_XFORM == -1)
3327 /* Avoid indexed addressing when targeting Power6 in order to avoid the
3328 DERAT mispredict penalty. However the LVE and STVE altivec instructions
3329 need indexed accesses and the type used is the scalar type of the element
3330 being loaded or stored. */
3331 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB
3332 && !TARGET_ALTIVEC);
3334 /* Set the -mrecip options. */
3335 if (rs6000_recip_name)
3337 char *p = ASTRDUP (rs6000_recip_name);
3339 unsigned int mask, i;
3342 while ((q = strtok (p, ",")) != NULL)
3353 if (!strcmp (q, "default"))
3354 mask = ((TARGET_RECIP_PRECISION)
3355 ? RECIP_HIGH_PRECISION : RECIP_LOW_PRECISION);
3358 for (i = 0; i < ARRAY_SIZE (recip_options); i++)
3359 if (!strcmp (q, recip_options[i].string))
3361 mask = recip_options[i].mask;
3365 if (i == ARRAY_SIZE (recip_options))
3367 error ("unknown option for -mrecip=%s", q);
3375 rs6000_recip_control &= ~mask;
3377 rs6000_recip_control |= mask;
3381 rs6000_init_hard_regno_mode_ok (global_init_p);
3383 /* Save the initial options in case the user does function specific options */
3385 target_option_default_node = target_option_current_node
3386 = build_target_option_node ();
3391 /* Implement TARGET_OPTION_OVERRIDE. On the RS/6000 this is used to
3392 define the target cpu type. */
3395 rs6000_option_override (void)
3397 (void) rs6000_option_override_internal (true);
3401 /* Implement targetm.vectorize.builtin_mask_for_load. */
3403 rs6000_builtin_mask_for_load (void)
3405 if (TARGET_ALTIVEC || TARGET_VSX)
3406 return altivec_builtin_mask_for_load;
3411 /* Implement LOOP_ALIGN. */
3413 rs6000_loop_align (rtx label)
3418 /* Don't override loop alignment if -falign-loops was specified. */
3419 if (!can_override_loop_align)
3420 return align_loops_log;
3422 bb = BLOCK_FOR_INSN (label);
3423 ninsns = num_loop_insns(bb->loop_father);
3425 /* Align small loops to 32 bytes to fit in an icache sector, otherwise return default. */
3426 if (ninsns > 4 && ninsns <= 8
3427 && (rs6000_cpu == PROCESSOR_POWER4
3428 || rs6000_cpu == PROCESSOR_POWER5
3429 || rs6000_cpu == PROCESSOR_POWER6
3430 || rs6000_cpu == PROCESSOR_POWER7))
3433 return align_loops_log;
3436 /* Implement TARGET_LOOP_ALIGN_MAX_SKIP. */
3438 rs6000_loop_align_max_skip (rtx label)
3440 return (1 << rs6000_loop_align (label)) - 1;
3443 /* Implement targetm.vectorize.builtin_conversion.
3444 Returns a decl of a function that implements conversion of an integer vector
3445 into a floating-point vector, or vice-versa. DEST_TYPE is the
3446 destination type and SRC_TYPE the source type of the conversion.
3447 Return NULL_TREE if it is not available. */
3449 rs6000_builtin_conversion (unsigned int tcode, tree dest_type, tree src_type)
3451 enum tree_code code = (enum tree_code) tcode;
3455 case FIX_TRUNC_EXPR:
3456 switch (TYPE_MODE (dest_type))
3459 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3462 return TYPE_UNSIGNED (dest_type)
3463 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
3464 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
3467 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3470 return TYPE_UNSIGNED (dest_type)
3471 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
3472 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
3479 switch (TYPE_MODE (src_type))
3482 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3485 return TYPE_UNSIGNED (src_type)
3486 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
3487 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
3490 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3493 return TYPE_UNSIGNED (src_type)
3494 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
3495 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
3506 /* Implement targetm.vectorize.builtin_mul_widen_even. */
3508 rs6000_builtin_mul_widen_even (tree type)
3510 if (!TARGET_ALTIVEC)
3513 switch (TYPE_MODE (type))
3516 return TYPE_UNSIGNED (type)
3517 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
3518 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
3521 return TYPE_UNSIGNED (type)
3522 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
3523 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
3529 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
3531 rs6000_builtin_mul_widen_odd (tree type)
3533 if (!TARGET_ALTIVEC)
3536 switch (TYPE_MODE (type))
3539 return TYPE_UNSIGNED (type)
3540 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
3541 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
3544 return TYPE_UNSIGNED (type)
3545 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
3546 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
3553 /* Return true iff, data reference of TYPE can reach vector alignment (16)
3554 after applying N number of iterations. This routine does not determine
3555 how may iterations are required to reach desired alignment. */
3558 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
3565 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
3568 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
3578 /* Assuming that all other types are naturally aligned. CHECKME! */
3583 /* Return true if the vector misalignment factor is supported by the
3586 rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
3593 /* Return if movmisalign pattern is not supported for this mode. */
3594 if (optab_handler (movmisalign_optab, mode) == CODE_FOR_nothing)
3597 if (misalignment == -1)
3599 /* Misalignment factor is unknown at compile time but we know
3600 it's word aligned. */
3601 if (rs6000_vector_alignment_reachable (type, is_packed))
3603 int element_size = TREE_INT_CST_LOW (TYPE_SIZE (type));
3605 if (element_size == 64 || element_size == 32)
3612 /* VSX supports word-aligned vector. */
3613 if (misalignment % 4 == 0)
3619 /* Implement targetm.vectorize.builtin_vec_perm. */
3621 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
3623 tree inner_type = TREE_TYPE (type);
3624 bool uns_p = TYPE_UNSIGNED (inner_type);
3627 *mask_element_type = unsigned_char_type_node;
3629 switch (TYPE_MODE (type))
3633 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
3634 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
3639 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
3640 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
3645 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
3646 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
3650 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
3654 if (!TARGET_ALLOW_DF_PERMUTE)
3657 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
3661 if (!TARGET_ALLOW_DF_PERMUTE)
3665 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
3666 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
3678 /* Implement targetm.vectorize.builtin_vectorization_cost. */
3680 rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
3681 tree vectype, int misalign)
3685 switch (type_of_cost)
3695 case cond_branch_not_taken:
3699 case cond_branch_taken:
3702 case unaligned_load:
3703 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3705 elements = TYPE_VECTOR_SUBPARTS (vectype);
3707 /* Double word aligned. */
3715 /* Double word aligned. */
3719 /* Unknown misalignment. */
3732 /* Misaligned loads are not supported. */
3737 case unaligned_store:
3738 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3740 elements = TYPE_VECTOR_SUBPARTS (vectype);
3742 /* Double word aligned. */
3750 /* Double word aligned. */
3754 /* Unknown misalignment. */
3767 /* Misaligned stores are not supported. */
3777 /* Implement targetm.vectorize.preferred_simd_mode. */
3779 static enum machine_mode
3780 rs6000_preferred_simd_mode (enum machine_mode mode)
3789 if (TARGET_ALTIVEC || TARGET_VSX)
3813 if (TARGET_PAIRED_FLOAT
3819 /* Handle generic options of the form -mfoo=yes/no.
3820 NAME is the option name.
3821 VALUE is the option value.
3822 FLAG is the pointer to the flag where to store a 1 or 0, depending on
3823 whether the option value is 'yes' or 'no' respectively. */
3825 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
3829 else if (!strcmp (value, "yes"))
3831 else if (!strcmp (value, "no"))
3834 error ("unknown -m%s= option specified: '%s'", name, value);
3837 /* Implement TARGET_OPTION_INIT_STRUCT. */
3840 rs6000_option_init_struct (struct gcc_options *opts)
3842 if (DEFAULT_ABI == ABI_DARWIN)
3843 /* The Darwin libraries never set errno, so we might as well
3844 avoid calling them when that's the only reason we would. */
3845 opts->x_flag_errno_math = 0;
3847 /* Enable section anchors by default. */
3849 opts->x_flag_section_anchors = 1;
3852 /* Implement TARGET_OPTION_DEFAULT_PARAMS. */
3855 rs6000_option_default_params (void)
3857 /* Double growth factor to counter reduced min jump length. */
3858 set_default_param_value (PARAM_MAX_GROW_COPY_BB_INSNS, 16);
3861 static enum fpu_type_t
3862 rs6000_parse_fpu_option (const char *option)
3864 if (!strcmp("none", option)) return FPU_NONE;
3865 if (!strcmp("sp_lite", option)) return FPU_SF_LITE;
3866 if (!strcmp("dp_lite", option)) return FPU_DF_LITE;
3867 if (!strcmp("sp_full", option)) return FPU_SF_FULL;
3868 if (!strcmp("dp_full", option)) return FPU_DF_FULL;
3869 error("unknown value %s for -mfpu", option);
3874 /* Handler for the Mathematical Acceleration Subsystem (mass) interface to a
3875 library with vectorized intrinsics. */
3878 rs6000_builtin_vectorized_libmass (tree fndecl, tree type_out, tree type_in)
3881 const char *suffix = NULL;
3882 tree fntype, new_fndecl, bdecl = NULL_TREE;
3885 enum machine_mode el_mode, in_mode;
3888 /* Libmass is suitable for unsafe math only as it does not correctly support
3889 parts of IEEE with the required precision such as denormals. Only support
3890 it if we have VSX to use the simd d2 or f4 functions.
3891 XXX: Add variable length support. */
3892 if (!flag_unsafe_math_optimizations || !TARGET_VSX)
3895 el_mode = TYPE_MODE (TREE_TYPE (type_out));
3896 n = TYPE_VECTOR_SUBPARTS (type_out);
3897 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3898 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3899 if (el_mode != in_mode
3903 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3905 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3908 case BUILT_IN_ATAN2:
3909 case BUILT_IN_HYPOT:
3915 case BUILT_IN_ACOSH:
3917 case BUILT_IN_ASINH:
3919 case BUILT_IN_ATANH:
3927 case BUILT_IN_EXPM1:
3928 case BUILT_IN_LGAMMA:
3929 case BUILT_IN_LOG10:
3930 case BUILT_IN_LOG1P:
3938 bdecl = implicit_built_in_decls[fn];
3939 suffix = "d2"; /* pow -> powd2 */
3940 if (el_mode != DFmode
3945 case BUILT_IN_ATAN2F:
3946 case BUILT_IN_HYPOTF:
3951 case BUILT_IN_ACOSF:
3952 case BUILT_IN_ACOSHF:
3953 case BUILT_IN_ASINF:
3954 case BUILT_IN_ASINHF:
3955 case BUILT_IN_ATANF:
3956 case BUILT_IN_ATANHF:
3957 case BUILT_IN_CBRTF:
3959 case BUILT_IN_COSHF:
3961 case BUILT_IN_ERFCF:
3962 case BUILT_IN_EXP2F:
3964 case BUILT_IN_EXPM1F:
3965 case BUILT_IN_LGAMMAF:
3966 case BUILT_IN_LOG10F:
3967 case BUILT_IN_LOG1PF:
3968 case BUILT_IN_LOG2F:
3971 case BUILT_IN_SINHF:
3972 case BUILT_IN_SQRTF:
3974 case BUILT_IN_TANHF:
3975 bdecl = implicit_built_in_decls[fn];
3976 suffix = "4"; /* powf -> powf4 */
3977 if (el_mode != SFmode
3989 gcc_assert (suffix != NULL);
3990 bname = IDENTIFIER_POINTER (DECL_NAME (bdecl));
3991 strcpy (name, bname + sizeof ("__builtin_") - 1);
3992 strcat (name, suffix);
3995 fntype = build_function_type_list (type_out, type_in, NULL);
3996 else if (n_args == 2)
3997 fntype = build_function_type_list (type_out, type_in, type_in, NULL);
4001 /* Build a function declaration for the vectorized function. */
4002 new_fndecl = build_decl (BUILTINS_LOCATION,
4003 FUNCTION_DECL, get_identifier (name), fntype);
4004 TREE_PUBLIC (new_fndecl) = 1;
4005 DECL_EXTERNAL (new_fndecl) = 1;
4006 DECL_IS_NOVOPS (new_fndecl) = 1;
4007 TREE_READONLY (new_fndecl) = 1;
4012 /* Returns a function decl for a vectorized version of the builtin function
4013 with builtin function code FN and the result vector type TYPE, or NULL_TREE
4014 if it is not available. */
4017 rs6000_builtin_vectorized_function (tree fndecl, tree type_out,
4020 enum machine_mode in_mode, out_mode;
4023 if (TREE_CODE (type_out) != VECTOR_TYPE
4024 || TREE_CODE (type_in) != VECTOR_TYPE
4025 || !TARGET_VECTORIZE_BUILTINS)
4028 out_mode = TYPE_MODE (TREE_TYPE (type_out));
4029 out_n = TYPE_VECTOR_SUBPARTS (type_out);
4030 in_mode = TYPE_MODE (TREE_TYPE (type_in));
4031 in_n = TYPE_VECTOR_SUBPARTS (type_in);
4033 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
4035 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
4038 case BUILT_IN_COPYSIGN:
4039 if (VECTOR_UNIT_VSX_P (V2DFmode)
4040 && out_mode == DFmode && out_n == 2
4041 && in_mode == DFmode && in_n == 2)
4042 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
4044 case BUILT_IN_COPYSIGNF:
4045 if (out_mode != SFmode || out_n != 4
4046 || in_mode != SFmode || in_n != 4)
4048 if (VECTOR_UNIT_VSX_P (V4SFmode))
4049 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
4050 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4051 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
4054 if (VECTOR_UNIT_VSX_P (V2DFmode)
4055 && out_mode == DFmode && out_n == 2
4056 && in_mode == DFmode && in_n == 2)
4057 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
4059 case BUILT_IN_SQRTF:
4060 if (VECTOR_UNIT_VSX_P (V4SFmode)
4061 && out_mode == SFmode && out_n == 4
4062 && in_mode == SFmode && in_n == 4)
4063 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
4066 if (VECTOR_UNIT_VSX_P (V2DFmode)
4067 && out_mode == DFmode && out_n == 2
4068 && in_mode == DFmode && in_n == 2)
4069 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
4071 case BUILT_IN_CEILF:
4072 if (out_mode != SFmode || out_n != 4
4073 || in_mode != SFmode || in_n != 4)
4075 if (VECTOR_UNIT_VSX_P (V4SFmode))
4076 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
4077 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4078 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
4080 case BUILT_IN_FLOOR:
4081 if (VECTOR_UNIT_VSX_P (V2DFmode)
4082 && out_mode == DFmode && out_n == 2
4083 && in_mode == DFmode && in_n == 2)
4084 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
4086 case BUILT_IN_FLOORF:
4087 if (out_mode != SFmode || out_n != 4
4088 || in_mode != SFmode || in_n != 4)
4090 if (VECTOR_UNIT_VSX_P (V4SFmode))
4091 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
4092 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4093 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
4096 if (VECTOR_UNIT_VSX_P (V2DFmode)
4097 && out_mode == DFmode && out_n == 2
4098 && in_mode == DFmode && in_n == 2)
4099 return rs6000_builtin_decls[VSX_BUILTIN_XVMADDDP];
4102 if (VECTOR_UNIT_VSX_P (V4SFmode)
4103 && out_mode == SFmode && out_n == 4
4104 && in_mode == SFmode && in_n == 4)
4105 return rs6000_builtin_decls[VSX_BUILTIN_XVMADDSP];
4106 else if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)
4107 && out_mode == SFmode && out_n == 4
4108 && in_mode == SFmode && in_n == 4)
4109 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VMADDFP];
4111 case BUILT_IN_TRUNC:
4112 if (VECTOR_UNIT_VSX_P (V2DFmode)
4113 && out_mode == DFmode && out_n == 2
4114 && in_mode == DFmode && in_n == 2)
4115 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
4117 case BUILT_IN_TRUNCF:
4118 if (out_mode != SFmode || out_n != 4
4119 || in_mode != SFmode || in_n != 4)
4121 if (VECTOR_UNIT_VSX_P (V4SFmode))
4122 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
4123 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4124 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
4126 case BUILT_IN_NEARBYINT:
4127 if (VECTOR_UNIT_VSX_P (V2DFmode)
4128 && flag_unsafe_math_optimizations
4129 && out_mode == DFmode && out_n == 2
4130 && in_mode == DFmode && in_n == 2)
4131 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
4133 case BUILT_IN_NEARBYINTF:
4134 if (VECTOR_UNIT_VSX_P (V4SFmode)
4135 && flag_unsafe_math_optimizations
4136 && out_mode == SFmode && out_n == 4
4137 && in_mode == SFmode && in_n == 4)
4138 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
4141 if (VECTOR_UNIT_VSX_P (V2DFmode)
4142 && !flag_trapping_math
4143 && out_mode == DFmode && out_n == 2
4144 && in_mode == DFmode && in_n == 2)
4145 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
4147 case BUILT_IN_RINTF:
4148 if (VECTOR_UNIT_VSX_P (V4SFmode)
4149 && !flag_trapping_math
4150 && out_mode == SFmode && out_n == 4
4151 && in_mode == SFmode && in_n == 4)
4152 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
4159 else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
4161 enum rs6000_builtins fn
4162 = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl);
4165 case RS6000_BUILTIN_RSQRTF:
4166 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
4167 && out_mode == SFmode && out_n == 4
4168 && in_mode == SFmode && in_n == 4)
4169 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRSQRTFP];
4171 case RS6000_BUILTIN_RSQRT:
4172 if (VECTOR_UNIT_VSX_P (V2DFmode)
4173 && out_mode == DFmode && out_n == 2
4174 && in_mode == DFmode && in_n == 2)
4175 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
4177 case RS6000_BUILTIN_RECIPF:
4178 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
4179 && out_mode == SFmode && out_n == 4
4180 && in_mode == SFmode && in_n == 4)
4181 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRECIPFP];
4183 case RS6000_BUILTIN_RECIP:
4184 if (VECTOR_UNIT_VSX_P (V2DFmode)
4185 && out_mode == DFmode && out_n == 2
4186 && in_mode == DFmode && in_n == 2)
4187 return rs6000_builtin_decls[VSX_BUILTIN_RECIP_V2DF];
4194 /* Generate calls to libmass if appropriate. */
4195 if (rs6000_veclib_handler)
4196 return rs6000_veclib_handler (fndecl, type_out, type_in);
4202 /* Implement TARGET_HANDLE_OPTION. */
4205 rs6000_handle_option (size_t code, const char *arg, int value)
4207 enum fpu_type_t fpu_type = FPU_NONE;
4214 target_flags &= ~(MASK_POWER | MASK_POWER2
4215 | MASK_MULTIPLE | MASK_STRING);
4216 target_flags_explicit |= (MASK_POWER | MASK_POWER2
4217 | MASK_MULTIPLE | MASK_STRING);
4219 case OPT_mno_powerpc:
4220 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
4221 | MASK_PPC_GFXOPT | MASK_POWERPC64);
4222 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
4223 | MASK_PPC_GFXOPT | MASK_POWERPC64);
4226 target_flags &= ~MASK_MINIMAL_TOC;
4227 TARGET_NO_FP_IN_TOC = 0;
4228 TARGET_NO_SUM_IN_TOC = 0;
4229 target_flags_explicit |= MASK_MINIMAL_TOC;
4230 #ifdef TARGET_USES_SYSV4_OPT
4231 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
4232 just the same as -mminimal-toc. */
4233 target_flags |= MASK_MINIMAL_TOC;
4234 target_flags_explicit |= MASK_MINIMAL_TOC;
4238 #ifdef TARGET_USES_SYSV4_OPT
4240 /* Make -mtoc behave like -mminimal-toc. */
4241 target_flags |= MASK_MINIMAL_TOC;
4242 target_flags_explicit |= MASK_MINIMAL_TOC;
4246 #if defined (HAVE_LD_LARGE_TOC) && defined (TARGET_USES_LINUX64_OPT)
4248 if (strcmp (arg, "small") == 0)
4249 rs6000_current_cmodel = CMODEL_SMALL;
4250 else if (strcmp (arg, "medium") == 0)
4251 rs6000_current_cmodel = CMODEL_MEDIUM;
4252 else if (strcmp (arg, "large") == 0)
4253 rs6000_current_cmodel = CMODEL_LARGE;
4256 error ("invalid option for -mcmodel: '%s'", arg);
4259 rs6000_explicit_options.cmodel = true;
4262 #ifdef TARGET_USES_AIX64_OPT
4267 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
4268 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
4269 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
4272 #ifdef TARGET_USES_AIX64_OPT
4277 target_flags &= ~MASK_POWERPC64;
4278 target_flags_explicit |= MASK_POWERPC64;
4281 case OPT_minsert_sched_nops_:
4282 rs6000_sched_insert_nops_str = arg;
4285 case OPT_mminimal_toc:
4288 TARGET_NO_FP_IN_TOC = 0;
4289 TARGET_NO_SUM_IN_TOC = 0;
4296 target_flags |= (MASK_MULTIPLE | MASK_STRING);
4297 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
4304 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
4305 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
4309 case OPT_mpowerpc_gpopt:
4310 case OPT_mpowerpc_gfxopt:
4313 target_flags |= MASK_POWERPC;
4314 target_flags_explicit |= MASK_POWERPC;
4318 case OPT_maix_struct_return:
4319 case OPT_msvr4_struct_return:
4320 rs6000_explicit_options.aix_struct_ret = true;
4324 rs6000_explicit_options.vrsave = true;
4325 TARGET_ALTIVEC_VRSAVE = value;
4329 rs6000_explicit_options.vrsave = true;
4330 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
4334 target_flags_explicit |= MASK_ISEL;
4336 rs6000_parse_yes_no_option ("isel", arg, &isel);
4338 target_flags |= MASK_ISEL;
4340 target_flags &= ~MASK_ISEL;
4344 rs6000_explicit_options.spe = true;
4349 rs6000_explicit_options.spe = true;
4350 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
4357 while ((q = strtok (p, ",")) != NULL)
4371 if (! strcmp (q, "all"))
4372 mask = MASK_DEBUG_ALL;
4373 else if (! strcmp (q, "stack"))
4374 mask = MASK_DEBUG_STACK;
4375 else if (! strcmp (q, "arg"))
4376 mask = MASK_DEBUG_ARG;
4377 else if (! strcmp (q, "reg"))
4378 mask = MASK_DEBUG_REG;
4379 else if (! strcmp (q, "addr"))
4380 mask = MASK_DEBUG_ADDR;
4381 else if (! strcmp (q, "cost"))
4382 mask = MASK_DEBUG_COST;
4383 else if (! strcmp (q, "target"))
4384 mask = MASK_DEBUG_TARGET;
4386 error ("unknown -mdebug-%s switch", q);
4389 rs6000_debug &= ~mask;
4391 rs6000_debug |= mask;
4395 #ifdef TARGET_USES_SYSV4_OPT
4397 rs6000_abi_name = arg;
4401 rs6000_sdata_name = arg;
4404 case OPT_mtls_size_:
4405 if (strcmp (arg, "16") == 0)
4406 rs6000_tls_size = 16;
4407 else if (strcmp (arg, "32") == 0)
4408 rs6000_tls_size = 32;
4409 else if (strcmp (arg, "64") == 0)
4410 rs6000_tls_size = 64;
4412 error ("bad value %qs for -mtls-size switch", arg);
4415 case OPT_mrelocatable:
4418 target_flags |= MASK_MINIMAL_TOC;
4419 target_flags_explicit |= MASK_MINIMAL_TOC;
4420 TARGET_NO_FP_IN_TOC = 1;
4424 case OPT_mrelocatable_lib:
4427 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
4428 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
4429 TARGET_NO_FP_IN_TOC = 1;
4433 target_flags &= ~MASK_RELOCATABLE;
4434 target_flags_explicit |= MASK_RELOCATABLE;
4440 if (!strcmp (arg, "altivec"))
4442 rs6000_explicit_options.altivec_abi = true;
4443 rs6000_altivec_abi = 1;
4445 /* Enabling the AltiVec ABI turns off the SPE ABI. */
4448 else if (! strcmp (arg, "no-altivec"))
4450 rs6000_explicit_options.altivec_abi = true;
4451 rs6000_altivec_abi = 0;
4453 else if (! strcmp (arg, "spe"))
4455 rs6000_explicit_options.spe_abi = true;
4457 rs6000_altivec_abi = 0;
4458 if (!TARGET_SPE_ABI)
4459 error ("not configured for ABI: '%s'", arg);
4461 else if (! strcmp (arg, "no-spe"))
4463 rs6000_explicit_options.spe_abi = true;
4467 /* These are here for testing during development only, do not
4468 document in the manual please. */
4469 else if (! strcmp (arg, "d64"))
4471 rs6000_darwin64_abi = 1;
4472 warning (0, "using darwin64 ABI");
4474 else if (! strcmp (arg, "d32"))
4476 rs6000_darwin64_abi = 0;
4477 warning (0, "using old darwin ABI");
4480 else if (! strcmp (arg, "ibmlongdouble"))
4482 rs6000_explicit_options.ieee = true;
4483 rs6000_ieeequad = 0;
4484 warning (0, "using IBM extended precision long double");
4486 else if (! strcmp (arg, "ieeelongdouble"))
4488 rs6000_explicit_options.ieee = true;
4489 rs6000_ieeequad = 1;
4490 warning (0, "using IEEE extended precision long double");
4495 error ("unknown ABI specified: '%s'", arg);
4501 rs6000_select[1].string = arg;
4502 rs6000_cpu_index = rs6000_cpu_name_lookup (arg);
4503 if (rs6000_cpu_index < 0)
4504 error ("bad value (%s) for -mcpu", arg);
4508 rs6000_select[2].string = arg;
4509 rs6000_tune_index = rs6000_cpu_name_lookup (arg);
4510 if (rs6000_tune_index < 0)
4511 error ("bad value (%s) for -mtune", arg);
4514 case OPT_mtraceback_:
4515 if (! strncmp (arg, "full", 4))
4516 rs6000_traceback = traceback_full;
4517 else if (! strncmp (arg, "part", 4))
4518 rs6000_traceback = traceback_part;
4519 else if (! strncmp (arg, "no", 2))
4520 rs6000_traceback = traceback_none;
4522 error ("unknown -mtraceback arg %qs; expecting %<full%>, "
4523 "%<partial%> or %<none%>", arg);
4526 case OPT_mfloat_gprs_:
4527 rs6000_explicit_options.float_gprs = true;
4528 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
4529 rs6000_float_gprs = 1;
4530 else if (! strcmp (arg, "double"))
4531 rs6000_float_gprs = 2;
4532 else if (! strcmp (arg, "no"))
4533 rs6000_float_gprs = 0;
4536 error ("invalid option for -mfloat-gprs: '%s'", arg);
4541 case OPT_mlong_double_:
4542 rs6000_explicit_options.long_double = true;
4543 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4544 if (value != 64 && value != 128)
4546 error ("unknown switch -mlong-double-%s", arg);
4547 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4551 rs6000_long_double_type_size = value;
4554 case OPT_msched_costly_dep_:
4555 rs6000_sched_costly_dep_str = arg;
4559 rs6000_explicit_options.alignment = true;
4560 if (! strcmp (arg, "power"))
4562 /* On 64-bit Darwin, power alignment is ABI-incompatible with
4563 some C library functions, so warn about it. The flag may be
4564 useful for performance studies from time to time though, so
4565 don't disable it entirely. */
4566 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
4567 warning (0, "-malign-power is not supported for 64-bit Darwin;"
4568 " it is incompatible with the installed C and C++ libraries");
4569 rs6000_alignment_flags = MASK_ALIGN_POWER;
4571 else if (! strcmp (arg, "natural"))
4572 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
4575 error ("unknown -malign-XXXXX option specified: '%s'", arg);
4580 case OPT_msingle_float:
4581 if (!TARGET_SINGLE_FPU)
4582 warning (0, "-msingle-float option equivalent to -mhard-float");
4583 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
4584 rs6000_double_float = 0;
4585 target_flags &= ~MASK_SOFT_FLOAT;
4586 target_flags_explicit |= MASK_SOFT_FLOAT;
4589 case OPT_mdouble_float:
4590 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
4591 rs6000_single_float = 1;
4592 target_flags &= ~MASK_SOFT_FLOAT;
4593 target_flags_explicit |= MASK_SOFT_FLOAT;
4596 case OPT_msimple_fpu:
4597 if (!TARGET_SINGLE_FPU)
4598 warning (0, "-msimple-fpu option ignored");
4601 case OPT_mhard_float:
4602 /* -mhard_float implies -msingle-float and -mdouble-float. */
4603 rs6000_single_float = rs6000_double_float = 1;
4606 case OPT_msoft_float:
4607 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
4608 rs6000_single_float = rs6000_double_float = 0;
4612 fpu_type = rs6000_parse_fpu_option(arg);
4613 if (fpu_type != FPU_NONE)
4614 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
4616 target_flags &= ~MASK_SOFT_FLOAT;
4617 target_flags_explicit |= MASK_SOFT_FLOAT;
4618 rs6000_xilinx_fpu = 1;
4619 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
4620 rs6000_single_float = 1;
4621 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
4622 rs6000_single_float = rs6000_double_float = 1;
4623 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
4624 rs6000_simple_fpu = 1;
4628 /* -mfpu=none is equivalent to -msoft-float */
4629 target_flags |= MASK_SOFT_FLOAT;
4630 target_flags_explicit |= MASK_SOFT_FLOAT;
4631 rs6000_single_float = rs6000_double_float = 0;
4635 rs6000_recip_name = (value) ? "default" : "none";
4639 rs6000_recip_name = arg;
4645 /* Do anything needed at the start of the asm file. */
4648 rs6000_file_start (void)
4652 const char *start = buffer;
4653 struct rs6000_cpu_select *ptr;
4654 const char *default_cpu = TARGET_CPU_DEFAULT;
4655 FILE *file = asm_out_file;
4657 default_file_start ();
4659 #ifdef TARGET_BI_ARCH
4660 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
4664 if (flag_verbose_asm)
4666 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
4667 rs6000_select[0].string = default_cpu;
4669 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
4671 ptr = &rs6000_select[i];
4672 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
4674 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
4679 if (PPC405_ERRATUM77)
4681 fprintf (file, "%s PPC405CR_ERRATUM77", start);
4685 #ifdef USING_ELFOS_H
4686 switch (rs6000_sdata)
4688 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
4689 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
4690 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
4691 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
4694 if (rs6000_sdata && g_switch_value)
4696 fprintf (file, "%s -G %d", start,
4706 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
4708 switch_to_section (toc_section);
4709 switch_to_section (text_section);
4714 /* Return nonzero if this function is known to have a null epilogue. */
4717 direct_return (void)
4719 if (reload_completed)
4721 rs6000_stack_t *info = rs6000_stack_info ();
4723 if (info->first_gp_reg_save == 32
4724 && info->first_fp_reg_save == 64
4725 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
4726 && ! info->lr_save_p
4727 && ! info->cr_save_p
4728 && info->vrsave_mask == 0
4736 /* Return the number of instructions it takes to form a constant in an
4737 integer register. */
4740 num_insns_constant_wide (HOST_WIDE_INT value)
4742 /* signed constant loadable with {cal|addi} */
4743 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
4746 /* constant loadable with {cau|addis} */
4747 else if ((value & 0xffff) == 0
4748 && (value >> 31 == -1 || value >> 31 == 0))
4751 #if HOST_BITS_PER_WIDE_INT == 64
4752 else if (TARGET_POWERPC64)
4754 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
4755 HOST_WIDE_INT high = value >> 31;
4757 if (high == 0 || high == -1)
4763 return num_insns_constant_wide (high) + 1;
4765 return num_insns_constant_wide (low) + 1;
4767 return (num_insns_constant_wide (high)
4768 + num_insns_constant_wide (low) + 1);
4777 num_insns_constant (rtx op, enum machine_mode mode)
4779 HOST_WIDE_INT low, high;
4781 switch (GET_CODE (op))
4784 #if HOST_BITS_PER_WIDE_INT == 64
4785 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
4786 && mask64_operand (op, mode))
4790 return num_insns_constant_wide (INTVAL (op));
4793 if (mode == SFmode || mode == SDmode)
4798 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4799 if (DECIMAL_FLOAT_MODE_P (mode))
4800 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
4802 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
4803 return num_insns_constant_wide ((HOST_WIDE_INT) l);
4806 if (mode == VOIDmode || mode == DImode)
4808 high = CONST_DOUBLE_HIGH (op);
4809 low = CONST_DOUBLE_LOW (op);
4816 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4817 if (DECIMAL_FLOAT_MODE_P (mode))
4818 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
4820 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
4821 high = l[WORDS_BIG_ENDIAN == 0];
4822 low = l[WORDS_BIG_ENDIAN != 0];
4826 return (num_insns_constant_wide (low)
4827 + num_insns_constant_wide (high));
4830 if ((high == 0 && low >= 0)
4831 || (high == -1 && low < 0))
4832 return num_insns_constant_wide (low);
4834 else if (mask64_operand (op, mode))
4838 return num_insns_constant_wide (high) + 1;
4841 return (num_insns_constant_wide (high)
4842 + num_insns_constant_wide (low) + 1);
4850 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
4851 If the mode of OP is MODE_VECTOR_INT, this simply returns the
4852 corresponding element of the vector, but for V4SFmode and V2SFmode,
4853 the corresponding "float" is interpreted as an SImode integer. */
4856 const_vector_elt_as_int (rtx op, unsigned int elt)
4858 rtx tmp = CONST_VECTOR_ELT (op, elt);
4859 if (GET_MODE (op) == V4SFmode
4860 || GET_MODE (op) == V2SFmode)
4861 tmp = gen_lowpart (SImode, tmp);
4862 return INTVAL (tmp);
4865 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
4866 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
4867 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
4868 all items are set to the same value and contain COPIES replicas of the
4869 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
4870 operand and the others are set to the value of the operand's msb. */
4873 vspltis_constant (rtx op, unsigned step, unsigned copies)
4875 enum machine_mode mode = GET_MODE (op);
4876 enum machine_mode inner = GET_MODE_INNER (mode);
4879 unsigned nunits = GET_MODE_NUNITS (mode);
4880 unsigned bitsize = GET_MODE_BITSIZE (inner);
4881 unsigned mask = GET_MODE_MASK (inner);
4883 HOST_WIDE_INT val = const_vector_elt_as_int (op, nunits - 1);
4884 HOST_WIDE_INT splat_val = val;
4885 HOST_WIDE_INT msb_val = val > 0 ? 0 : -1;
4887 /* Construct the value to be splatted, if possible. If not, return 0. */
4888 for (i = 2; i <= copies; i *= 2)
4890 HOST_WIDE_INT small_val;
4892 small_val = splat_val >> bitsize;
4894 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
4896 splat_val = small_val;
4899 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
4900 if (EASY_VECTOR_15 (splat_val))
4903 /* Also check if we can splat, and then add the result to itself. Do so if
4904 the value is positive, of if the splat instruction is using OP's mode;
4905 for splat_val < 0, the splat and the add should use the same mode. */
4906 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
4907 && (splat_val >= 0 || (step == 1 && copies == 1)))
4910 /* Also check if are loading up the most significant bit which can be done by
4911 loading up -1 and shifting the value left by -1. */
4912 else if (EASY_VECTOR_MSB (splat_val, inner))
4918 /* Check if VAL is present in every STEP-th element, and the
4919 other elements are filled with its most significant bit. */
4920 for (i = 0; i < nunits - 1; ++i)
4922 HOST_WIDE_INT desired_val;
4923 if (((i + 1) & (step - 1)) == 0)
4926 desired_val = msb_val;
4928 if (desired_val != const_vector_elt_as_int (op, i))
4936 /* Return true if OP is of the given MODE and can be synthesized
4937 with a vspltisb, vspltish or vspltisw. */
4940 easy_altivec_constant (rtx op, enum machine_mode mode)
4942 unsigned step, copies;
4944 if (mode == VOIDmode)
4945 mode = GET_MODE (op);
4946 else if (mode != GET_MODE (op))
4949 /* Start with a vspltisw. */
4950 step = GET_MODE_NUNITS (mode) / 4;
4953 if (vspltis_constant (op, step, copies))
4956 /* Then try with a vspltish. */
4962 if (vspltis_constant (op, step, copies))
4965 /* And finally a vspltisb. */
4971 if (vspltis_constant (op, step, copies))
4977 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
4978 result is OP. Abort if it is not possible. */
4981 gen_easy_altivec_constant (rtx op)
4983 enum machine_mode mode = GET_MODE (op);
4984 int nunits = GET_MODE_NUNITS (mode);
4985 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
4986 unsigned step = nunits / 4;
4987 unsigned copies = 1;
4989 /* Start with a vspltisw. */
4990 if (vspltis_constant (op, step, copies))
4991 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
4993 /* Then try with a vspltish. */
4999 if (vspltis_constant (op, step, copies))
5000 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
5002 /* And finally a vspltisb. */
5008 if (vspltis_constant (op, step, copies))
5009 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
5015 output_vec_const_move (rtx *operands)
5018 enum machine_mode mode;
5023 mode = GET_MODE (dest);
5025 if (TARGET_VSX && zero_constant (vec, mode))
5026 return "xxlxor %x0,%x0,%x0";
5031 if (zero_constant (vec, mode))
5032 return "vxor %0,%0,%0";
5034 splat_vec = gen_easy_altivec_constant (vec);
5035 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
5036 operands[1] = XEXP (splat_vec, 0);
5037 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
5040 switch (GET_MODE (splat_vec))
5043 return "vspltisw %0,%1";
5046 return "vspltish %0,%1";
5049 return "vspltisb %0,%1";
5056 gcc_assert (TARGET_SPE);
5058 /* Vector constant 0 is handled as a splitter of V2SI, and in the
5059 pattern of V1DI, V4HI, and V2SF.
5061 FIXME: We should probably return # and add post reload
5062 splitters for these, but this way is so easy ;-). */
5063 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
5064 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
5065 operands[1] = CONST_VECTOR_ELT (vec, 0);
5066 operands[2] = CONST_VECTOR_ELT (vec, 1);
5068 return "li %0,%1\n\tevmergelo %0,%0,%0";
5070 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
5073 /* Initialize TARGET of vector PAIRED to VALS. */
5076 paired_expand_vector_init (rtx target, rtx vals)
5078 enum machine_mode mode = GET_MODE (target);
5079 int n_elts = GET_MODE_NUNITS (mode);
5081 rtx x, new_rtx, tmp, constant_op, op1, op2;
5084 for (i = 0; i < n_elts; ++i)
5086 x = XVECEXP (vals, 0, i);
5087 if (!CONSTANT_P (x))
5092 /* Load from constant pool. */
5093 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
5099 /* The vector is initialized only with non-constants. */
5100 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
5101 XVECEXP (vals, 0, 1));
5103 emit_move_insn (target, new_rtx);
5107 /* One field is non-constant and the other one is a constant. Load the
5108 constant from the constant pool and use ps_merge instruction to
5109 construct the whole vector. */
5110 op1 = XVECEXP (vals, 0, 0);
5111 op2 = XVECEXP (vals, 0, 1);
5113 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
5115 tmp = gen_reg_rtx (GET_MODE (constant_op));
5116 emit_move_insn (tmp, constant_op);
5118 if (CONSTANT_P (op1))
5119 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
5121 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
5123 emit_move_insn (target, new_rtx);
5127 paired_expand_vector_move (rtx operands[])
5129 rtx op0 = operands[0], op1 = operands[1];
5131 emit_move_insn (op0, op1);
5134 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
5135 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
5136 operands for the relation operation COND. This is a recursive
5140 paired_emit_vector_compare (enum rtx_code rcode,
5141 rtx dest, rtx op0, rtx op1,
5142 rtx cc_op0, rtx cc_op1)
5144 rtx tmp = gen_reg_rtx (V2SFmode);
5147 gcc_assert (TARGET_PAIRED_FLOAT);
5148 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
5154 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
5158 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
5159 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
5163 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
5166 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
5169 tmp1 = gen_reg_rtx (V2SFmode);
5170 max = gen_reg_rtx (V2SFmode);
5171 min = gen_reg_rtx (V2SFmode);
5172 gen_reg_rtx (V2SFmode);
5174 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
5175 emit_insn (gen_selv2sf4
5176 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
5177 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
5178 emit_insn (gen_selv2sf4
5179 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
5180 emit_insn (gen_subv2sf3 (tmp1, min, max));
5181 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
5184 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
5187 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
5190 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
5193 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
5196 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
5205 /* Emit vector conditional expression.
5206 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
5207 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
5210 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
5211 rtx cond, rtx cc_op0, rtx cc_op1)
5213 enum rtx_code rcode = GET_CODE (cond);
5215 if (!TARGET_PAIRED_FLOAT)
5218 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
5223 /* Initialize vector TARGET to VALS. */
5226 rs6000_expand_vector_init (rtx target, rtx vals)
5228 enum machine_mode mode = GET_MODE (target);
5229 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5230 int n_elts = GET_MODE_NUNITS (mode);
5231 int n_var = 0, one_var = -1;
5232 bool all_same = true, all_const_zero = true;
5236 for (i = 0; i < n_elts; ++i)
5238 x = XVECEXP (vals, 0, i);
5239 if (!CONSTANT_P (x))
5240 ++n_var, one_var = i;
5241 else if (x != CONST0_RTX (inner_mode))
5242 all_const_zero = false;
5244 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
5250 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
5251 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
5252 if ((int_vector_p || TARGET_VSX) && all_const_zero)
5254 /* Zero register. */
5255 emit_insn (gen_rtx_SET (VOIDmode, target,
5256 gen_rtx_XOR (mode, target, target)));
5259 else if (int_vector_p && easy_vector_constant (const_vec, mode))
5261 /* Splat immediate. */
5262 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
5267 /* Load from constant pool. */
5268 emit_move_insn (target, const_vec);
5273 /* Double word values on VSX can use xxpermdi or lxvdsx. */
5274 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5278 rtx element = XVECEXP (vals, 0, 0);
5279 if (mode == V2DFmode)
5280 emit_insn (gen_vsx_splat_v2df (target, element));
5282 emit_insn (gen_vsx_splat_v2di (target, element));
5286 rtx op0 = copy_to_reg (XVECEXP (vals, 0, 0));
5287 rtx op1 = copy_to_reg (XVECEXP (vals, 0, 1));
5288 if (mode == V2DFmode)
5289 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
5291 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
5296 /* With single precision floating point on VSX, know that internally single
5297 precision is actually represented as a double, and either make 2 V2DF
5298 vectors, and convert these vectors to single precision, or do one
5299 conversion, and splat the result to the other elements. */
5300 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
5304 rtx freg = gen_reg_rtx (V4SFmode);
5305 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
5307 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
5308 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
5312 rtx dbl_even = gen_reg_rtx (V2DFmode);
5313 rtx dbl_odd = gen_reg_rtx (V2DFmode);
5314 rtx flt_even = gen_reg_rtx (V4SFmode);
5315 rtx flt_odd = gen_reg_rtx (V4SFmode);
5317 emit_insn (gen_vsx_concat_v2sf (dbl_even,
5318 copy_to_reg (XVECEXP (vals, 0, 0)),
5319 copy_to_reg (XVECEXP (vals, 0, 1))));
5320 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
5321 copy_to_reg (XVECEXP (vals, 0, 2)),
5322 copy_to_reg (XVECEXP (vals, 0, 3))));
5323 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
5324 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
5325 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
5330 /* Store value to stack temp. Load vector element. Splat. However, splat
5331 of 64-bit items is not supported on Altivec. */
5332 if (all_same && GET_MODE_SIZE (mode) <= 4)
5334 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
5335 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
5336 XVECEXP (vals, 0, 0));
5337 x = gen_rtx_UNSPEC (VOIDmode,
5338 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
5339 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5341 gen_rtx_SET (VOIDmode,
5344 x = gen_rtx_VEC_SELECT (inner_mode, target,
5345 gen_rtx_PARALLEL (VOIDmode,
5346 gen_rtvec (1, const0_rtx)));
5347 emit_insn (gen_rtx_SET (VOIDmode, target,
5348 gen_rtx_VEC_DUPLICATE (mode, x)));
5352 /* One field is non-constant. Load constant then overwrite
5356 rtx copy = copy_rtx (vals);
5358 /* Load constant part of vector, substitute neighboring value for
5360 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
5361 rs6000_expand_vector_init (target, copy);
5363 /* Insert variable. */
5364 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
5368 /* Construct the vector in memory one field at a time
5369 and load the whole vector. */
5370 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
5371 for (i = 0; i < n_elts; i++)
5372 emit_move_insn (adjust_address_nv (mem, inner_mode,
5373 i * GET_MODE_SIZE (inner_mode)),
5374 XVECEXP (vals, 0, i));
5375 emit_move_insn (target, mem);
5378 /* Set field ELT of TARGET to VAL. */
5381 rs6000_expand_vector_set (rtx target, rtx val, int elt)
5383 enum machine_mode mode = GET_MODE (target);
5384 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5385 rtx reg = gen_reg_rtx (mode);
5387 int width = GET_MODE_SIZE (inner_mode);
5390 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5392 rtx (*set_func) (rtx, rtx, rtx, rtx)
5393 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
5394 emit_insn (set_func (target, target, val, GEN_INT (elt)));
5398 /* Load single variable value. */
5399 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
5400 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
5401 x = gen_rtx_UNSPEC (VOIDmode,
5402 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
5403 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5405 gen_rtx_SET (VOIDmode,
5409 /* Linear sequence. */
5410 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
5411 for (i = 0; i < 16; ++i)
5412 XVECEXP (mask, 0, i) = GEN_INT (i);
5414 /* Set permute mask to insert element into target. */
5415 for (i = 0; i < width; ++i)
5416 XVECEXP (mask, 0, elt*width + i)
5417 = GEN_INT (i + 0x10);
5418 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
5419 x = gen_rtx_UNSPEC (mode,
5420 gen_rtvec (3, target, reg,
5421 force_reg (V16QImode, x)),
5423 emit_insn (gen_rtx_SET (VOIDmode, target, x));
5426 /* Extract field ELT from VEC into TARGET. */
5429 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
5431 enum machine_mode mode = GET_MODE (vec);
5432 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5435 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5437 rtx (*extract_func) (rtx, rtx, rtx)
5438 = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
5439 emit_insn (extract_func (target, vec, GEN_INT (elt)));
5443 /* Allocate mode-sized buffer. */
5444 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
5446 emit_move_insn (mem, vec);
5448 /* Add offset to field within buffer matching vector element. */
5449 mem = adjust_address_nv (mem, inner_mode, elt * GET_MODE_SIZE (inner_mode));
5451 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
5454 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
5455 implement ANDing by the mask IN. */
5457 build_mask64_2_operands (rtx in, rtx *out)
5459 #if HOST_BITS_PER_WIDE_INT >= 64
5460 unsigned HOST_WIDE_INT c, lsb, m1, m2;
5463 gcc_assert (GET_CODE (in) == CONST_INT);
5468 /* Assume c initially something like 0x00fff000000fffff. The idea
5469 is to rotate the word so that the middle ^^^^^^ group of zeros
5470 is at the MS end and can be cleared with an rldicl mask. We then
5471 rotate back and clear off the MS ^^ group of zeros with a
5473 c = ~c; /* c == 0xff000ffffff00000 */
5474 lsb = c & -c; /* lsb == 0x0000000000100000 */
5475 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
5476 c = ~c; /* c == 0x00fff000000fffff */
5477 c &= -lsb; /* c == 0x00fff00000000000 */
5478 lsb = c & -c; /* lsb == 0x0000100000000000 */
5479 c = ~c; /* c == 0xff000fffffffffff */
5480 c &= -lsb; /* c == 0xff00000000000000 */
5482 while ((lsb >>= 1) != 0)
5483 shift++; /* shift == 44 on exit from loop */
5484 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
5485 m1 = ~m1; /* m1 == 0x000000ffffffffff */
5486 m2 = ~c; /* m2 == 0x00ffffffffffffff */
5490 /* Assume c initially something like 0xff000f0000000000. The idea
5491 is to rotate the word so that the ^^^ middle group of zeros
5492 is at the LS end and can be cleared with an rldicr mask. We then
5493 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
5495 lsb = c & -c; /* lsb == 0x0000010000000000 */
5496 m2 = -lsb; /* m2 == 0xffffff0000000000 */
5497 c = ~c; /* c == 0x00fff0ffffffffff */
5498 c &= -lsb; /* c == 0x00fff00000000000 */
5499 lsb = c & -c; /* lsb == 0x0000100000000000 */
5500 c = ~c; /* c == 0xff000fffffffffff */
5501 c &= -lsb; /* c == 0xff00000000000000 */
5503 while ((lsb >>= 1) != 0)
5504 shift++; /* shift == 44 on exit from loop */
5505 m1 = ~c; /* m1 == 0x00ffffffffffffff */
5506 m1 >>= shift; /* m1 == 0x0000000000000fff */
5507 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
5510 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
5511 masks will be all 1's. We are guaranteed more than one transition. */
5512 out[0] = GEN_INT (64 - shift);
5513 out[1] = GEN_INT (m1);
5514 out[2] = GEN_INT (shift);
5515 out[3] = GEN_INT (m2);
5523 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
5526 invalid_e500_subreg (rtx op, enum machine_mode mode)
5528 if (TARGET_E500_DOUBLE)
5530 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
5531 subreg:TI and reg:TF. Decimal float modes are like integer
5532 modes (only low part of each register used) for this
5534 if (GET_CODE (op) == SUBREG
5535 && (mode == SImode || mode == DImode || mode == TImode
5536 || mode == DDmode || mode == TDmode)
5537 && REG_P (SUBREG_REG (op))
5538 && (GET_MODE (SUBREG_REG (op)) == DFmode
5539 || GET_MODE (SUBREG_REG (op)) == TFmode))
5542 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
5544 if (GET_CODE (op) == SUBREG
5545 && (mode == DFmode || mode == TFmode)
5546 && REG_P (SUBREG_REG (op))
5547 && (GET_MODE (SUBREG_REG (op)) == DImode
5548 || GET_MODE (SUBREG_REG (op)) == TImode
5549 || GET_MODE (SUBREG_REG (op)) == DDmode
5550 || GET_MODE (SUBREG_REG (op)) == TDmode))
5555 && GET_CODE (op) == SUBREG
5557 && REG_P (SUBREG_REG (op))
5558 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
5564 /* AIX increases natural record alignment to doubleword if the first
5565 field is an FP double while the FP fields remain word aligned. */
5568 rs6000_special_round_type_align (tree type, unsigned int computed,
5569 unsigned int specified)
5571 unsigned int align = MAX (computed, specified);
5572 tree field = TYPE_FIELDS (type);
5574 /* Skip all non field decls */
5575 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5576 field = DECL_CHAIN (field);
5578 if (field != NULL && field != type)
5580 type = TREE_TYPE (field);
5581 while (TREE_CODE (type) == ARRAY_TYPE)
5582 type = TREE_TYPE (type);
5584 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
5585 align = MAX (align, 64);
5591 /* Darwin increases record alignment to the natural alignment of
5595 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
5596 unsigned int specified)
5598 unsigned int align = MAX (computed, specified);
5600 if (TYPE_PACKED (type))
5603 /* Find the first field, looking down into aggregates. */
5605 tree field = TYPE_FIELDS (type);
5606 /* Skip all non field decls */
5607 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5608 field = DECL_CHAIN (field);
5611 /* A packed field does not contribute any extra alignment. */
5612 if (DECL_PACKED (field))
5614 type = TREE_TYPE (field);
5615 while (TREE_CODE (type) == ARRAY_TYPE)
5616 type = TREE_TYPE (type);
5617 } while (AGGREGATE_TYPE_P (type));
5619 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
5620 align = MAX (align, TYPE_ALIGN (type));
5625 /* Return 1 for an operand in small memory on V.4/eabi. */
5628 small_data_operand (rtx op ATTRIBUTE_UNUSED,
5629 enum machine_mode mode ATTRIBUTE_UNUSED)
5634 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
5637 if (DEFAULT_ABI != ABI_V4)
5640 /* Vector and float memory instructions have a limited offset on the
5641 SPE, so using a vector or float variable directly as an operand is
5644 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
5647 if (GET_CODE (op) == SYMBOL_REF)
5650 else if (GET_CODE (op) != CONST
5651 || GET_CODE (XEXP (op, 0)) != PLUS
5652 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
5653 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
5658 rtx sum = XEXP (op, 0);
5659 HOST_WIDE_INT summand;
5661 /* We have to be careful here, because it is the referenced address
5662 that must be 32k from _SDA_BASE_, not just the symbol. */
5663 summand = INTVAL (XEXP (sum, 1));
5664 if (summand < 0 || summand > g_switch_value)
5667 sym_ref = XEXP (sum, 0);
5670 return SYMBOL_REF_SMALL_P (sym_ref);
5676 /* Return true if either operand is a general purpose register. */
5679 gpr_or_gpr_p (rtx op0, rtx op1)
5681 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
5682 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
5686 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
5689 reg_offset_addressing_ok_p (enum machine_mode mode)
5699 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
5700 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
5708 /* Paired vector modes. Only reg+reg addressing is valid. */
5709 if (TARGET_PAIRED_FLOAT)
5721 virtual_stack_registers_memory_p (rtx op)
5725 if (GET_CODE (op) == REG)
5726 regnum = REGNO (op);
5728 else if (GET_CODE (op) == PLUS
5729 && GET_CODE (XEXP (op, 0)) == REG
5730 && GET_CODE (XEXP (op, 1)) == CONST_INT)
5731 regnum = REGNO (XEXP (op, 0));
5736 return (regnum >= FIRST_VIRTUAL_REGISTER
5737 && regnum <= LAST_VIRTUAL_POINTER_REGISTER);
5741 constant_pool_expr_p (rtx op)
5745 split_const (op, &base, &offset);
5746 return (GET_CODE (base) == SYMBOL_REF
5747 && CONSTANT_POOL_ADDRESS_P (base)
5748 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
5751 static rtx tocrel_base, tocrel_offset;
5754 toc_relative_expr_p (rtx op)
5756 if (GET_CODE (op) != CONST)
5759 split_const (op, &tocrel_base, &tocrel_offset);
5760 return (GET_CODE (tocrel_base) == UNSPEC
5761 && XINT (tocrel_base, 1) == UNSPEC_TOCREL);
5765 legitimate_constant_pool_address_p (const_rtx x, bool strict)
5768 && (GET_CODE (x) == PLUS || GET_CODE (x) == LO_SUM)
5769 && GET_CODE (XEXP (x, 0)) == REG
5770 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5771 || ((TARGET_MINIMAL_TOC
5772 || TARGET_CMODEL != CMODEL_SMALL)
5773 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict)))
5774 && toc_relative_expr_p (XEXP (x, 1)));
5778 legitimate_small_data_p (enum machine_mode mode, rtx x)
5780 return (DEFAULT_ABI == ABI_V4
5781 && !flag_pic && !TARGET_TOC
5782 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
5783 && small_data_operand (x, mode));
5786 /* SPE offset addressing is limited to 5-bits worth of double words. */
5787 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
5790 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
5792 unsigned HOST_WIDE_INT offset, extra;
5794 if (GET_CODE (x) != PLUS)
5796 if (GET_CODE (XEXP (x, 0)) != REG)
5798 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5800 if (!reg_offset_addressing_ok_p (mode))
5801 return virtual_stack_registers_memory_p (x);
5802 if (legitimate_constant_pool_address_p (x, strict))
5804 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5807 offset = INTVAL (XEXP (x, 1));
5815 /* SPE vector modes. */
5816 return SPE_CONST_OFFSET_OK (offset);
5819 if (TARGET_E500_DOUBLE)
5820 return SPE_CONST_OFFSET_OK (offset);
5822 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
5824 if (VECTOR_MEM_VSX_P (DFmode))
5829 /* On e500v2, we may have:
5831 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
5833 Which gets addressed with evldd instructions. */
5834 if (TARGET_E500_DOUBLE)
5835 return SPE_CONST_OFFSET_OK (offset);
5837 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
5839 else if (offset & 3)
5844 if (TARGET_E500_DOUBLE)
5845 return (SPE_CONST_OFFSET_OK (offset)
5846 && SPE_CONST_OFFSET_OK (offset + 8));
5850 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
5852 else if (offset & 3)
5863 return (offset < 0x10000) && (offset + extra < 0x10000);
5867 legitimate_indexed_address_p (rtx x, int strict)
5871 if (GET_CODE (x) != PLUS)
5877 /* Recognize the rtl generated by reload which we know will later be
5878 replaced with proper base and index regs. */
5880 && reload_in_progress
5881 && (REG_P (op0) || GET_CODE (op0) == PLUS)
5885 return (REG_P (op0) && REG_P (op1)
5886 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
5887 && INT_REG_OK_FOR_INDEX_P (op1, strict))
5888 || (INT_REG_OK_FOR_BASE_P (op1, strict)
5889 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
5893 avoiding_indexed_address_p (enum machine_mode mode)
5895 /* Avoid indexed addressing for modes that have non-indexed
5896 load/store instruction forms. */
5897 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
5901 legitimate_indirect_address_p (rtx x, int strict)
5903 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
5907 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
5909 if (!TARGET_MACHO || !flag_pic
5910 || mode != SImode || GET_CODE (x) != MEM)
5914 if (GET_CODE (x) != LO_SUM)
5916 if (GET_CODE (XEXP (x, 0)) != REG)
5918 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
5922 return CONSTANT_P (x);
5926 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
5928 if (GET_CODE (x) != LO_SUM)
5930 if (GET_CODE (XEXP (x, 0)) != REG)
5932 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5934 /* Restrict addressing for DI because of our SUBREG hackery. */
5935 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5936 || mode == DDmode || mode == TDmode
5941 if (TARGET_ELF || TARGET_MACHO)
5943 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
5947 if (GET_MODE_NUNITS (mode) != 1)
5949 if (GET_MODE_BITSIZE (mode) > 64
5950 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
5951 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5952 && (mode == DFmode || mode == DDmode))))
5955 return CONSTANT_P (x);
5962 /* Try machine-dependent ways of modifying an illegitimate address
5963 to be legitimate. If we find one, return the new, valid address.
5964 This is used from only one place: `memory_address' in explow.c.
5966 OLDX is the address as it was before break_out_memory_refs was
5967 called. In some cases it is useful to look at this to decide what
5970 It is always safe for this function to do nothing. It exists to
5971 recognize opportunities to optimize the output.
5973 On RS/6000, first check for the sum of a register with a constant
5974 integer that is out of range. If so, generate code to add the
5975 constant with the low-order 16 bits masked to the register and force
5976 this result into another register (this can be done with `cau').
5977 Then generate an address of REG+(CONST&0xffff), allowing for the
5978 possibility of bit 16 being a one.
5980 Then check for the sum of a register and something not constant, try to
5981 load the other things into a register and return the sum. */
5984 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
5985 enum machine_mode mode)
5987 unsigned int extra = 0;
5989 if (!reg_offset_addressing_ok_p (mode))
5991 if (virtual_stack_registers_memory_p (x))
5994 /* In theory we should not be seeing addresses of the form reg+0,
5995 but just in case it is generated, optimize it away. */
5996 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
5997 return force_reg (Pmode, XEXP (x, 0));
5999 /* Make sure both operands are registers. */
6000 else if (GET_CODE (x) == PLUS)
6001 return gen_rtx_PLUS (Pmode,
6002 force_reg (Pmode, XEXP (x, 0)),
6003 force_reg (Pmode, XEXP (x, 1)));
6005 return force_reg (Pmode, x);
6007 if (GET_CODE (x) == SYMBOL_REF)
6009 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
6011 return rs6000_legitimize_tls_address (x, model);
6021 if (!TARGET_POWERPC64)
6029 extra = TARGET_POWERPC64 ? 8 : 12;
6035 if (GET_CODE (x) == PLUS
6036 && GET_CODE (XEXP (x, 0)) == REG
6037 && GET_CODE (XEXP (x, 1)) == CONST_INT
6038 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
6040 && !((TARGET_POWERPC64
6041 && (mode == DImode || mode == TImode)
6042 && (INTVAL (XEXP (x, 1)) & 3) != 0)
6043 || SPE_VECTOR_MODE (mode)
6044 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6045 || mode == DImode || mode == DDmode
6046 || mode == TDmode))))
6048 HOST_WIDE_INT high_int, low_int;
6050 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
6051 if (low_int >= 0x8000 - extra)
6053 high_int = INTVAL (XEXP (x, 1)) - low_int;
6054 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
6055 GEN_INT (high_int)), 0);
6056 return plus_constant (sum, low_int);
6058 else if (GET_CODE (x) == PLUS
6059 && GET_CODE (XEXP (x, 0)) == REG
6060 && GET_CODE (XEXP (x, 1)) != CONST_INT
6061 && GET_MODE_NUNITS (mode) == 1
6062 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6064 || ((mode != DImode && mode != DFmode && mode != DDmode)
6065 || (TARGET_E500_DOUBLE && mode != DDmode)))
6066 && (TARGET_POWERPC64 || mode != DImode)
6067 && !avoiding_indexed_address_p (mode)
6072 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
6073 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
6075 else if (SPE_VECTOR_MODE (mode)
6076 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6077 || mode == DDmode || mode == TDmode
6078 || mode == DImode)))
6082 /* We accept [reg + reg] and [reg + OFFSET]. */
6084 if (GET_CODE (x) == PLUS)
6086 rtx op1 = XEXP (x, 0);
6087 rtx op2 = XEXP (x, 1);
6090 op1 = force_reg (Pmode, op1);
6092 if (GET_CODE (op2) != REG
6093 && (GET_CODE (op2) != CONST_INT
6094 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
6095 || (GET_MODE_SIZE (mode) > 8
6096 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
6097 op2 = force_reg (Pmode, op2);
6099 /* We can't always do [reg + reg] for these, because [reg +
6100 reg + offset] is not a legitimate addressing mode. */
6101 y = gen_rtx_PLUS (Pmode, op1, op2);
6103 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
6104 return force_reg (Pmode, y);
6109 return force_reg (Pmode, x);
6115 && GET_CODE (x) != CONST_INT
6116 && GET_CODE (x) != CONST_DOUBLE
6118 && GET_MODE_NUNITS (mode) == 1
6119 && (GET_MODE_BITSIZE (mode) <= 32
6120 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6121 && (mode == DFmode || mode == DDmode))))
6123 rtx reg = gen_reg_rtx (Pmode);
6124 emit_insn (gen_elf_high (reg, x));
6125 return gen_rtx_LO_SUM (Pmode, reg, x);
6127 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
6130 && ! MACHO_DYNAMIC_NO_PIC_P
6132 && GET_CODE (x) != CONST_INT
6133 && GET_CODE (x) != CONST_DOUBLE
6135 && GET_MODE_NUNITS (mode) == 1
6136 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6137 || (mode != DFmode && mode != DDmode))
6141 rtx reg = gen_reg_rtx (Pmode);
6142 emit_insn (gen_macho_high (reg, x));
6143 return gen_rtx_LO_SUM (Pmode, reg, x);
6146 && GET_CODE (x) == SYMBOL_REF
6147 && constant_pool_expr_p (x)
6148 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
6150 rtx reg = TARGET_CMODEL != CMODEL_SMALL ? gen_reg_rtx (Pmode) : NULL_RTX;
6151 return create_TOC_reference (x, reg);
6157 /* Debug version of rs6000_legitimize_address. */
6159 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
6165 ret = rs6000_legitimize_address (x, oldx, mode);
6166 insns = get_insns ();
6172 "\nrs6000_legitimize_address: mode %s, old code %s, "
6173 "new code %s, modified\n",
6174 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
6175 GET_RTX_NAME (GET_CODE (ret)));
6177 fprintf (stderr, "Original address:\n");
6180 fprintf (stderr, "oldx:\n");
6183 fprintf (stderr, "New address:\n");
6188 fprintf (stderr, "Insns added:\n");
6189 debug_rtx_list (insns, 20);
6195 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
6196 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
6207 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
6208 We need to emit DTP-relative relocations. */
6211 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
6216 fputs ("\t.long\t", file);
6219 fputs (DOUBLE_INT_ASM_OP, file);
6224 output_addr_const (file, x);
6225 fputs ("@dtprel+0x8000", file);
6228 /* In the name of slightly smaller debug output, and to cater to
6229 general assembler lossage, recognize various UNSPEC sequences
6230 and turn them back into a direct symbol reference. */
6233 rs6000_delegitimize_address (rtx orig_x)
6237 orig_x = delegitimize_mem_from_attrs (orig_x);
6242 if (GET_CODE (x) == (TARGET_CMODEL != CMODEL_SMALL ? LO_SUM : PLUS)
6243 && GET_CODE (XEXP (x, 1)) == CONST)
6245 y = XEXP (XEXP (x, 1), 0);
6246 if (GET_CODE (y) == UNSPEC
6247 && XINT (y, 1) == UNSPEC_TOCREL
6248 && ((GET_CODE (XEXP (x, 0)) == REG
6249 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
6250 || TARGET_MINIMAL_TOC
6251 || TARGET_CMODEL != CMODEL_SMALL))
6252 || (TARGET_CMODEL != CMODEL_SMALL
6253 && GET_CODE (XEXP (x, 0)) == PLUS
6254 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6255 && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER
6256 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6257 && rtx_equal_p (XEXP (x, 1),
6258 XEXP (XEXP (XEXP (x, 0), 1), 0)))))
6260 y = XVECEXP (y, 0, 0);
6261 if (!MEM_P (orig_x))
6264 return replace_equiv_address_nv (orig_x, y);
6269 && GET_CODE (orig_x) == LO_SUM
6270 && GET_CODE (XEXP (x, 1)) == CONST)
6272 y = XEXP (XEXP (x, 1), 0);
6273 if (GET_CODE (y) == UNSPEC
6274 && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET)
6275 return XVECEXP (y, 0, 0);
6281 /* Construct the SYMBOL_REF for the tls_get_addr function. */
6283 static GTY(()) rtx rs6000_tls_symbol;
6285 rs6000_tls_get_addr (void)
6287 if (!rs6000_tls_symbol)
6288 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
6290 return rs6000_tls_symbol;
6293 /* Construct the SYMBOL_REF for TLS GOT references. */
6295 static GTY(()) rtx rs6000_got_symbol;
6297 rs6000_got_sym (void)
6299 if (!rs6000_got_symbol)
6301 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
6302 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
6303 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
6306 return rs6000_got_symbol;
6309 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
6310 this (thread-local) address. */
6313 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
6317 dest = gen_reg_rtx (Pmode);
6318 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
6324 tlsreg = gen_rtx_REG (Pmode, 13);
6325 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
6329 tlsreg = gen_rtx_REG (Pmode, 2);
6330 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
6334 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
6338 tmp = gen_reg_rtx (Pmode);
6341 tlsreg = gen_rtx_REG (Pmode, 13);
6342 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
6346 tlsreg = gen_rtx_REG (Pmode, 2);
6347 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
6351 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
6353 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
6358 rtx r3, got, tga, tmp1, tmp2, call_insn;
6360 /* We currently use relocations like @got@tlsgd for tls, which
6361 means the linker will handle allocation of tls entries, placing
6362 them in the .got section. So use a pointer to the .got section,
6363 not one to secondary TOC sections used by 64-bit -mminimal-toc,
6364 or to secondary GOT sections used by 32-bit -fPIC. */
6366 got = gen_rtx_REG (Pmode, 2);
6370 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
6373 rtx gsym = rs6000_got_sym ();
6374 got = gen_reg_rtx (Pmode);
6376 rs6000_emit_move (got, gsym, Pmode);
6381 tmp1 = gen_reg_rtx (Pmode);
6382 tmp2 = gen_reg_rtx (Pmode);
6383 mem = gen_const_mem (Pmode, tmp1);
6384 lab = gen_label_rtx ();
6385 emit_insn (gen_load_toc_v4_PIC_1b (gsym, lab));
6386 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
6387 emit_move_insn (tmp2, mem);
6388 last = emit_insn (gen_addsi3 (got, tmp1, tmp2));
6389 set_unique_reg_note (last, REG_EQUAL, gsym);
6394 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
6396 r3 = gen_rtx_REG (Pmode, 3);
6397 tga = rs6000_tls_get_addr ();
6398 emit_library_call_value (tga, dest, LCT_CONST, Pmode, 1, r3, Pmode);
6400 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6401 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
6402 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
6403 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
6404 else if (DEFAULT_ABI == ABI_V4)
6405 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
6408 call_insn = last_call_insn ();
6409 PATTERN (call_insn) = insn;
6410 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
6411 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
6412 pic_offset_table_rtx);
6414 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
6416 r3 = gen_rtx_REG (Pmode, 3);
6417 tga = rs6000_tls_get_addr ();
6418 tmp1 = gen_reg_rtx (Pmode);
6419 emit_library_call_value (tga, tmp1, LCT_CONST, Pmode, 1, r3, Pmode);
6421 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6422 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
6423 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
6424 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
6425 else if (DEFAULT_ABI == ABI_V4)
6426 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
6429 call_insn = last_call_insn ();
6430 PATTERN (call_insn) = insn;
6431 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
6432 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
6433 pic_offset_table_rtx);
6435 if (rs6000_tls_size == 16)
6438 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
6440 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
6442 else if (rs6000_tls_size == 32)
6444 tmp2 = gen_reg_rtx (Pmode);
6446 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
6448 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
6451 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
6453 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
6457 tmp2 = gen_reg_rtx (Pmode);
6459 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
6461 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
6463 insn = gen_rtx_SET (Pmode, dest,
6464 gen_rtx_PLUS (Pmode, tmp2, tmp1));
6470 /* IE, or 64-bit offset LE. */
6471 tmp2 = gen_reg_rtx (Pmode);
6473 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
6475 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
6478 insn = gen_tls_tls_64 (dest, tmp2, addr);
6480 insn = gen_tls_tls_32 (dest, tmp2, addr);
6488 /* Return 1 if X contains a thread-local symbol. */
6491 rs6000_tls_referenced_p (rtx x)
6493 if (! TARGET_HAVE_TLS)
6496 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
6499 /* Return 1 if *X is a thread-local symbol. This is the same as
6500 rs6000_tls_symbol_ref except for the type of the unused argument. */
6503 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
6505 return RS6000_SYMBOL_REF_TLS_P (*x);
6508 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
6509 replace the input X, or the original X if no replacement is called for.
6510 The output parameter *WIN is 1 if the calling macro should goto WIN,
6513 For RS/6000, we wish to handle large displacements off a base
6514 register by splitting the addend across an addiu/addis and the mem insn.
6515 This cuts number of extra insns needed from 3 to 1.
6517 On Darwin, we use this to generate code for floating point constants.
6518 A movsf_low is generated so we wind up with 2 instructions rather than 3.
6519 The Darwin code is inside #if TARGET_MACHO because only then are the
6520 machopic_* functions defined. */
6522 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
6523 int opnum, int type,
6524 int ind_levels ATTRIBUTE_UNUSED, int *win)
6526 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6528 /* We must recognize output that we have already generated ourselves. */
6529 if (GET_CODE (x) == PLUS
6530 && GET_CODE (XEXP (x, 0)) == PLUS
6531 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6532 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6533 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6535 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6536 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6537 opnum, (enum reload_type)type);
6542 /* Likewise for (lo_sum (high ...) ...) output we have generated. */
6543 if (GET_CODE (x) == LO_SUM
6544 && GET_CODE (XEXP (x, 0)) == HIGH)
6546 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6547 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6548 opnum, (enum reload_type)type);
6554 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
6555 && GET_CODE (x) == LO_SUM
6556 && GET_CODE (XEXP (x, 0)) == PLUS
6557 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
6558 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6559 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
6560 && machopic_operand_p (XEXP (x, 1)))
6562 /* Result of previous invocation of this function on Darwin
6563 floating point constant. */
6564 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6565 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6566 opnum, (enum reload_type)type);
6572 if (TARGET_CMODEL != CMODEL_SMALL
6573 && GET_CODE (x) == LO_SUM
6574 && GET_CODE (XEXP (x, 0)) == PLUS
6575 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6576 && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER
6577 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6578 && GET_CODE (XEXP (x, 1)) == CONST
6579 && GET_CODE (XEXP (XEXP (x, 1), 0)) == UNSPEC
6580 && XINT (XEXP (XEXP (x, 1), 0), 1) == UNSPEC_TOCREL
6581 && rtx_equal_p (XEXP (XEXP (XEXP (x, 0), 1), 0), XEXP (x, 1)))
6583 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6584 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6585 opnum, (enum reload_type) type);
6590 /* Force ld/std non-word aligned offset into base register by wrapping
6592 if (GET_CODE (x) == PLUS
6593 && GET_CODE (XEXP (x, 0)) == REG
6594 && REGNO (XEXP (x, 0)) < 32
6595 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6596 && GET_CODE (XEXP (x, 1)) == CONST_INT
6598 && (INTVAL (XEXP (x, 1)) & 3) != 0
6599 && VECTOR_MEM_NONE_P (mode)
6600 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
6601 && TARGET_POWERPC64)
6603 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
6604 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6605 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6606 opnum, (enum reload_type) type);
6611 if (GET_CODE (x) == PLUS
6612 && GET_CODE (XEXP (x, 0)) == REG
6613 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
6614 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6615 && GET_CODE (XEXP (x, 1)) == CONST_INT
6617 && !SPE_VECTOR_MODE (mode)
6618 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6619 || mode == DDmode || mode == TDmode
6621 && VECTOR_MEM_NONE_P (mode))
6623 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
6624 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
6626 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
6628 /* Check for 32-bit overflow. */
6629 if (high + low != val)
6635 /* Reload the high part into a base reg; leave the low part
6636 in the mem directly. */
6638 x = gen_rtx_PLUS (GET_MODE (x),
6639 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
6643 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6644 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6645 opnum, (enum reload_type)type);
6650 if (GET_CODE (x) == SYMBOL_REF
6652 && VECTOR_MEM_NONE_P (mode)
6653 && !SPE_VECTOR_MODE (mode)
6655 && DEFAULT_ABI == ABI_DARWIN
6656 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
6658 && DEFAULT_ABI == ABI_V4
6661 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
6662 The same goes for DImode without 64-bit gprs and DFmode and DDmode
6666 && (mode != DImode || TARGET_POWERPC64)
6667 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
6668 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
6673 rtx offset = machopic_gen_offset (x);
6674 x = gen_rtx_LO_SUM (GET_MODE (x),
6675 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
6676 gen_rtx_HIGH (Pmode, offset)), offset);
6680 x = gen_rtx_LO_SUM (GET_MODE (x),
6681 gen_rtx_HIGH (Pmode, x), x);
6683 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6684 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6685 opnum, (enum reload_type)type);
6690 /* Reload an offset address wrapped by an AND that represents the
6691 masking of the lower bits. Strip the outer AND and let reload
6692 convert the offset address into an indirect address. For VSX,
6693 force reload to create the address with an AND in a separate
6694 register, because we can't guarantee an altivec register will
6696 if (VECTOR_MEM_ALTIVEC_P (mode)
6697 && GET_CODE (x) == AND
6698 && GET_CODE (XEXP (x, 0)) == PLUS
6699 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6700 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6701 && GET_CODE (XEXP (x, 1)) == CONST_INT
6702 && INTVAL (XEXP (x, 1)) == -16)
6711 && GET_CODE (x) == SYMBOL_REF
6712 && constant_pool_expr_p (x)
6713 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
6715 x = create_TOC_reference (x, NULL_RTX);
6716 if (TARGET_CMODEL != CMODEL_SMALL)
6717 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6718 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6719 opnum, (enum reload_type) type);
6727 /* Debug version of rs6000_legitimize_reload_address. */
6729 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
6730 int opnum, int type,
6731 int ind_levels, int *win)
6733 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
6736 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
6737 "type = %d, ind_levels = %d, win = %d, original addr:\n",
6738 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
6742 fprintf (stderr, "Same address returned\n");
6744 fprintf (stderr, "NULL returned\n");
6747 fprintf (stderr, "New address:\n");
6754 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
6755 that is a valid memory address for an instruction.
6756 The MODE argument is the machine mode for the MEM expression
6757 that wants to use this address.
6759 On the RS/6000, there are four valid address: a SYMBOL_REF that
6760 refers to a constant pool entry of an address (or the sum of it
6761 plus a constant), a short (16-bit signed) constant plus a register,
6762 the sum of two registers, or a register indirect, possibly with an
6763 auto-increment. For DFmode, DDmode and DImode with a constant plus
6764 register, we must ensure that both words are addressable or PowerPC64
6765 with offset word aligned.
6767 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
6768 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
6769 because adjacent memory cells are accessed by adding word-sized offsets
6770 during assembly output. */
6772 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
6774 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6776 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
6777 if (VECTOR_MEM_ALTIVEC_P (mode)
6778 && GET_CODE (x) == AND
6779 && GET_CODE (XEXP (x, 1)) == CONST_INT
6780 && INTVAL (XEXP (x, 1)) == -16)
6783 if (RS6000_SYMBOL_REF_TLS_P (x))
6785 if (legitimate_indirect_address_p (x, reg_ok_strict))
6787 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
6788 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6789 && !SPE_VECTOR_MODE (mode)
6792 /* Restrict addressing for DI because of our SUBREG hackery. */
6793 && !(TARGET_E500_DOUBLE
6794 && (mode == DFmode || mode == DDmode || mode == DImode))
6796 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
6798 if (virtual_stack_registers_memory_p (x))
6800 if (reg_offset_p && legitimate_small_data_p (mode, x))
6802 if (reg_offset_p && legitimate_constant_pool_address_p (x, reg_ok_strict))
6804 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
6807 && GET_CODE (x) == PLUS
6808 && GET_CODE (XEXP (x, 0)) == REG
6809 && (XEXP (x, 0) == virtual_stack_vars_rtx
6810 || XEXP (x, 0) == arg_pointer_rtx)
6811 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6813 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
6818 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6820 || (mode != DFmode && mode != DDmode)
6821 || (TARGET_E500_DOUBLE && mode != DDmode))
6822 && (TARGET_POWERPC64 || mode != DImode)
6823 && !avoiding_indexed_address_p (mode)
6824 && legitimate_indexed_address_p (x, reg_ok_strict))
6826 if (GET_CODE (x) == PRE_MODIFY
6830 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6832 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
6833 && (TARGET_POWERPC64 || mode != DImode)
6834 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6835 && !SPE_VECTOR_MODE (mode)
6836 /* Restrict addressing for DI because of our SUBREG hackery. */
6837 && !(TARGET_E500_DOUBLE
6838 && (mode == DFmode || mode == DDmode || mode == DImode))
6840 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
6841 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
6842 || (!avoiding_indexed_address_p (mode)
6843 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
6844 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
6846 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
6851 /* Debug version of rs6000_legitimate_address_p. */
6853 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
6856 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
6858 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
6859 "strict = %d, code = %s\n",
6860 ret ? "true" : "false",
6861 GET_MODE_NAME (mode),
6863 GET_RTX_NAME (GET_CODE (x)));
6869 /* Implement TARGET_MODE_DEPENDENT_ADDRESS_P. */
6872 rs6000_mode_dependent_address_p (const_rtx addr)
6874 return rs6000_mode_dependent_address_ptr (addr);
6877 /* Go to LABEL if ADDR (a legitimate address expression)
6878 has an effect that depends on the machine mode it is used for.
6880 On the RS/6000 this is true of all integral offsets (since AltiVec
6881 and VSX modes don't allow them) or is a pre-increment or decrement.
6883 ??? Except that due to conceptual problems in offsettable_address_p
6884 we can't really report the problems of integral offsets. So leave
6885 this assuming that the adjustable offset must be valid for the
6886 sub-words of a TFmode operand, which is what we had before. */
6889 rs6000_mode_dependent_address (const_rtx addr)
6891 switch (GET_CODE (addr))
6894 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
6895 is considered a legitimate address before reload, so there
6896 are no offset restrictions in that case. Note that this
6897 condition is safe in strict mode because any address involving
6898 virtual_stack_vars_rtx or arg_pointer_rtx would already have
6899 been rejected as illegitimate. */
6900 if (XEXP (addr, 0) != virtual_stack_vars_rtx
6901 && XEXP (addr, 0) != arg_pointer_rtx
6902 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
6904 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
6905 return val + 12 + 0x8000 >= 0x10000;
6910 /* Anything in the constant pool is sufficiently aligned that
6911 all bytes have the same high part address. */
6912 return !legitimate_constant_pool_address_p (addr, false);
6914 /* Auto-increment cases are now treated generically in recog.c. */
6916 return TARGET_UPDATE;
6918 /* AND is only allowed in Altivec loads. */
6929 /* Debug version of rs6000_mode_dependent_address. */
6931 rs6000_debug_mode_dependent_address (const_rtx addr)
6933 bool ret = rs6000_mode_dependent_address (addr);
6935 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
6936 ret ? "true" : "false");
6942 /* Implement FIND_BASE_TERM. */
6945 rs6000_find_base_term (rtx op)
6949 split_const (op, &base, &offset);
6950 if (GET_CODE (base) == UNSPEC)
6951 switch (XINT (base, 1))
6954 case UNSPEC_MACHOPIC_OFFSET:
6955 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
6956 for aliasing purposes. */
6957 return XVECEXP (base, 0, 0);
6963 /* More elaborate version of recog's offsettable_memref_p predicate
6964 that works around the ??? note of rs6000_mode_dependent_address.
6965 In particular it accepts
6967 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
6969 in 32-bit mode, that the recog predicate rejects. */
6972 rs6000_offsettable_memref_p (rtx op)
6977 /* First mimic offsettable_memref_p. */
6978 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
6981 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
6982 the latter predicate knows nothing about the mode of the memory
6983 reference and, therefore, assumes that it is the largest supported
6984 mode (TFmode). As a consequence, legitimate offsettable memory
6985 references are rejected. rs6000_legitimate_offset_address_p contains
6986 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
6987 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
6990 /* Change register usage conditional on target flags. */
6992 rs6000_conditional_register_usage (void)
6996 if (TARGET_DEBUG_TARGET)
6997 fprintf (stderr, "rs6000_conditional_register_usage called\n");
6999 /* Set MQ register fixed (already call_used) if not POWER
7000 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
7005 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
7007 fixed_regs[13] = call_used_regs[13]
7008 = call_really_used_regs[13] = 1;
7010 /* Conditionally disable FPRs. */
7011 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
7012 for (i = 32; i < 64; i++)
7013 fixed_regs[i] = call_used_regs[i]
7014 = call_really_used_regs[i] = 1;
7016 /* The TOC register is not killed across calls in a way that is
7017 visible to the compiler. */
7018 if (DEFAULT_ABI == ABI_AIX)
7019 call_really_used_regs[2] = 0;
7021 if (DEFAULT_ABI == ABI_V4
7022 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
7024 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
7026 if (DEFAULT_ABI == ABI_V4
7027 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
7029 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7030 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7031 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
7033 if (DEFAULT_ABI == ABI_DARWIN
7034 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
7035 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7036 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7037 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
7039 if (TARGET_TOC && TARGET_MINIMAL_TOC)
7040 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7041 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
7045 global_regs[SPEFSCR_REGNO] = 1;
7046 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
7047 registers in prologues and epilogues. We no longer use r14
7048 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
7049 pool for link-compatibility with older versions of GCC. Once
7050 "old" code has died out, we can return r14 to the allocation
7053 = call_used_regs[14]
7054 = call_really_used_regs[14] = 1;
7057 if (!TARGET_ALTIVEC && !TARGET_VSX)
7059 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
7060 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
7061 call_really_used_regs[VRSAVE_REGNO] = 1;
7064 if (TARGET_ALTIVEC || TARGET_VSX)
7065 global_regs[VSCR_REGNO] = 1;
7067 if (TARGET_ALTIVEC_ABI)
7069 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
7070 call_used_regs[i] = call_really_used_regs[i] = 1;
7072 /* AIX reserves VR20:31 in non-extended ABI mode. */
7074 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
7075 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
7079 /* Try to output insns to set TARGET equal to the constant C if it can
7080 be done in less than N insns. Do all computations in MODE.
7081 Returns the place where the output has been placed if it can be
7082 done and the insns have been emitted. If it would take more than N
7083 insns, zero is returned and no insns and emitted. */
7086 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
7087 rtx source, int n ATTRIBUTE_UNUSED)
7089 rtx result, insn, set;
7090 HOST_WIDE_INT c0, c1;
7097 dest = gen_reg_rtx (mode);
7098 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
7102 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
7104 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
7105 GEN_INT (INTVAL (source)
7106 & (~ (HOST_WIDE_INT) 0xffff))));
7107 emit_insn (gen_rtx_SET (VOIDmode, dest,
7108 gen_rtx_IOR (SImode, copy_rtx (result),
7109 GEN_INT (INTVAL (source) & 0xffff))));
7114 switch (GET_CODE (source))
7117 c0 = INTVAL (source);
7122 #if HOST_BITS_PER_WIDE_INT >= 64
7123 c0 = CONST_DOUBLE_LOW (source);
7126 c0 = CONST_DOUBLE_LOW (source);
7127 c1 = CONST_DOUBLE_HIGH (source);
7135 result = rs6000_emit_set_long_const (dest, c0, c1);
7142 insn = get_last_insn ();
7143 set = single_set (insn);
7144 if (! CONSTANT_P (SET_SRC (set)))
7145 set_unique_reg_note (insn, REG_EQUAL, source);
7150 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
7151 fall back to a straight forward decomposition. We do this to avoid
7152 exponential run times encountered when looking for longer sequences
7153 with rs6000_emit_set_const. */
7155 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
7157 if (!TARGET_POWERPC64)
7159 rtx operand1, operand2;
7161 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
7163 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
7165 emit_move_insn (operand1, GEN_INT (c1));
7166 emit_move_insn (operand2, GEN_INT (c2));
7170 HOST_WIDE_INT ud1, ud2, ud3, ud4;
7173 ud2 = (c1 & 0xffff0000) >> 16;
7174 #if HOST_BITS_PER_WIDE_INT >= 64
7178 ud4 = (c2 & 0xffff0000) >> 16;
7180 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
7181 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
7184 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
7186 emit_move_insn (dest, GEN_INT (ud1));
7189 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
7190 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
7193 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
7196 emit_move_insn (dest, GEN_INT (ud2 << 16));
7198 emit_move_insn (copy_rtx (dest),
7199 gen_rtx_IOR (DImode, copy_rtx (dest),
7202 else if (ud3 == 0 && ud4 == 0)
7204 gcc_assert (ud2 & 0x8000);
7205 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
7208 emit_move_insn (copy_rtx (dest),
7209 gen_rtx_IOR (DImode, copy_rtx (dest),
7211 emit_move_insn (copy_rtx (dest),
7212 gen_rtx_ZERO_EXTEND (DImode,
7213 gen_lowpart (SImode,
7216 else if ((ud4 == 0xffff && (ud3 & 0x8000))
7217 || (ud4 == 0 && ! (ud3 & 0x8000)))
7220 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
7223 emit_move_insn (dest, GEN_INT (ud3 << 16));
7226 emit_move_insn (copy_rtx (dest),
7227 gen_rtx_IOR (DImode, copy_rtx (dest),
7229 emit_move_insn (copy_rtx (dest),
7230 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
7233 emit_move_insn (copy_rtx (dest),
7234 gen_rtx_IOR (DImode, copy_rtx (dest),
7240 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
7243 emit_move_insn (dest, GEN_INT (ud4 << 16));
7246 emit_move_insn (copy_rtx (dest),
7247 gen_rtx_IOR (DImode, copy_rtx (dest),
7250 emit_move_insn (copy_rtx (dest),
7251 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
7254 emit_move_insn (copy_rtx (dest),
7255 gen_rtx_IOR (DImode, copy_rtx (dest),
7256 GEN_INT (ud2 << 16)));
7258 emit_move_insn (copy_rtx (dest),
7259 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
7265 /* Helper for the following. Get rid of [r+r] memory refs
7266 in cases where it won't work (TImode, TFmode, TDmode). */
7269 rs6000_eliminate_indexed_memrefs (rtx operands[2])
7271 if (reload_in_progress)
7274 if (GET_CODE (operands[0]) == MEM
7275 && GET_CODE (XEXP (operands[0], 0)) != REG
7276 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0), false))
7278 = replace_equiv_address (operands[0],
7279 copy_addr_to_reg (XEXP (operands[0], 0)));
7281 if (GET_CODE (operands[1]) == MEM
7282 && GET_CODE (XEXP (operands[1], 0)) != REG
7283 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0), false))
7285 = replace_equiv_address (operands[1],
7286 copy_addr_to_reg (XEXP (operands[1], 0)));
7289 /* Return true if memory accesses to DECL are known to never straddle
7293 offsettable_ok_by_alignment (tree decl)
7295 unsigned HOST_WIDE_INT dsize, dalign;
7297 /* Presume any compiler generated symbol_ref is suitably aligned. */
7301 if (TREE_CODE (decl) != VAR_DECL
7302 && TREE_CODE (decl) != PARM_DECL
7303 && TREE_CODE (decl) != RESULT_DECL
7304 && TREE_CODE (decl) != FIELD_DECL)
7307 if (!DECL_SIZE_UNIT (decl))
7310 if (!host_integerp (DECL_SIZE_UNIT (decl), 1))
7313 dsize = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
7319 dalign = DECL_ALIGN_UNIT (decl);
7320 return dalign >= dsize;
7323 /* Emit a move from SOURCE to DEST in mode MODE. */
7325 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
7329 operands[1] = source;
7331 if (TARGET_DEBUG_ADDR)
7334 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
7335 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
7336 GET_MODE_NAME (mode),
7339 can_create_pseudo_p ());
7341 fprintf (stderr, "source:\n");
7345 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
7346 if (GET_CODE (operands[1]) == CONST_DOUBLE
7347 && ! FLOAT_MODE_P (mode)
7348 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
7350 /* FIXME. This should never happen. */
7351 /* Since it seems that it does, do the safe thing and convert
7353 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
7355 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
7356 || FLOAT_MODE_P (mode)
7357 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
7358 || CONST_DOUBLE_LOW (operands[1]) < 0)
7359 && (CONST_DOUBLE_HIGH (operands[1]) != -1
7360 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
7362 /* Check if GCC is setting up a block move that will end up using FP
7363 registers as temporaries. We must make sure this is acceptable. */
7364 if (GET_CODE (operands[0]) == MEM
7365 && GET_CODE (operands[1]) == MEM
7367 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
7368 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
7369 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
7370 ? 32 : MEM_ALIGN (operands[0])))
7371 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
7373 : MEM_ALIGN (operands[1]))))
7374 && ! MEM_VOLATILE_P (operands [0])
7375 && ! MEM_VOLATILE_P (operands [1]))
7377 emit_move_insn (adjust_address (operands[0], SImode, 0),
7378 adjust_address (operands[1], SImode, 0));
7379 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
7380 adjust_address (copy_rtx (operands[1]), SImode, 4));
7384 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
7385 && !gpc_reg_operand (operands[1], mode))
7386 operands[1] = force_reg (mode, operands[1]);
7388 if (mode == SFmode && ! TARGET_POWERPC
7389 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7390 && GET_CODE (operands[0]) == MEM)
7394 if (reload_in_progress || reload_completed)
7395 regnum = true_regnum (operands[1]);
7396 else if (GET_CODE (operands[1]) == REG)
7397 regnum = REGNO (operands[1]);
7401 /* If operands[1] is a register, on POWER it may have
7402 double-precision data in it, so truncate it to single
7404 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
7407 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
7408 : gen_reg_rtx (mode));
7409 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
7410 operands[1] = newreg;
7414 /* Recognize the case where operand[1] is a reference to thread-local
7415 data and load its address to a register. */
7416 if (rs6000_tls_referenced_p (operands[1]))
7418 enum tls_model model;
7419 rtx tmp = operands[1];
7422 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
7424 addend = XEXP (XEXP (tmp, 0), 1);
7425 tmp = XEXP (XEXP (tmp, 0), 0);
7428 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
7429 model = SYMBOL_REF_TLS_MODEL (tmp);
7430 gcc_assert (model != 0);
7432 tmp = rs6000_legitimize_tls_address (tmp, model);
7435 tmp = gen_rtx_PLUS (mode, tmp, addend);
7436 tmp = force_operand (tmp, operands[0]);
7441 /* Handle the case where reload calls us with an invalid address. */
7442 if (reload_in_progress && mode == Pmode
7443 && (! general_operand (operands[1], mode)
7444 || ! nonimmediate_operand (operands[0], mode)))
7447 /* 128-bit constant floating-point values on Darwin should really be
7448 loaded as two parts. */
7449 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
7450 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
7452 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
7453 know how to get a DFmode SUBREG of a TFmode. */
7454 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
7455 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
7456 simplify_gen_subreg (imode, operands[1], mode, 0),
7458 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
7459 GET_MODE_SIZE (imode)),
7460 simplify_gen_subreg (imode, operands[1], mode,
7461 GET_MODE_SIZE (imode)),
7466 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
7467 cfun->machine->sdmode_stack_slot =
7468 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
7470 if (reload_in_progress
7472 && MEM_P (operands[0])
7473 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
7474 && REG_P (operands[1]))
7476 if (FP_REGNO_P (REGNO (operands[1])))
7478 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
7479 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7480 emit_insn (gen_movsd_store (mem, operands[1]));
7482 else if (INT_REGNO_P (REGNO (operands[1])))
7484 rtx mem = adjust_address_nv (operands[0], mode, 4);
7485 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7486 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
7492 if (reload_in_progress
7494 && REG_P (operands[0])
7495 && MEM_P (operands[1])
7496 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
7498 if (FP_REGNO_P (REGNO (operands[0])))
7500 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
7501 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7502 emit_insn (gen_movsd_load (operands[0], mem));
7504 else if (INT_REGNO_P (REGNO (operands[0])))
7506 rtx mem = adjust_address_nv (operands[1], mode, 4);
7507 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7508 emit_insn (gen_movsd_hardfloat (operands[0], mem));
7515 /* FIXME: In the long term, this switch statement should go away
7516 and be replaced by a sequence of tests based on things like
7522 if (CONSTANT_P (operands[1])
7523 && GET_CODE (operands[1]) != CONST_INT)
7524 operands[1] = force_const_mem (mode, operands[1]);
7529 rs6000_eliminate_indexed_memrefs (operands);
7536 if (CONSTANT_P (operands[1])
7537 && ! easy_fp_constant (operands[1], mode))
7538 operands[1] = force_const_mem (mode, operands[1]);
7551 if (CONSTANT_P (operands[1])
7552 && !easy_vector_constant (operands[1], mode))
7553 operands[1] = force_const_mem (mode, operands[1]);
7558 /* Use default pattern for address of ELF small data */
7561 && DEFAULT_ABI == ABI_V4
7562 && (GET_CODE (operands[1]) == SYMBOL_REF
7563 || GET_CODE (operands[1]) == CONST)
7564 && small_data_operand (operands[1], mode))
7566 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7570 if (DEFAULT_ABI == ABI_V4
7571 && mode == Pmode && mode == SImode
7572 && flag_pic == 1 && got_operand (operands[1], mode))
7574 emit_insn (gen_movsi_got (operands[0], operands[1]));
7578 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
7582 && CONSTANT_P (operands[1])
7583 && GET_CODE (operands[1]) != HIGH
7584 && GET_CODE (operands[1]) != CONST_INT)
7586 rtx target = (!can_create_pseudo_p ()
7588 : gen_reg_rtx (mode));
7590 /* If this is a function address on -mcall-aixdesc,
7591 convert it to the address of the descriptor. */
7592 if (DEFAULT_ABI == ABI_AIX
7593 && GET_CODE (operands[1]) == SYMBOL_REF
7594 && XSTR (operands[1], 0)[0] == '.')
7596 const char *name = XSTR (operands[1], 0);
7598 while (*name == '.')
7600 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
7601 CONSTANT_POOL_ADDRESS_P (new_ref)
7602 = CONSTANT_POOL_ADDRESS_P (operands[1]);
7603 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
7604 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
7605 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
7606 operands[1] = new_ref;
7609 if (DEFAULT_ABI == ABI_DARWIN)
7612 if (MACHO_DYNAMIC_NO_PIC_P)
7614 /* Take care of any required data indirection. */
7615 operands[1] = rs6000_machopic_legitimize_pic_address (
7616 operands[1], mode, operands[0]);
7617 if (operands[0] != operands[1])
7618 emit_insn (gen_rtx_SET (VOIDmode,
7619 operands[0], operands[1]));
7623 emit_insn (gen_macho_high (target, operands[1]));
7624 emit_insn (gen_macho_low (operands[0], target, operands[1]));
7628 emit_insn (gen_elf_high (target, operands[1]));
7629 emit_insn (gen_elf_low (operands[0], target, operands[1]));
7633 /* If this is a SYMBOL_REF that refers to a constant pool entry,
7634 and we have put it in the TOC, we just need to make a TOC-relative
7637 && GET_CODE (operands[1]) == SYMBOL_REF
7638 && constant_pool_expr_p (operands[1])
7639 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
7640 get_pool_mode (operands[1])))
7641 || (TARGET_CMODEL == CMODEL_MEDIUM
7642 && GET_CODE (operands[1]) == SYMBOL_REF
7643 && !CONSTANT_POOL_ADDRESS_P (operands[1])
7644 && SYMBOL_REF_LOCAL_P (operands[1])
7645 && offsettable_ok_by_alignment (SYMBOL_REF_DECL (operands[1]))))
7648 if (TARGET_CMODEL != CMODEL_SMALL)
7650 if (can_create_pseudo_p ())
7651 reg = gen_reg_rtx (Pmode);
7655 operands[1] = create_TOC_reference (operands[1], reg);
7657 else if (mode == Pmode
7658 && CONSTANT_P (operands[1])
7659 && ((GET_CODE (operands[1]) != CONST_INT
7660 && ! easy_fp_constant (operands[1], mode))
7661 || (GET_CODE (operands[1]) == CONST_INT
7662 && (num_insns_constant (operands[1], mode)
7663 > (TARGET_CMODEL != CMODEL_SMALL ? 3 : 2)))
7664 || (GET_CODE (operands[0]) == REG
7665 && FP_REGNO_P (REGNO (operands[0]))))
7666 && GET_CODE (operands[1]) != HIGH
7667 && ! legitimate_constant_pool_address_p (operands[1], false)
7668 && ! toc_relative_expr_p (operands[1])
7669 && (TARGET_CMODEL == CMODEL_SMALL
7670 || can_create_pseudo_p ()
7671 || (REG_P (operands[0])
7672 && INT_REG_OK_FOR_BASE_P (operands[0], true))))
7676 /* Darwin uses a special PIC legitimizer. */
7677 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
7680 rs6000_machopic_legitimize_pic_address (operands[1], mode,
7682 if (operands[0] != operands[1])
7683 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7688 /* If we are to limit the number of things we put in the TOC and
7689 this is a symbol plus a constant we can add in one insn,
7690 just put the symbol in the TOC and add the constant. Don't do
7691 this if reload is in progress. */
7692 if (GET_CODE (operands[1]) == CONST
7693 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
7694 && GET_CODE (XEXP (operands[1], 0)) == PLUS
7695 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
7696 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
7697 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
7698 && ! side_effects_p (operands[0]))
7701 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
7702 rtx other = XEXP (XEXP (operands[1], 0), 1);
7704 sym = force_reg (mode, sym);
7705 emit_insn (gen_add3_insn (operands[0], sym, other));
7709 operands[1] = force_const_mem (mode, operands[1]);
7712 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7713 && constant_pool_expr_p (XEXP (operands[1], 0))
7714 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
7715 get_pool_constant (XEXP (operands[1], 0)),
7716 get_pool_mode (XEXP (operands[1], 0))))
7720 if (TARGET_CMODEL != CMODEL_SMALL)
7722 if (can_create_pseudo_p ())
7723 reg = gen_reg_rtx (Pmode);
7727 tocref = create_TOC_reference (XEXP (operands[1], 0), reg);
7728 operands[1] = gen_const_mem (mode, tocref);
7729 set_mem_alias_set (operands[1], get_TOC_alias_set ());
7735 rs6000_eliminate_indexed_memrefs (operands);
7739 emit_insn (gen_rtx_PARALLEL (VOIDmode,
7741 gen_rtx_SET (VOIDmode,
7742 operands[0], operands[1]),
7743 gen_rtx_CLOBBER (VOIDmode,
7744 gen_rtx_SCRATCH (SImode)))));
7750 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
7753 /* Above, we may have called force_const_mem which may have returned
7754 an invalid address. If we can, fix this up; otherwise, reload will
7755 have to deal with it. */
7756 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
7757 operands[1] = validize_mem (operands[1]);
7760 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7763 /* Nonzero if we can use a floating-point register to pass this arg. */
7764 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
7765 (SCALAR_FLOAT_MODE_P (MODE) \
7766 && (CUM)->fregno <= FP_ARG_MAX_REG \
7767 && TARGET_HARD_FLOAT && TARGET_FPRS)
7769 /* Nonzero if we can use an AltiVec register to pass this arg. */
7770 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
7771 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
7772 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
7773 && TARGET_ALTIVEC_ABI \
7776 /* Return a nonzero value to say to return the function value in
7777 memory, just as large structures are always returned. TYPE will be
7778 the data type of the value, and FNTYPE will be the type of the
7779 function doing the returning, or @code{NULL} for libcalls.
7781 The AIX ABI for the RS/6000 specifies that all structures are
7782 returned in memory. The Darwin ABI does the same.
7784 For the Darwin 64 Bit ABI, a function result can be returned in
7785 registers or in memory, depending on the size of the return data
7786 type. If it is returned in registers, the value occupies the same
7787 registers as it would if it were the first and only function
7788 argument. Otherwise, the function places its result in memory at
7789 the location pointed to by GPR3.
7791 The SVR4 ABI specifies that structures <= 8 bytes are returned in r3/r4,
7792 but a draft put them in memory, and GCC used to implement the draft
7793 instead of the final standard. Therefore, aix_struct_return
7794 controls this instead of DEFAULT_ABI; V.4 targets needing backward
7795 compatibility can change DRAFT_V4_STRUCT_RET to override the
7796 default, and -m switches get the final word. See
7797 rs6000_option_override_internal for more details.
7799 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
7800 long double support is enabled. These values are returned in memory.
7802 int_size_in_bytes returns -1 for variable size objects, which go in
7803 memory always. The cast to unsigned makes -1 > 8. */
7806 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
7808 /* For the Darwin64 ABI, test if we can fit the return value in regs. */
7810 && rs6000_darwin64_abi
7811 && TREE_CODE (type) == RECORD_TYPE
7812 && int_size_in_bytes (type) > 0)
7814 CUMULATIVE_ARGS valcum;
7818 valcum.fregno = FP_ARG_MIN_REG;
7819 valcum.vregno = ALTIVEC_ARG_MIN_REG;
7820 /* Do a trial code generation as if this were going to be passed
7821 as an argument; if any part goes in memory, we return NULL. */
7822 valret = rs6000_darwin64_record_arg (&valcum, type, true, true);
7825 /* Otherwise fall through to more conventional ABI rules. */
7828 if (AGGREGATE_TYPE_P (type)
7829 && (aix_struct_return
7830 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
7833 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7834 modes only exist for GCC vector types if -maltivec. */
7835 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
7836 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
7839 /* Return synthetic vectors in memory. */
7840 if (TREE_CODE (type) == VECTOR_TYPE
7841 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
7843 static bool warned_for_return_big_vectors = false;
7844 if (!warned_for_return_big_vectors)
7846 warning (0, "GCC vector returned by reference: "
7847 "non-standard ABI extension with no compatibility guarantee");
7848 warned_for_return_big_vectors = true;
7853 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
7859 #ifdef HAVE_AS_GNU_ATTRIBUTE
7860 /* Return TRUE if a call to function FNDECL may be one that
7861 potentially affects the function calling ABI of the object file. */
7864 call_ABI_of_interest (tree fndecl)
7866 if (cgraph_state == CGRAPH_STATE_EXPANSION)
7868 struct cgraph_node *c_node;
7870 /* Libcalls are always interesting. */
7871 if (fndecl == NULL_TREE)
7874 /* Any call to an external function is interesting. */
7875 if (DECL_EXTERNAL (fndecl))
7878 /* Interesting functions that we are emitting in this object file. */
7879 c_node = cgraph_node (fndecl);
7880 return !cgraph_only_called_directly_p (c_node);
7886 /* Initialize a variable CUM of type CUMULATIVE_ARGS
7887 for a call to a function whose data type is FNTYPE.
7888 For a library call, FNTYPE is 0 and RETURN_MODE the return value mode.
7890 For incoming args we set the number of arguments in the prototype large
7891 so we never return a PARALLEL. */
7894 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
7895 rtx libname ATTRIBUTE_UNUSED, int incoming,
7896 int libcall, int n_named_args,
7897 tree fndecl ATTRIBUTE_UNUSED,
7898 enum machine_mode return_mode ATTRIBUTE_UNUSED)
7900 static CUMULATIVE_ARGS zero_cumulative;
7902 *cum = zero_cumulative;
7904 cum->fregno = FP_ARG_MIN_REG;
7905 cum->vregno = ALTIVEC_ARG_MIN_REG;
7906 cum->prototype = (fntype && prototype_p (fntype));
7907 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
7908 ? CALL_LIBCALL : CALL_NORMAL);
7909 cum->sysv_gregno = GP_ARG_MIN_REG;
7910 cum->stdarg = stdarg_p (fntype);
7912 cum->nargs_prototype = 0;
7913 if (incoming || cum->prototype)
7914 cum->nargs_prototype = n_named_args;
7916 /* Check for a longcall attribute. */
7917 if ((!fntype && rs6000_default_long_calls)
7919 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
7920 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
7921 cum->call_cookie |= CALL_LONG;
7923 if (TARGET_DEBUG_ARG)
7925 fprintf (stderr, "\ninit_cumulative_args:");
7928 tree ret_type = TREE_TYPE (fntype);
7929 fprintf (stderr, " ret code = %s,",
7930 tree_code_name[ (int)TREE_CODE (ret_type) ]);
7933 if (cum->call_cookie & CALL_LONG)
7934 fprintf (stderr, " longcall,");
7936 fprintf (stderr, " proto = %d, nargs = %d\n",
7937 cum->prototype, cum->nargs_prototype);
7940 #ifdef HAVE_AS_GNU_ATTRIBUTE
7941 if (DEFAULT_ABI == ABI_V4)
7943 cum->escapes = call_ABI_of_interest (fndecl);
7950 return_type = TREE_TYPE (fntype);
7951 return_mode = TYPE_MODE (return_type);
7954 return_type = lang_hooks.types.type_for_mode (return_mode, 0);
7956 if (return_type != NULL)
7958 if (TREE_CODE (return_type) == RECORD_TYPE
7959 && TYPE_TRANSPARENT_AGGR (return_type))
7961 return_type = TREE_TYPE (first_field (return_type));
7962 return_mode = TYPE_MODE (return_type);
7964 if (AGGREGATE_TYPE_P (return_type)
7965 && ((unsigned HOST_WIDE_INT) int_size_in_bytes (return_type)
7967 rs6000_returns_struct = true;
7969 if (SCALAR_FLOAT_MODE_P (return_mode))
7970 rs6000_passes_float = true;
7971 else if (ALTIVEC_VECTOR_MODE (return_mode)
7972 || VSX_VECTOR_MODE (return_mode)
7973 || SPE_VECTOR_MODE (return_mode))
7974 rs6000_passes_vector = true;
7981 && TARGET_ALTIVEC_ABI
7982 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
7984 error ("cannot return value in vector register because"
7985 " altivec instructions are disabled, use -maltivec"
7990 /* Return true if TYPE must be passed on the stack and not in registers. */
7993 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
7995 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
7996 return must_pass_in_stack_var_size (mode, type);
7998 return must_pass_in_stack_var_size_or_pad (mode, type);
8001 /* If defined, a C expression which determines whether, and in which
8002 direction, to pad out an argument with extra space. The value
8003 should be of type `enum direction': either `upward' to pad above
8004 the argument, `downward' to pad below, or `none' to inhibit
8007 For the AIX ABI structs are always stored left shifted in their
8011 function_arg_padding (enum machine_mode mode, const_tree type)
8013 #ifndef AGGREGATE_PADDING_FIXED
8014 #define AGGREGATE_PADDING_FIXED 0
8016 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
8017 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
8020 if (!AGGREGATE_PADDING_FIXED)
8022 /* GCC used to pass structures of the same size as integer types as
8023 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
8024 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
8025 passed padded downward, except that -mstrict-align further
8026 muddied the water in that multi-component structures of 2 and 4
8027 bytes in size were passed padded upward.
8029 The following arranges for best compatibility with previous
8030 versions of gcc, but removes the -mstrict-align dependency. */
8031 if (BYTES_BIG_ENDIAN)
8033 HOST_WIDE_INT size = 0;
8035 if (mode == BLKmode)
8037 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
8038 size = int_size_in_bytes (type);
8041 size = GET_MODE_SIZE (mode);
8043 if (size == 1 || size == 2 || size == 4)
8049 if (AGGREGATES_PAD_UPWARD_ALWAYS)
8051 if (type != 0 && AGGREGATE_TYPE_P (type))
8055 /* Fall back to the default. */
8056 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
8059 /* If defined, a C expression that gives the alignment boundary, in bits,
8060 of an argument with the specified mode and type. If it is not defined,
8061 PARM_BOUNDARY is used for all arguments.
8063 V.4 wants long longs and doubles to be double word aligned. Just
8064 testing the mode size is a boneheaded way to do this as it means
8065 that other types such as complex int are also double word aligned.
8066 However, we're stuck with this because changing the ABI might break
8067 existing library interfaces.
8069 Doubleword align SPE vectors.
8070 Quadword align Altivec vectors.
8071 Quadword align large synthetic vector types. */
8074 rs6000_function_arg_boundary (enum machine_mode mode, const_tree type)
8076 if (DEFAULT_ABI == ABI_V4
8077 && (GET_MODE_SIZE (mode) == 8
8078 || (TARGET_HARD_FLOAT
8080 && (mode == TFmode || mode == TDmode))))
8082 else if (SPE_VECTOR_MODE (mode)
8083 || (type && TREE_CODE (type) == VECTOR_TYPE
8084 && int_size_in_bytes (type) >= 8
8085 && int_size_in_bytes (type) < 16))
8087 else if ((ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode))
8088 || (type && TREE_CODE (type) == VECTOR_TYPE
8089 && int_size_in_bytes (type) >= 16))
8091 else if (TARGET_MACHO
8092 && rs6000_darwin64_abi
8094 && type && TYPE_ALIGN (type) > 64)
8097 return PARM_BOUNDARY;
8100 /* For a function parm of MODE and TYPE, return the starting word in
8101 the parameter area. NWORDS of the parameter area are already used. */
8104 rs6000_parm_start (enum machine_mode mode, const_tree type,
8105 unsigned int nwords)
8108 unsigned int parm_offset;
8110 align = rs6000_function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
8111 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
8112 return nwords + (-(parm_offset + nwords) & align);
8115 /* Compute the size (in words) of a function argument. */
8117 static unsigned long
8118 rs6000_arg_size (enum machine_mode mode, const_tree type)
8122 if (mode != BLKmode)
8123 size = GET_MODE_SIZE (mode);
8125 size = int_size_in_bytes (type);
8128 return (size + 3) >> 2;
8130 return (size + 7) >> 3;
8133 /* Use this to flush pending int fields. */
8136 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
8137 HOST_WIDE_INT bitpos, int final)
8139 unsigned int startbit, endbit;
8140 int intregs, intoffset;
8141 enum machine_mode mode;
8143 /* Handle the situations where a float is taking up the first half
8144 of the GPR, and the other half is empty (typically due to
8145 alignment restrictions). We can detect this by a 8-byte-aligned
8146 int field, or by seeing that this is the final flush for this
8147 argument. Count the word and continue on. */
8148 if (cum->floats_in_gpr == 1
8149 && (cum->intoffset % 64 == 0
8150 || (cum->intoffset == -1 && final)))
8153 cum->floats_in_gpr = 0;
8156 if (cum->intoffset == -1)
8159 intoffset = cum->intoffset;
8160 cum->intoffset = -1;
8161 cum->floats_in_gpr = 0;
8163 if (intoffset % BITS_PER_WORD != 0)
8165 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
8167 if (mode == BLKmode)
8169 /* We couldn't find an appropriate mode, which happens,
8170 e.g., in packed structs when there are 3 bytes to load.
8171 Back intoffset back to the beginning of the word in this
8173 intoffset = intoffset & -BITS_PER_WORD;
8177 startbit = intoffset & -BITS_PER_WORD;
8178 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
8179 intregs = (endbit - startbit) / BITS_PER_WORD;
8180 cum->words += intregs;
8181 /* words should be unsigned. */
8182 if ((unsigned)cum->words < (endbit/BITS_PER_WORD))
8184 int pad = (endbit/BITS_PER_WORD) - cum->words;
8189 /* The darwin64 ABI calls for us to recurse down through structs,
8190 looking for elements passed in registers. Unfortunately, we have
8191 to track int register count here also because of misalignments
8192 in powerpc alignment mode. */
8195 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
8197 HOST_WIDE_INT startbitpos)
8201 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
8202 if (TREE_CODE (f) == FIELD_DECL)
8204 HOST_WIDE_INT bitpos = startbitpos;
8205 tree ftype = TREE_TYPE (f);
8206 enum machine_mode mode;
8207 if (ftype == error_mark_node)
8209 mode = TYPE_MODE (ftype);
8211 if (DECL_SIZE (f) != 0
8212 && host_integerp (bit_position (f), 1))
8213 bitpos += int_bit_position (f);
8215 /* ??? FIXME: else assume zero offset. */
8217 if (TREE_CODE (ftype) == RECORD_TYPE)
8218 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
8219 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
8221 unsigned n_fpregs = (GET_MODE_SIZE (mode) + 7) >> 3;
8222 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
8223 cum->fregno += n_fpregs;
8224 /* Single-precision floats present a special problem for
8225 us, because they are smaller than an 8-byte GPR, and so
8226 the structure-packing rules combined with the standard
8227 varargs behavior mean that we want to pack float/float
8228 and float/int combinations into a single register's
8229 space. This is complicated by the arg advance flushing,
8230 which works on arbitrarily large groups of int-type
8234 if (cum->floats_in_gpr == 1)
8236 /* Two floats in a word; count the word and reset
8239 cum->floats_in_gpr = 0;
8241 else if (bitpos % 64 == 0)
8243 /* A float at the beginning of an 8-byte word;
8244 count it and put off adjusting cum->words until
8245 we see if a arg advance flush is going to do it
8247 cum->floats_in_gpr++;
8251 /* The float is at the end of a word, preceded
8252 by integer fields, so the arg advance flush
8253 just above has already set cum->words and
8254 everything is taken care of. */
8258 cum->words += n_fpregs;
8260 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
8262 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
8266 else if (cum->intoffset == -1)
8267 cum->intoffset = bitpos;
8271 /* Check for an item that needs to be considered specially under the darwin 64
8272 bit ABI. These are record types where the mode is BLK or the structure is
8275 rs6000_darwin64_struct_check_p (enum machine_mode mode, const_tree type)
8277 return rs6000_darwin64_abi
8278 && ((mode == BLKmode
8279 && TREE_CODE (type) == RECORD_TYPE
8280 && int_size_in_bytes (type) > 0)
8281 || (type && TREE_CODE (type) == RECORD_TYPE
8282 && int_size_in_bytes (type) == 8)) ? 1 : 0;
8285 /* Update the data in CUM to advance over an argument
8286 of mode MODE and data type TYPE.
8287 (TYPE is null for libcalls where that information may not be available.)
8289 Note that for args passed by reference, function_arg will be called
8290 with MODE and TYPE set to that of the pointer to the arg, not the arg
8294 rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8295 const_tree type, bool named, int depth)
8297 /* Only tick off an argument if we're not recursing. */
8299 cum->nargs_prototype--;
8301 #ifdef HAVE_AS_GNU_ATTRIBUTE
8302 if (DEFAULT_ABI == ABI_V4
8305 if (SCALAR_FLOAT_MODE_P (mode))
8306 rs6000_passes_float = true;
8307 else if (named && (ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode)))
8308 rs6000_passes_vector = true;
8309 else if (SPE_VECTOR_MODE (mode)
8311 && cum->sysv_gregno <= GP_ARG_MAX_REG)
8312 rs6000_passes_vector = true;
8316 if (TARGET_ALTIVEC_ABI
8317 && (ALTIVEC_VECTOR_MODE (mode)
8318 || VSX_VECTOR_MODE (mode)
8319 || (type && TREE_CODE (type) == VECTOR_TYPE
8320 && int_size_in_bytes (type) == 16)))
8324 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
8327 if (!TARGET_ALTIVEC)
8328 error ("cannot pass argument in vector register because"
8329 " altivec instructions are disabled, use -maltivec"
8332 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
8333 even if it is going to be passed in a vector register.
8334 Darwin does the same for variable-argument functions. */
8335 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
8336 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
8346 /* Vector parameters must be 16-byte aligned. This places
8347 them at 2 mod 4 in terms of words in 32-bit mode, since
8348 the parameter save area starts at offset 24 from the
8349 stack. In 64-bit mode, they just have to start on an
8350 even word, since the parameter save area is 16-byte
8351 aligned. Space for GPRs is reserved even if the argument
8352 will be passed in memory. */
8354 align = (2 - cum->words) & 3;
8356 align = cum->words & 1;
8357 cum->words += align + rs6000_arg_size (mode, type);
8359 if (TARGET_DEBUG_ARG)
8361 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
8363 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
8364 cum->nargs_prototype, cum->prototype,
8365 GET_MODE_NAME (mode));
8369 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
8371 && cum->sysv_gregno <= GP_ARG_MAX_REG)
8374 else if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8376 int size = int_size_in_bytes (type);
8377 /* Variable sized types have size == -1 and are
8378 treated as if consisting entirely of ints.
8379 Pad to 16 byte boundary if needed. */
8380 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8381 && (cum->words % 2) != 0)
8383 /* For varargs, we can just go up by the size of the struct. */
8385 cum->words += (size + 7) / 8;
8388 /* It is tempting to say int register count just goes up by
8389 sizeof(type)/8, but this is wrong in a case such as
8390 { int; double; int; } [powerpc alignment]. We have to
8391 grovel through the fields for these too. */
8393 cum->floats_in_gpr = 0;
8394 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
8395 rs6000_darwin64_record_arg_advance_flush (cum,
8396 size * BITS_PER_UNIT, 1);
8398 if (TARGET_DEBUG_ARG)
8400 fprintf (stderr, "function_adv: words = %2d, align=%d, size=%d",
8401 cum->words, TYPE_ALIGN (type), size);
8403 "nargs = %4d, proto = %d, mode = %4s (darwin64 abi)\n",
8404 cum->nargs_prototype, cum->prototype,
8405 GET_MODE_NAME (mode));
8408 else if (DEFAULT_ABI == ABI_V4)
8410 if (TARGET_HARD_FLOAT && TARGET_FPRS
8411 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8412 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8413 || (mode == TFmode && !TARGET_IEEEQUAD)
8414 || mode == SDmode || mode == DDmode || mode == TDmode))
8416 /* _Decimal128 must use an even/odd register pair. This assumes
8417 that the register number is odd when fregno is odd. */
8418 if (mode == TDmode && (cum->fregno % 2) == 1)
8421 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8422 <= FP_ARG_V4_MAX_REG)
8423 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8426 cum->fregno = FP_ARG_V4_MAX_REG + 1;
8427 if (mode == DFmode || mode == TFmode
8428 || mode == DDmode || mode == TDmode)
8429 cum->words += cum->words & 1;
8430 cum->words += rs6000_arg_size (mode, type);
8435 int n_words = rs6000_arg_size (mode, type);
8436 int gregno = cum->sysv_gregno;
8438 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8439 (r7,r8) or (r9,r10). As does any other 2 word item such
8440 as complex int due to a historical mistake. */
8442 gregno += (1 - gregno) & 1;
8444 /* Multi-reg args are not split between registers and stack. */
8445 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8447 /* Long long and SPE vectors are aligned on the stack.
8448 So are other 2 word items such as complex int due to
8449 a historical mistake. */
8451 cum->words += cum->words & 1;
8452 cum->words += n_words;
8455 /* Note: continuing to accumulate gregno past when we've started
8456 spilling to the stack indicates the fact that we've started
8457 spilling to the stack to expand_builtin_saveregs. */
8458 cum->sysv_gregno = gregno + n_words;
8461 if (TARGET_DEBUG_ARG)
8463 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8464 cum->words, cum->fregno);
8465 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
8466 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
8467 fprintf (stderr, "mode = %4s, named = %d\n",
8468 GET_MODE_NAME (mode), named);
8473 int n_words = rs6000_arg_size (mode, type);
8474 int start_words = cum->words;
8475 int align_words = rs6000_parm_start (mode, type, start_words);
8477 cum->words = align_words + n_words;
8479 if (SCALAR_FLOAT_MODE_P (mode)
8480 && TARGET_HARD_FLOAT && TARGET_FPRS)
8482 /* _Decimal128 must be passed in an even/odd float register pair.
8483 This assumes that the register number is odd when fregno is
8485 if (mode == TDmode && (cum->fregno % 2) == 1)
8487 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8490 if (TARGET_DEBUG_ARG)
8492 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8493 cum->words, cum->fregno);
8494 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
8495 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
8496 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
8497 named, align_words - start_words, depth);
8503 rs6000_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8504 const_tree type, bool named)
8506 rs6000_function_arg_advance_1 (cum, mode, type, named, 0);
8510 spe_build_register_parallel (enum machine_mode mode, int gregno)
8517 r1 = gen_rtx_REG (DImode, gregno);
8518 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8519 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
8523 r1 = gen_rtx_REG (DImode, gregno);
8524 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8525 r3 = gen_rtx_REG (DImode, gregno + 2);
8526 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8527 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
8530 r1 = gen_rtx_REG (DImode, gregno);
8531 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8532 r3 = gen_rtx_REG (DImode, gregno + 2);
8533 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8534 r5 = gen_rtx_REG (DImode, gregno + 4);
8535 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
8536 r7 = gen_rtx_REG (DImode, gregno + 6);
8537 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
8538 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
8545 /* Determine where to put a SIMD argument on the SPE. */
8547 rs6000_spe_function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
8550 int gregno = cum->sysv_gregno;
8552 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
8553 are passed and returned in a pair of GPRs for ABI compatibility. */
8554 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
8555 || mode == DCmode || mode == TCmode))
8557 int n_words = rs6000_arg_size (mode, type);
8559 /* Doubles go in an odd/even register pair (r5/r6, etc). */
8561 gregno += (1 - gregno) & 1;
8563 /* Multi-reg args are not split between registers and stack. */
8564 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8567 return spe_build_register_parallel (mode, gregno);
8571 int n_words = rs6000_arg_size (mode, type);
8573 /* SPE vectors are put in odd registers. */
8574 if (n_words == 2 && (gregno & 1) == 0)
8577 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
8580 enum machine_mode m = SImode;
8582 r1 = gen_rtx_REG (m, gregno);
8583 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
8584 r2 = gen_rtx_REG (m, gregno + 1);
8585 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
8586 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
8593 if (gregno <= GP_ARG_MAX_REG)
8594 return gen_rtx_REG (mode, gregno);
8600 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
8601 structure between cum->intoffset and bitpos to integer registers. */
8604 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
8605 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
8607 enum machine_mode mode;
8609 unsigned int startbit, endbit;
8610 int this_regno, intregs, intoffset;
8613 if (cum->intoffset == -1)
8616 intoffset = cum->intoffset;
8617 cum->intoffset = -1;
8619 /* If this is the trailing part of a word, try to only load that
8620 much into the register. Otherwise load the whole register. Note
8621 that in the latter case we may pick up unwanted bits. It's not a
8622 problem at the moment but may wish to revisit. */
8624 if (intoffset % BITS_PER_WORD != 0)
8626 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
8628 if (mode == BLKmode)
8630 /* We couldn't find an appropriate mode, which happens,
8631 e.g., in packed structs when there are 3 bytes to load.
8632 Back intoffset back to the beginning of the word in this
8634 intoffset = intoffset & -BITS_PER_WORD;
8641 startbit = intoffset & -BITS_PER_WORD;
8642 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
8643 intregs = (endbit - startbit) / BITS_PER_WORD;
8644 this_regno = cum->words + intoffset / BITS_PER_WORD;
8646 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
8649 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
8653 intoffset /= BITS_PER_UNIT;
8656 regno = GP_ARG_MIN_REG + this_regno;
8657 reg = gen_rtx_REG (mode, regno);
8659 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
8662 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
8666 while (intregs > 0);
8669 /* Recursive workhorse for the following. */
8672 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
8673 HOST_WIDE_INT startbitpos, rtx rvec[],
8678 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
8679 if (TREE_CODE (f) == FIELD_DECL)
8681 HOST_WIDE_INT bitpos = startbitpos;
8682 tree ftype = TREE_TYPE (f);
8683 enum machine_mode mode;
8684 if (ftype == error_mark_node)
8686 mode = TYPE_MODE (ftype);
8688 if (DECL_SIZE (f) != 0
8689 && host_integerp (bit_position (f), 1))
8690 bitpos += int_bit_position (f);
8692 /* ??? FIXME: else assume zero offset. */
8694 if (TREE_CODE (ftype) == RECORD_TYPE)
8695 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
8696 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
8698 unsigned n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
8702 case SCmode: mode = SFmode; break;
8703 case DCmode: mode = DFmode; break;
8704 case TCmode: mode = TFmode; break;
8708 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8709 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
8711 gcc_assert (cum->fregno == FP_ARG_MAX_REG
8712 && (mode == TFmode || mode == TDmode));
8713 /* Long double or _Decimal128 split over regs and memory. */
8714 mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : DFmode;
8718 = gen_rtx_EXPR_LIST (VOIDmode,
8719 gen_rtx_REG (mode, cum->fregno++),
8720 GEN_INT (bitpos / BITS_PER_UNIT));
8721 if (mode == TFmode || mode == TDmode)
8724 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
8726 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8728 = gen_rtx_EXPR_LIST (VOIDmode,
8729 gen_rtx_REG (mode, cum->vregno++),
8730 GEN_INT (bitpos / BITS_PER_UNIT));
8732 else if (cum->intoffset == -1)
8733 cum->intoffset = bitpos;
8737 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
8738 the register(s) to be used for each field and subfield of a struct
8739 being passed by value, along with the offset of where the
8740 register's value may be found in the block. FP fields go in FP
8741 register, vector fields go in vector registers, and everything
8742 else goes in int registers, packed as in memory.
8744 This code is also used for function return values. RETVAL indicates
8745 whether this is the case.
8747 Much of this is taken from the SPARC V9 port, which has a similar
8748 calling convention. */
8751 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
8752 bool named, bool retval)
8754 rtx rvec[FIRST_PSEUDO_REGISTER];
8755 int k = 1, kbase = 1;
8756 HOST_WIDE_INT typesize = int_size_in_bytes (type);
8757 /* This is a copy; modifications are not visible to our caller. */
8758 CUMULATIVE_ARGS copy_cum = *orig_cum;
8759 CUMULATIVE_ARGS *cum = ©_cum;
8761 /* Pad to 16 byte boundary if needed. */
8762 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8763 && (cum->words % 2) != 0)
8770 /* Put entries into rvec[] for individual FP and vector fields, and
8771 for the chunks of memory that go in int regs. Note we start at
8772 element 1; 0 is reserved for an indication of using memory, and
8773 may or may not be filled in below. */
8774 rs6000_darwin64_record_arg_recurse (cum, type, /* startbit pos= */ 0, rvec, &k);
8775 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
8777 /* If any part of the struct went on the stack put all of it there.
8778 This hack is because the generic code for
8779 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
8780 parts of the struct are not at the beginning. */
8784 return NULL_RTX; /* doesn't go in registers at all */
8786 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8788 if (k > 1 || cum->use_stack)
8789 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
8794 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
8797 rs6000_mixed_function_arg (enum machine_mode mode, const_tree type,
8802 rtx rvec[GP_ARG_NUM_REG + 1];
8804 if (align_words >= GP_ARG_NUM_REG)
8807 n_units = rs6000_arg_size (mode, type);
8809 /* Optimize the simple case where the arg fits in one gpr, except in
8810 the case of BLKmode due to assign_parms assuming that registers are
8811 BITS_PER_WORD wide. */
8813 || (n_units == 1 && mode != BLKmode))
8814 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8817 if (align_words + n_units > GP_ARG_NUM_REG)
8818 /* Not all of the arg fits in gprs. Say that it goes in memory too,
8819 using a magic NULL_RTX component.
8820 This is not strictly correct. Only some of the arg belongs in
8821 memory, not all of it. However, the normal scheme using
8822 function_arg_partial_nregs can result in unusual subregs, eg.
8823 (subreg:SI (reg:DF) 4), which are not handled well. The code to
8824 store the whole arg to memory is often more efficient than code
8825 to store pieces, and we know that space is available in the right
8826 place for the whole arg. */
8827 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8832 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
8833 rtx off = GEN_INT (i++ * 4);
8834 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8836 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
8838 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8841 /* Determine where to put an argument to a function.
8842 Value is zero to push the argument on the stack,
8843 or a hard register in which to store the argument.
8845 MODE is the argument's machine mode.
8846 TYPE is the data type of the argument (as a tree).
8847 This is null for libcalls where that information may
8849 CUM is a variable of type CUMULATIVE_ARGS which gives info about
8850 the preceding args and about the function being called. It is
8851 not modified in this routine.
8852 NAMED is nonzero if this argument is a named parameter
8853 (otherwise it is an extra parameter matching an ellipsis).
8855 On RS/6000 the first eight words of non-FP are normally in registers
8856 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
8857 Under V.4, the first 8 FP args are in registers.
8859 If this is floating-point and no prototype is specified, we use
8860 both an FP and integer register (or possibly FP reg and stack). Library
8861 functions (when CALL_LIBCALL is set) always have the proper types for args,
8862 so we can pass the FP value just in one register. emit_library_function
8863 doesn't support PARALLEL anyway.
8865 Note that for args passed by reference, function_arg will be called
8866 with MODE and TYPE set to that of the pointer to the arg, not the arg
8870 rs6000_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8871 const_tree type, bool named)
8873 enum rs6000_abi abi = DEFAULT_ABI;
8875 /* Return a marker to indicate whether CR1 needs to set or clear the
8876 bit that V.4 uses to say fp args were passed in registers.
8877 Assume that we don't need the marker for software floating point,
8878 or compiler generated library calls. */
8879 if (mode == VOIDmode)
8882 && (cum->call_cookie & CALL_LIBCALL) == 0
8884 || (cum->nargs_prototype < 0
8885 && (cum->prototype || TARGET_NO_PROTOTYPE))))
8887 /* For the SPE, we need to crxor CR6 always. */
8889 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
8890 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
8891 return GEN_INT (cum->call_cookie
8892 | ((cum->fregno == FP_ARG_MIN_REG)
8893 ? CALL_V4_SET_FP_ARGS
8894 : CALL_V4_CLEAR_FP_ARGS));
8897 return GEN_INT (cum->call_cookie);
8900 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8902 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, /*retval= */false);
8903 if (rslt != NULL_RTX)
8905 /* Else fall through to usual handling. */
8908 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
8909 if (TARGET_64BIT && ! cum->prototype)
8911 /* Vector parameters get passed in vector register
8912 and also in GPRs or memory, in absence of prototype. */
8915 align_words = (cum->words + 1) & ~1;
8917 if (align_words >= GP_ARG_NUM_REG)
8923 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8925 return gen_rtx_PARALLEL (mode,
8927 gen_rtx_EXPR_LIST (VOIDmode,
8929 gen_rtx_EXPR_LIST (VOIDmode,
8930 gen_rtx_REG (mode, cum->vregno),
8934 return gen_rtx_REG (mode, cum->vregno);
8935 else if (TARGET_ALTIVEC_ABI
8936 && (ALTIVEC_VECTOR_MODE (mode)
8937 || VSX_VECTOR_MODE (mode)
8938 || (type && TREE_CODE (type) == VECTOR_TYPE
8939 && int_size_in_bytes (type) == 16)))
8941 if (named || abi == ABI_V4)
8945 /* Vector parameters to varargs functions under AIX or Darwin
8946 get passed in memory and possibly also in GPRs. */
8947 int align, align_words, n_words;
8948 enum machine_mode part_mode;
8950 /* Vector parameters must be 16-byte aligned. This places them at
8951 2 mod 4 in terms of words in 32-bit mode, since the parameter
8952 save area starts at offset 24 from the stack. In 64-bit mode,
8953 they just have to start on an even word, since the parameter
8954 save area is 16-byte aligned. */
8956 align = (2 - cum->words) & 3;
8958 align = cum->words & 1;
8959 align_words = cum->words + align;
8961 /* Out of registers? Memory, then. */
8962 if (align_words >= GP_ARG_NUM_REG)
8965 if (TARGET_32BIT && TARGET_POWERPC64)
8966 return rs6000_mixed_function_arg (mode, type, align_words);
8968 /* The vector value goes in GPRs. Only the part of the
8969 value in GPRs is reported here. */
8971 n_words = rs6000_arg_size (mode, type);
8972 if (align_words + n_words > GP_ARG_NUM_REG)
8973 /* Fortunately, there are only two possibilities, the value
8974 is either wholly in GPRs or half in GPRs and half not. */
8977 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
8980 else if (TARGET_SPE_ABI && TARGET_SPE
8981 && (SPE_VECTOR_MODE (mode)
8982 || (TARGET_E500_DOUBLE && (mode == DFmode
8985 || mode == TCmode))))
8986 return rs6000_spe_function_arg (cum, mode, type);
8988 else if (abi == ABI_V4)
8990 if (TARGET_HARD_FLOAT && TARGET_FPRS
8991 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8992 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8993 || (mode == TFmode && !TARGET_IEEEQUAD)
8994 || mode == SDmode || mode == DDmode || mode == TDmode))
8996 /* _Decimal128 must use an even/odd register pair. This assumes
8997 that the register number is odd when fregno is odd. */
8998 if (mode == TDmode && (cum->fregno % 2) == 1)
9001 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
9002 <= FP_ARG_V4_MAX_REG)
9003 return gen_rtx_REG (mode, cum->fregno);
9009 int n_words = rs6000_arg_size (mode, type);
9010 int gregno = cum->sysv_gregno;
9012 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
9013 (r7,r8) or (r9,r10). As does any other 2 word item such
9014 as complex int due to a historical mistake. */
9016 gregno += (1 - gregno) & 1;
9018 /* Multi-reg args are not split between registers and stack. */
9019 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
9022 if (TARGET_32BIT && TARGET_POWERPC64)
9023 return rs6000_mixed_function_arg (mode, type,
9024 gregno - GP_ARG_MIN_REG);
9025 return gen_rtx_REG (mode, gregno);
9030 int align_words = rs6000_parm_start (mode, type, cum->words);
9032 /* _Decimal128 must be passed in an even/odd float register pair.
9033 This assumes that the register number is odd when fregno is odd. */
9034 if (mode == TDmode && (cum->fregno % 2) == 1)
9037 if (USE_FP_FOR_ARG_P (cum, mode, type))
9039 rtx rvec[GP_ARG_NUM_REG + 1];
9043 enum machine_mode fmode = mode;
9044 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
9046 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
9048 /* Currently, we only ever need one reg here because complex
9049 doubles are split. */
9050 gcc_assert (cum->fregno == FP_ARG_MAX_REG
9051 && (fmode == TFmode || fmode == TDmode));
9053 /* Long double or _Decimal128 split over regs and memory. */
9054 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
9057 /* Do we also need to pass this arg in the parameter save
9060 && (cum->nargs_prototype <= 0
9061 || (DEFAULT_ABI == ABI_AIX
9063 && align_words >= GP_ARG_NUM_REG)));
9065 if (!needs_psave && mode == fmode)
9066 return gen_rtx_REG (fmode, cum->fregno);
9071 /* Describe the part that goes in gprs or the stack.
9072 This piece must come first, before the fprs. */
9073 if (align_words < GP_ARG_NUM_REG)
9075 unsigned long n_words = rs6000_arg_size (mode, type);
9077 if (align_words + n_words > GP_ARG_NUM_REG
9078 || (TARGET_32BIT && TARGET_POWERPC64))
9080 /* If this is partially on the stack, then we only
9081 include the portion actually in registers here. */
9082 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
9085 if (align_words + n_words > GP_ARG_NUM_REG)
9086 /* Not all of the arg fits in gprs. Say that it
9087 goes in memory too, using a magic NULL_RTX
9088 component. Also see comment in
9089 rs6000_mixed_function_arg for why the normal
9090 function_arg_partial_nregs scheme doesn't work
9092 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
9096 r = gen_rtx_REG (rmode,
9097 GP_ARG_MIN_REG + align_words);
9098 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
9099 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
9101 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
9105 /* The whole arg fits in gprs. */
9106 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
9107 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
9111 /* It's entirely in memory. */
9112 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
9115 /* Describe where this piece goes in the fprs. */
9116 r = gen_rtx_REG (fmode, cum->fregno);
9117 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
9119 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
9121 else if (align_words < GP_ARG_NUM_REG)
9123 if (TARGET_32BIT && TARGET_POWERPC64)
9124 return rs6000_mixed_function_arg (mode, type, align_words);
9126 if (mode == BLKmode)
9129 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
9136 /* For an arg passed partly in registers and partly in memory, this is
9137 the number of bytes passed in registers. For args passed entirely in
9138 registers or entirely in memory, zero. When an arg is described by a
9139 PARALLEL, perhaps using more than one register type, this function
9140 returns the number of bytes used by the first element of the PARALLEL. */
9143 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
9144 tree type, bool named)
9149 if (DEFAULT_ABI == ABI_V4)
9152 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
9153 && cum->nargs_prototype >= 0)
9156 /* In this complicated case we just disable the partial_nregs code. */
9157 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
9160 align_words = rs6000_parm_start (mode, type, cum->words);
9162 if (USE_FP_FOR_ARG_P (cum, mode, type))
9164 /* If we are passing this arg in the fixed parameter save area
9165 (gprs or memory) as well as fprs, then this function should
9166 return the number of partial bytes passed in the parameter
9167 save area rather than partial bytes passed in fprs. */
9169 && (cum->nargs_prototype <= 0
9170 || (DEFAULT_ABI == ABI_AIX
9172 && align_words >= GP_ARG_NUM_REG)))
9174 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
9175 > FP_ARG_MAX_REG + 1)
9176 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
9177 else if (cum->nargs_prototype >= 0)
9181 if (align_words < GP_ARG_NUM_REG
9182 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
9183 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
9185 if (ret != 0 && TARGET_DEBUG_ARG)
9186 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
9191 /* A C expression that indicates when an argument must be passed by
9192 reference. If nonzero for an argument, a copy of that argument is
9193 made in memory and a pointer to the argument is passed instead of
9194 the argument itself. The pointer is passed in whatever way is
9195 appropriate for passing a pointer to that type.
9197 Under V.4, aggregates and long double are passed by reference.
9199 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
9200 reference unless the AltiVec vector extension ABI is in force.
9202 As an extension to all ABIs, variable sized types are passed by
9206 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
9207 enum machine_mode mode, const_tree type,
9208 bool named ATTRIBUTE_UNUSED)
9210 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
9212 if (TARGET_DEBUG_ARG)
9213 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
9220 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
9222 if (TARGET_DEBUG_ARG)
9223 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
9227 if (int_size_in_bytes (type) < 0)
9229 if (TARGET_DEBUG_ARG)
9230 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
9234 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
9235 modes only exist for GCC vector types if -maltivec. */
9236 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
9238 if (TARGET_DEBUG_ARG)
9239 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
9243 /* Pass synthetic vectors in memory. */
9244 if (TREE_CODE (type) == VECTOR_TYPE
9245 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
9247 static bool warned_for_pass_big_vectors = false;
9248 if (TARGET_DEBUG_ARG)
9249 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
9250 if (!warned_for_pass_big_vectors)
9252 warning (0, "GCC vector passed by reference: "
9253 "non-standard ABI extension with no compatibility guarantee");
9254 warned_for_pass_big_vectors = true;
9263 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
9266 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
9271 for (i = 0; i < nregs; i++)
9273 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
9274 if (reload_completed)
9276 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
9279 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
9280 i * GET_MODE_SIZE (reg_mode));
9283 tem = replace_equiv_address (tem, XEXP (tem, 0));
9287 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
9291 /* Perform any needed actions needed for a function that is receiving a
9292 variable number of arguments.
9296 MODE and TYPE are the mode and type of the current parameter.
9298 PRETEND_SIZE is a variable that should be set to the amount of stack
9299 that must be pushed by the prolog to pretend that our caller pushed
9302 Normally, this macro will push all remaining incoming registers on the
9303 stack and set PRETEND_SIZE to the length of the registers pushed. */
9306 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
9307 tree type, int *pretend_size ATTRIBUTE_UNUSED,
9310 CUMULATIVE_ARGS next_cum;
9311 int reg_size = TARGET_32BIT ? 4 : 8;
9312 rtx save_area = NULL_RTX, mem;
9313 int first_reg_offset;
9316 /* Skip the last named argument. */
9318 rs6000_function_arg_advance_1 (&next_cum, mode, type, true, 0);
9320 if (DEFAULT_ABI == ABI_V4)
9322 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
9326 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
9327 HOST_WIDE_INT offset = 0;
9329 /* Try to optimize the size of the varargs save area.
9330 The ABI requires that ap.reg_save_area is doubleword
9331 aligned, but we don't need to allocate space for all
9332 the bytes, only those to which we actually will save
9334 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
9335 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
9336 if (TARGET_HARD_FLOAT && TARGET_FPRS
9337 && next_cum.fregno <= FP_ARG_V4_MAX_REG
9338 && cfun->va_list_fpr_size)
9341 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
9342 * UNITS_PER_FP_WORD;
9343 if (cfun->va_list_fpr_size
9344 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
9345 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
9347 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
9348 * UNITS_PER_FP_WORD;
9352 offset = -((first_reg_offset * reg_size) & ~7);
9353 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
9355 gpr_reg_num = cfun->va_list_gpr_size;
9356 if (reg_size == 4 && (first_reg_offset & 1))
9359 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
9362 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
9364 - (int) (GP_ARG_NUM_REG * reg_size);
9366 if (gpr_size + fpr_size)
9369 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
9370 gcc_assert (GET_CODE (reg_save_area) == MEM);
9371 reg_save_area = XEXP (reg_save_area, 0);
9372 if (GET_CODE (reg_save_area) == PLUS)
9374 gcc_assert (XEXP (reg_save_area, 0)
9375 == virtual_stack_vars_rtx);
9376 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
9377 offset += INTVAL (XEXP (reg_save_area, 1));
9380 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
9383 cfun->machine->varargs_save_offset = offset;
9384 save_area = plus_constant (virtual_stack_vars_rtx, offset);
9389 first_reg_offset = next_cum.words;
9390 save_area = virtual_incoming_args_rtx;
9392 if (targetm.calls.must_pass_in_stack (mode, type))
9393 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
9396 set = get_varargs_alias_set ();
9397 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
9398 && cfun->va_list_gpr_size)
9400 int nregs = GP_ARG_NUM_REG - first_reg_offset;
9402 if (va_list_gpr_counter_field)
9404 /* V4 va_list_gpr_size counts number of registers needed. */
9405 if (nregs > cfun->va_list_gpr_size)
9406 nregs = cfun->va_list_gpr_size;
9410 /* char * va_list instead counts number of bytes needed. */
9411 if (nregs > cfun->va_list_gpr_size / reg_size)
9412 nregs = cfun->va_list_gpr_size / reg_size;
9415 mem = gen_rtx_MEM (BLKmode,
9416 plus_constant (save_area,
9417 first_reg_offset * reg_size));
9418 MEM_NOTRAP_P (mem) = 1;
9419 set_mem_alias_set (mem, set);
9420 set_mem_align (mem, BITS_PER_WORD);
9422 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
9426 /* Save FP registers if needed. */
9427 if (DEFAULT_ABI == ABI_V4
9428 && TARGET_HARD_FLOAT && TARGET_FPRS
9430 && next_cum.fregno <= FP_ARG_V4_MAX_REG
9431 && cfun->va_list_fpr_size)
9433 int fregno = next_cum.fregno, nregs;
9434 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
9435 rtx lab = gen_label_rtx ();
9436 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
9437 * UNITS_PER_FP_WORD);
9440 (gen_rtx_SET (VOIDmode,
9442 gen_rtx_IF_THEN_ELSE (VOIDmode,
9443 gen_rtx_NE (VOIDmode, cr1,
9445 gen_rtx_LABEL_REF (VOIDmode, lab),
9449 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
9450 fregno++, off += UNITS_PER_FP_WORD, nregs++)
9452 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9454 plus_constant (save_area, off));
9455 MEM_NOTRAP_P (mem) = 1;
9456 set_mem_alias_set (mem, set);
9457 set_mem_align (mem, GET_MODE_ALIGNMENT (
9458 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9459 ? DFmode : SFmode));
9460 emit_move_insn (mem, gen_rtx_REG (
9461 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9462 ? DFmode : SFmode, fregno));
9469 /* Create the va_list data type. */
9472 rs6000_build_builtin_va_list (void)
9474 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
9476 /* For AIX, prefer 'char *' because that's what the system
9477 header files like. */
9478 if (DEFAULT_ABI != ABI_V4)
9479 return build_pointer_type (char_type_node);
9481 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
9482 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
9483 get_identifier ("__va_list_tag"), record);
9485 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
9486 unsigned_char_type_node);
9487 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
9488 unsigned_char_type_node);
9489 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
9491 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9492 get_identifier ("reserved"), short_unsigned_type_node);
9493 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9494 get_identifier ("overflow_arg_area"),
9496 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9497 get_identifier ("reg_save_area"),
9500 va_list_gpr_counter_field = f_gpr;
9501 va_list_fpr_counter_field = f_fpr;
9503 DECL_FIELD_CONTEXT (f_gpr) = record;
9504 DECL_FIELD_CONTEXT (f_fpr) = record;
9505 DECL_FIELD_CONTEXT (f_res) = record;
9506 DECL_FIELD_CONTEXT (f_ovf) = record;
9507 DECL_FIELD_CONTEXT (f_sav) = record;
9509 TYPE_STUB_DECL (record) = type_decl;
9510 TYPE_NAME (record) = type_decl;
9511 TYPE_FIELDS (record) = f_gpr;
9512 DECL_CHAIN (f_gpr) = f_fpr;
9513 DECL_CHAIN (f_fpr) = f_res;
9514 DECL_CHAIN (f_res) = f_ovf;
9515 DECL_CHAIN (f_ovf) = f_sav;
9517 layout_type (record);
9519 /* The correct type is an array type of one element. */
9520 return build_array_type (record, build_index_type (size_zero_node));
9523 /* Implement va_start. */
9526 rs6000_va_start (tree valist, rtx nextarg)
9528 HOST_WIDE_INT words, n_gpr, n_fpr;
9529 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9530 tree gpr, fpr, ovf, sav, t;
9532 /* Only SVR4 needs something special. */
9533 if (DEFAULT_ABI != ABI_V4)
9535 std_expand_builtin_va_start (valist, nextarg);
9539 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9540 f_fpr = DECL_CHAIN (f_gpr);
9541 f_res = DECL_CHAIN (f_fpr);
9542 f_ovf = DECL_CHAIN (f_res);
9543 f_sav = DECL_CHAIN (f_ovf);
9545 valist = build_simple_mem_ref (valist);
9546 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9547 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9549 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9551 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9554 /* Count number of gp and fp argument registers used. */
9555 words = crtl->args.info.words;
9556 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
9558 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
9561 if (TARGET_DEBUG_ARG)
9562 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
9563 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
9564 words, n_gpr, n_fpr);
9566 if (cfun->va_list_gpr_size)
9568 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
9569 build_int_cst (NULL_TREE, n_gpr));
9570 TREE_SIDE_EFFECTS (t) = 1;
9571 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9574 if (cfun->va_list_fpr_size)
9576 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
9577 build_int_cst (NULL_TREE, n_fpr));
9578 TREE_SIDE_EFFECTS (t) = 1;
9579 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9581 #ifdef HAVE_AS_GNU_ATTRIBUTE
9582 if (call_ABI_of_interest (cfun->decl))
9583 rs6000_passes_float = true;
9587 /* Find the overflow area. */
9588 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
9590 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
9591 size_int (words * UNITS_PER_WORD));
9592 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
9593 TREE_SIDE_EFFECTS (t) = 1;
9594 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9596 /* If there were no va_arg invocations, don't set up the register
9598 if (!cfun->va_list_gpr_size
9599 && !cfun->va_list_fpr_size
9600 && n_gpr < GP_ARG_NUM_REG
9601 && n_fpr < FP_ARG_V4_MAX_REG)
9604 /* Find the register save area. */
9605 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
9606 if (cfun->machine->varargs_save_offset)
9607 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
9608 size_int (cfun->machine->varargs_save_offset));
9609 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
9610 TREE_SIDE_EFFECTS (t) = 1;
9611 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9614 /* Implement va_arg. */
9617 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
9620 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9621 tree gpr, fpr, ovf, sav, reg, t, u;
9622 int size, rsize, n_reg, sav_ofs, sav_scale;
9623 tree lab_false, lab_over, addr;
9625 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
9629 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
9631 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
9632 return build_va_arg_indirect_ref (t);
9635 /* We need to deal with the fact that the darwin ppc64 ABI is defined by an
9636 earlier version of gcc, with the property that it always applied alignment
9637 adjustments to the va-args (even for zero-sized types). The cheapest way
9638 to deal with this is to replicate the effect of the part of
9639 std_gimplify_va_arg_expr that carries out the align adjust, for the case
9641 We don't need to check for pass-by-reference because of the test above.
9642 We can return a simplifed answer, since we know there's no offset to add. */
9645 && rs6000_darwin64_abi
9646 && integer_zerop (TYPE_SIZE (type)))
9648 unsigned HOST_WIDE_INT align, boundary;
9649 tree valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
9650 align = PARM_BOUNDARY / BITS_PER_UNIT;
9651 boundary = rs6000_function_arg_boundary (TYPE_MODE (type), type);
9652 if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
9653 boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
9654 boundary /= BITS_PER_UNIT;
9655 if (boundary > align)
9658 /* This updates arg ptr by the amount that would be necessary
9659 to align the zero-sized (but not zero-alignment) item. */
9660 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9661 fold_build2 (POINTER_PLUS_EXPR,
9663 valist_tmp, size_int (boundary - 1)));
9664 gimplify_and_add (t, pre_p);
9666 t = fold_convert (sizetype, valist_tmp);
9667 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9668 fold_convert (TREE_TYPE (valist),
9669 fold_build2 (BIT_AND_EXPR, sizetype, t,
9670 size_int (-boundary))));
9671 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
9672 gimplify_and_add (t, pre_p);
9674 /* Since it is zero-sized there's no increment for the item itself. */
9675 valist_tmp = fold_convert (build_pointer_type (type), valist_tmp);
9676 return build_va_arg_indirect_ref (valist_tmp);
9679 if (DEFAULT_ABI != ABI_V4)
9681 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
9683 tree elem_type = TREE_TYPE (type);
9684 enum machine_mode elem_mode = TYPE_MODE (elem_type);
9685 int elem_size = GET_MODE_SIZE (elem_mode);
9687 if (elem_size < UNITS_PER_WORD)
9689 tree real_part, imag_part;
9690 gimple_seq post = NULL;
9692 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9694 /* Copy the value into a temporary, lest the formal temporary
9695 be reused out from under us. */
9696 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
9697 gimple_seq_add_seq (pre_p, post);
9699 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9702 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
9706 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
9709 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9710 f_fpr = DECL_CHAIN (f_gpr);
9711 f_res = DECL_CHAIN (f_fpr);
9712 f_ovf = DECL_CHAIN (f_res);
9713 f_sav = DECL_CHAIN (f_ovf);
9715 valist = build_va_arg_indirect_ref (valist);
9716 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9717 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9719 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9721 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9724 size = int_size_in_bytes (type);
9725 rsize = (size + 3) / 4;
9728 if (TARGET_HARD_FLOAT && TARGET_FPRS
9729 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
9730 || (TARGET_DOUBLE_FLOAT
9731 && (TYPE_MODE (type) == DFmode
9732 || TYPE_MODE (type) == TFmode
9733 || TYPE_MODE (type) == SDmode
9734 || TYPE_MODE (type) == DDmode
9735 || TYPE_MODE (type) == TDmode))))
9737 /* FP args go in FP registers, if present. */
9739 n_reg = (size + 7) / 8;
9740 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
9741 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
9742 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
9747 /* Otherwise into GP registers. */
9756 /* Pull the value out of the saved registers.... */
9759 addr = create_tmp_var (ptr_type_node, "addr");
9761 /* AltiVec vectors never go in registers when -mabi=altivec. */
9762 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
9766 lab_false = create_artificial_label (input_location);
9767 lab_over = create_artificial_label (input_location);
9769 /* Long long and SPE vectors are aligned in the registers.
9770 As are any other 2 gpr item such as complex int due to a
9771 historical mistake. */
9773 if (n_reg == 2 && reg == gpr)
9776 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9777 build_int_cst (TREE_TYPE (reg), n_reg - 1));
9778 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
9779 unshare_expr (reg), u);
9781 /* _Decimal128 is passed in even/odd fpr pairs; the stored
9782 reg number is 0 for f1, so we want to make it odd. */
9783 else if (reg == fpr && TYPE_MODE (type) == TDmode)
9785 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9786 build_int_cst (TREE_TYPE (reg), 1));
9787 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
9790 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
9791 t = build2 (GE_EXPR, boolean_type_node, u, t);
9792 u = build1 (GOTO_EXPR, void_type_node, lab_false);
9793 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
9794 gimplify_and_add (t, pre_p);
9798 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
9800 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9801 build_int_cst (TREE_TYPE (reg), n_reg));
9802 u = fold_convert (sizetype, u);
9803 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
9804 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
9806 /* _Decimal32 varargs are located in the second word of the 64-bit
9807 FP register for 32-bit binaries. */
9808 if (!TARGET_POWERPC64
9809 && TARGET_HARD_FLOAT && TARGET_FPRS
9810 && TYPE_MODE (type) == SDmode)
9811 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9813 gimplify_assign (addr, t, pre_p);
9815 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
9817 stmt = gimple_build_label (lab_false);
9818 gimple_seq_add_stmt (pre_p, stmt);
9820 if ((n_reg == 2 && !regalign) || n_reg > 2)
9822 /* Ensure that we don't find any more args in regs.
9823 Alignment has taken care of for special cases. */
9824 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
9828 /* ... otherwise out of the overflow area. */
9830 /* Care for on-stack alignment if needed. */
9834 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
9835 t = fold_convert (sizetype, t);
9836 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
9838 t = fold_convert (TREE_TYPE (ovf), t);
9840 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
9842 gimplify_assign (unshare_expr (addr), t, pre_p);
9844 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9845 gimplify_assign (unshare_expr (ovf), t, pre_p);
9849 stmt = gimple_build_label (lab_over);
9850 gimple_seq_add_stmt (pre_p, stmt);
9853 if (STRICT_ALIGNMENT
9854 && (TYPE_ALIGN (type)
9855 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
9857 /* The value (of type complex double, for example) may not be
9858 aligned in memory in the saved registers, so copy via a
9859 temporary. (This is the same code as used for SPARC.) */
9860 tree tmp = create_tmp_var (type, "va_arg_tmp");
9861 tree dest_addr = build_fold_addr_expr (tmp);
9863 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
9864 3, dest_addr, addr, size_int (rsize * 4));
9866 gimplify_and_add (copy, pre_p);
9870 addr = fold_convert (ptrtype, addr);
9871 return build_va_arg_indirect_ref (addr);
9877 def_builtin (int mask, const char *name, tree type, int code)
9879 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
9882 if (rs6000_builtin_decls[code])
9883 fatal_error ("internal error: builtin function to %s already processed",
9886 rs6000_builtin_decls[code] = t =
9887 add_builtin_function (name, type, code, BUILT_IN_MD,
9890 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT);
9891 switch (builtin_classify[code])
9896 /* assume builtin can do anything. */
9897 case RS6000_BTC_MISC:
9900 /* const function, function only depends on the inputs. */
9901 case RS6000_BTC_CONST:
9902 TREE_READONLY (t) = 1;
9903 TREE_NOTHROW (t) = 1;
9906 /* pure function, function can read global memory. */
9907 case RS6000_BTC_PURE:
9908 DECL_PURE_P (t) = 1;
9909 TREE_NOTHROW (t) = 1;
9912 /* Function is a math function. If rounding mode is on, then treat
9913 the function as not reading global memory, but it can have
9914 arbitrary side effects. If it is off, then assume the function is
9915 a const function. This mimics the ATTR_MATHFN_FPROUNDING
9916 attribute in builtin-attribute.def that is used for the math
9918 case RS6000_BTC_FP_PURE:
9919 TREE_NOTHROW (t) = 1;
9920 if (flag_rounding_math)
9922 DECL_PURE_P (t) = 1;
9923 DECL_IS_NOVOPS (t) = 1;
9926 TREE_READONLY (t) = 1;
9932 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
9934 static const struct builtin_description bdesc_3arg[] =
9936 { MASK_ALTIVEC, CODE_FOR_fmav4sf4, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
9937 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
9938 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
9939 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
9940 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
9941 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
9942 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
9943 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
9944 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
9945 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
9946 { MASK_ALTIVEC, CODE_FOR_nfmsv4sf4, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
9947 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
9948 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
9949 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
9950 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
9951 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
9952 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
9953 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
9954 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
9955 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
9956 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
9957 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
9958 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
9959 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
9960 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
9961 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
9962 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
9963 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
9964 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
9965 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
9966 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
9967 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
9968 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
9969 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
9970 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
9972 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
9973 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
9974 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
9975 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
9976 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
9977 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
9978 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
9979 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
9980 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
9981 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
9982 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
9983 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
9984 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
9985 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
9986 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
9988 { MASK_VSX, CODE_FOR_fmav2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
9989 { MASK_VSX, CODE_FOR_fmsv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
9990 { MASK_VSX, CODE_FOR_nfmav2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
9991 { MASK_VSX, CODE_FOR_nfmsv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
9993 { MASK_VSX, CODE_FOR_fmav4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
9994 { MASK_VSX, CODE_FOR_fmsv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
9995 { MASK_VSX, CODE_FOR_nfmav4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
9996 { MASK_VSX, CODE_FOR_nfmsv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
9998 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
9999 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
10001 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
10002 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
10003 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
10004 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
10005 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
10006 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
10007 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
10008 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
10009 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
10010 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
10012 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
10013 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
10014 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
10015 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
10016 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
10017 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
10018 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
10019 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
10020 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
10021 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
10023 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
10024 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
10025 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
10026 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
10027 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
10028 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
10029 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
10030 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
10031 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
10033 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
10034 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
10035 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
10036 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
10037 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
10038 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
10039 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
10041 { 0, CODE_FOR_fmsv2sf4, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
10042 { 0, CODE_FOR_fmav2sf4, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
10043 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
10044 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
10045 { 0, CODE_FOR_nfmsv2sf4, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
10046 { 0, CODE_FOR_nfmav2sf4, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
10047 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
10048 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
10049 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
10052 /* DST operations: void foo (void *, const int, const char). */
10054 static const struct builtin_description bdesc_dst[] =
10056 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
10057 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
10058 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
10059 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
10061 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
10062 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
10063 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
10064 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
10067 /* Simple binary operations: VECc = foo (VECa, VECb). */
10069 static struct builtin_description bdesc_2arg[] =
10071 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
10072 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
10073 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
10074 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
10075 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
10076 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
10077 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
10078 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
10079 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
10080 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
10081 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
10082 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
10083 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
10084 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
10085 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
10086 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
10087 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
10088 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
10089 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
10090 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
10091 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
10092 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
10093 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
10094 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
10095 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
10096 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
10097 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
10098 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
10099 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
10100 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
10101 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
10102 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
10103 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
10104 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
10105 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
10106 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
10107 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
10108 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
10109 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
10110 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
10111 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
10112 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
10113 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
10114 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
10115 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
10116 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
10117 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
10118 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
10119 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
10120 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
10121 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
10122 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
10123 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
10124 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
10125 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
10126 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
10127 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
10128 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
10129 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
10130 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
10131 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
10132 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
10133 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
10134 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
10135 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
10136 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
10137 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
10138 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
10139 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
10140 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
10141 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
10142 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
10143 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
10144 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
10145 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
10146 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
10147 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
10148 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
10149 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
10150 { MASK_ALTIVEC, CODE_FOR_recipv4sf3, "__builtin_altivec_vrecipdivfp", ALTIVEC_BUILTIN_VRECIPFP },
10151 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
10152 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
10153 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
10154 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
10155 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
10156 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
10157 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
10158 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
10159 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
10160 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
10161 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
10162 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
10163 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
10164 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
10165 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
10166 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
10167 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
10168 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
10169 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
10170 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
10171 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
10172 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
10173 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
10174 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
10175 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
10176 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
10177 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
10178 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
10179 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
10180 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
10181 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
10182 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
10183 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
10184 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
10185 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
10186 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
10187 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
10189 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
10190 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
10191 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
10192 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
10193 { MASK_VSX, CODE_FOR_recipv2df3, "__builtin_vsx_xvrecipdivdp", VSX_BUILTIN_RECIP_V2DF },
10194 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
10195 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
10196 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
10197 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
10198 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
10199 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
10200 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
10202 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
10203 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
10204 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
10205 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
10206 { MASK_VSX, CODE_FOR_recipv4sf3, "__builtin_vsx_xvrecipdivsp", VSX_BUILTIN_RECIP_V4SF },
10207 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
10208 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
10209 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
10210 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
10211 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
10212 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
10213 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
10215 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
10216 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
10217 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
10218 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
10219 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
10220 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
10222 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
10223 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
10224 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
10225 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
10226 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
10227 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
10228 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
10229 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
10230 { MASK_VSX, CODE_FOR_vec_interleave_lowv2df, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF },
10231 { MASK_VSX, CODE_FOR_vec_interleave_lowv2di, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI },
10232 { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF },
10233 { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI },
10235 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
10236 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
10237 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
10238 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
10239 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
10240 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
10241 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
10242 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
10243 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
10244 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
10245 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
10246 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
10247 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
10248 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
10249 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
10250 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
10251 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
10252 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
10253 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
10254 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
10255 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
10256 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
10257 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
10258 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
10259 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
10260 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
10261 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
10262 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
10263 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
10264 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
10265 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
10266 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
10267 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
10268 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
10269 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
10270 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
10271 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
10272 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
10273 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
10274 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
10275 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
10276 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
10277 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
10278 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
10279 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
10280 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
10281 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
10282 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
10283 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
10284 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
10285 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
10286 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
10287 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
10288 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
10289 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
10290 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
10291 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
10292 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
10293 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
10294 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
10295 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
10296 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
10297 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
10298 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
10299 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
10300 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
10301 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
10302 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
10303 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
10304 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
10305 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
10306 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
10307 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
10308 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
10309 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
10310 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
10311 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
10312 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
10313 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
10314 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
10315 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
10316 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
10317 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
10318 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
10319 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
10320 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
10321 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
10322 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
10323 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_recipdiv", ALTIVEC_BUILTIN_VEC_RECIP },
10324 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
10325 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
10326 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
10327 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
10328 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
10329 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
10330 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
10331 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
10332 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
10333 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
10334 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
10335 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
10336 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
10337 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
10338 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
10339 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
10340 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
10341 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
10342 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
10343 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
10344 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
10345 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
10346 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
10347 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
10348 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
10349 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
10350 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
10351 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
10352 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
10353 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
10354 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
10355 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
10356 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
10357 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
10358 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
10359 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
10360 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
10361 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
10362 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
10363 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
10365 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
10366 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
10368 { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
10369 { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
10370 { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
10371 { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
10372 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
10373 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
10374 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
10375 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
10376 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
10377 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
10379 /* Place holder, leave as first spe builtin. */
10380 { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
10381 { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
10382 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
10383 { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
10384 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
10385 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
10386 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
10387 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
10388 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
10389 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
10390 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
10391 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
10392 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
10393 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
10394 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
10395 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
10396 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
10397 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
10398 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
10399 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
10400 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
10401 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
10402 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
10403 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
10404 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
10405 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
10406 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
10407 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
10408 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
10409 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
10410 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
10411 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
10412 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
10413 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
10414 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
10415 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
10416 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
10417 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
10418 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
10419 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
10420 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
10421 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
10422 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
10423 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
10424 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
10425 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
10426 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
10427 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
10428 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
10429 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
10430 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
10431 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
10432 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
10433 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
10434 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
10435 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
10436 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
10437 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
10438 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
10439 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
10440 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
10441 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
10442 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
10443 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
10444 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
10445 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
10446 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
10447 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
10448 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
10449 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
10450 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
10451 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
10452 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
10453 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
10454 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
10455 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
10456 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
10457 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
10458 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
10459 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
10460 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
10461 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
10462 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
10463 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
10464 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
10465 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
10466 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
10467 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
10468 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
10469 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
10470 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
10471 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
10472 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
10473 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
10474 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
10475 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
10476 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
10477 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
10478 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
10479 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
10480 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
10481 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
10482 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
10483 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
10484 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
10485 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
10486 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
10487 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
10488 { 0, CODE_FOR_subv2si3, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
10490 /* SPE binary operations expecting a 5-bit unsigned literal. */
10491 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
10493 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
10494 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
10495 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
10496 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
10497 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
10498 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
10499 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
10500 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
10501 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
10502 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
10503 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
10504 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
10505 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
10506 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
10507 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
10508 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
10509 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
10510 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
10511 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
10512 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
10513 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
10514 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
10515 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
10516 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
10517 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
10518 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
10520 /* Place-holder. Leave as last binary SPE builtin. */
10521 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
10524 /* AltiVec predicates. */
10526 struct builtin_description_predicates
10528 const unsigned int mask;
10529 const enum insn_code icode;
10530 const char *const name;
10531 const enum rs6000_builtins code;
10534 static const struct builtin_description_predicates bdesc_altivec_preds[] =
10536 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
10537 ALTIVEC_BUILTIN_VCMPBFP_P },
10538 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
10539 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
10540 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
10541 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
10542 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
10543 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
10544 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
10545 ALTIVEC_BUILTIN_VCMPEQUW_P },
10546 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
10547 ALTIVEC_BUILTIN_VCMPGTSW_P },
10548 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
10549 ALTIVEC_BUILTIN_VCMPGTUW_P },
10550 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
10551 ALTIVEC_BUILTIN_VCMPEQUH_P },
10552 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
10553 ALTIVEC_BUILTIN_VCMPGTSH_P },
10554 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
10555 ALTIVEC_BUILTIN_VCMPGTUH_P },
10556 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
10557 ALTIVEC_BUILTIN_VCMPEQUB_P },
10558 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
10559 ALTIVEC_BUILTIN_VCMPGTSB_P },
10560 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
10561 ALTIVEC_BUILTIN_VCMPGTUB_P },
10563 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
10564 VSX_BUILTIN_XVCMPEQSP_P },
10565 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
10566 VSX_BUILTIN_XVCMPGESP_P },
10567 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
10568 VSX_BUILTIN_XVCMPGTSP_P },
10569 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
10570 VSX_BUILTIN_XVCMPEQDP_P },
10571 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
10572 VSX_BUILTIN_XVCMPGEDP_P },
10573 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
10574 VSX_BUILTIN_XVCMPGTDP_P },
10576 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
10577 ALTIVEC_BUILTIN_VCMPEQ_P },
10578 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
10579 ALTIVEC_BUILTIN_VCMPGT_P },
10580 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
10581 ALTIVEC_BUILTIN_VCMPGE_P }
10584 /* SPE predicates. */
10585 static struct builtin_description bdesc_spe_predicates[] =
10587 /* Place-holder. Leave as first. */
10588 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
10589 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
10590 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
10591 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
10592 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
10593 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
10594 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
10595 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
10596 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
10597 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
10598 /* Place-holder. Leave as last. */
10599 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
10602 /* SPE evsel predicates. */
10603 static struct builtin_description bdesc_spe_evsel[] =
10605 /* Place-holder. Leave as first. */
10606 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
10607 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
10608 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
10609 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
10610 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
10611 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
10612 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
10613 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
10614 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
10615 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
10616 /* Place-holder. Leave as last. */
10617 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
10620 /* PAIRED predicates. */
10621 static const struct builtin_description bdesc_paired_preds[] =
10623 /* Place-holder. Leave as first. */
10624 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
10625 /* Place-holder. Leave as last. */
10626 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
10629 /* ABS* operations. */
10631 static const struct builtin_description bdesc_abs[] =
10633 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
10634 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
10635 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
10636 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
10637 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
10638 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
10639 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
10640 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
10641 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
10642 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
10643 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
10646 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
10649 static struct builtin_description bdesc_1arg[] =
10651 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
10652 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
10653 { MASK_ALTIVEC, CODE_FOR_rev4sf2, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
10654 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
10655 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
10656 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
10657 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
10658 { MASK_ALTIVEC, CODE_FOR_rsqrtv4sf2, "__builtin_altivec_vrsqrtfp", ALTIVEC_BUILTIN_VRSQRTFP },
10659 { MASK_ALTIVEC, CODE_FOR_rsqrtev4sf2, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
10660 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
10661 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
10662 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
10663 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
10664 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
10665 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
10666 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
10667 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
10668 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
10670 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
10671 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
10672 { MASK_VSX, CODE_FOR_rsqrtv2df2, "__builtin_vsx_xvrsqrtdp", VSX_BUILTIN_VEC_RSQRT_V2DF },
10673 { MASK_VSX, CODE_FOR_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
10674 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
10675 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
10676 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
10678 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
10679 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
10680 { MASK_VSX, CODE_FOR_rsqrtv4sf2, "__builtin_vsx_xvrsqrtsp", VSX_BUILTIN_VEC_RSQRT_V4SF },
10681 { MASK_VSX, CODE_FOR_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
10682 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
10683 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
10684 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
10686 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
10687 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
10688 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
10689 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
10690 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
10691 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
10693 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
10694 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
10695 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
10696 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
10697 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
10698 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
10700 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
10701 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
10702 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
10703 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
10705 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
10706 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
10707 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
10708 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
10709 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
10710 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
10711 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
10712 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
10713 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
10715 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
10716 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
10717 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
10718 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
10719 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
10720 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
10721 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
10722 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
10723 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
10725 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
10726 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
10727 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
10728 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
10729 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
10731 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
10732 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
10733 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
10734 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
10735 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
10736 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
10737 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
10738 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
10739 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
10740 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrt", ALTIVEC_BUILTIN_VEC_RSQRT },
10741 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
10742 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
10743 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
10744 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
10745 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
10746 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
10747 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
10748 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
10749 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
10750 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
10752 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
10753 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
10754 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
10756 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
10757 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
10758 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
10759 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
10761 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
10762 end with SPE_BUILTIN_EVSUBFUSIAAW. */
10763 { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
10764 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
10765 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
10766 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
10767 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
10768 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
10769 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
10770 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
10771 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
10772 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
10773 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
10774 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
10775 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
10776 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
10777 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
10778 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
10779 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
10780 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
10781 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
10782 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
10783 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
10784 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
10785 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
10786 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
10787 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
10788 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
10789 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
10790 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
10792 /* Place-holder. Leave as last unary SPE builtin. */
10793 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
10795 { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
10796 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
10797 { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
10798 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
10799 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
10803 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
10806 tree arg0 = CALL_EXPR_ARG (exp, 0);
10807 rtx op0 = expand_normal (arg0);
10808 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10809 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10811 if (icode == CODE_FOR_nothing)
10812 /* Builtin not supported on this processor. */
10815 /* If we got invalid arguments bail out before generating bad rtl. */
10816 if (arg0 == error_mark_node)
10819 if (icode == CODE_FOR_altivec_vspltisb
10820 || icode == CODE_FOR_altivec_vspltish
10821 || icode == CODE_FOR_altivec_vspltisw
10822 || icode == CODE_FOR_spe_evsplatfi
10823 || icode == CODE_FOR_spe_evsplati)
10825 /* Only allow 5-bit *signed* literals. */
10826 if (GET_CODE (op0) != CONST_INT
10827 || INTVAL (op0) > 15
10828 || INTVAL (op0) < -16)
10830 error ("argument 1 must be a 5-bit signed literal");
10836 || GET_MODE (target) != tmode
10837 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10838 target = gen_reg_rtx (tmode);
10840 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10841 op0 = copy_to_mode_reg (mode0, op0);
10843 pat = GEN_FCN (icode) (target, op0);
10852 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
10854 rtx pat, scratch1, scratch2;
10855 tree arg0 = CALL_EXPR_ARG (exp, 0);
10856 rtx op0 = expand_normal (arg0);
10857 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10858 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10860 /* If we have invalid arguments, bail out before generating bad rtl. */
10861 if (arg0 == error_mark_node)
10865 || GET_MODE (target) != tmode
10866 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10867 target = gen_reg_rtx (tmode);
10869 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10870 op0 = copy_to_mode_reg (mode0, op0);
10872 scratch1 = gen_reg_rtx (mode0);
10873 scratch2 = gen_reg_rtx (mode0);
10875 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
10884 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
10887 tree arg0 = CALL_EXPR_ARG (exp, 0);
10888 tree arg1 = CALL_EXPR_ARG (exp, 1);
10889 rtx op0 = expand_normal (arg0);
10890 rtx op1 = expand_normal (arg1);
10891 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10892 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10893 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10895 if (icode == CODE_FOR_nothing)
10896 /* Builtin not supported on this processor. */
10899 /* If we got invalid arguments bail out before generating bad rtl. */
10900 if (arg0 == error_mark_node || arg1 == error_mark_node)
10903 if (icode == CODE_FOR_altivec_vcfux
10904 || icode == CODE_FOR_altivec_vcfsx
10905 || icode == CODE_FOR_altivec_vctsxs
10906 || icode == CODE_FOR_altivec_vctuxs
10907 || icode == CODE_FOR_altivec_vspltb
10908 || icode == CODE_FOR_altivec_vsplth
10909 || icode == CODE_FOR_altivec_vspltw
10910 || icode == CODE_FOR_spe_evaddiw
10911 || icode == CODE_FOR_spe_evldd
10912 || icode == CODE_FOR_spe_evldh
10913 || icode == CODE_FOR_spe_evldw
10914 || icode == CODE_FOR_spe_evlhhesplat
10915 || icode == CODE_FOR_spe_evlhhossplat
10916 || icode == CODE_FOR_spe_evlhhousplat
10917 || icode == CODE_FOR_spe_evlwhe
10918 || icode == CODE_FOR_spe_evlwhos
10919 || icode == CODE_FOR_spe_evlwhou
10920 || icode == CODE_FOR_spe_evlwhsplat
10921 || icode == CODE_FOR_spe_evlwwsplat
10922 || icode == CODE_FOR_spe_evrlwi
10923 || icode == CODE_FOR_spe_evslwi
10924 || icode == CODE_FOR_spe_evsrwis
10925 || icode == CODE_FOR_spe_evsubifw
10926 || icode == CODE_FOR_spe_evsrwiu)
10928 /* Only allow 5-bit unsigned literals. */
10930 if (TREE_CODE (arg1) != INTEGER_CST
10931 || TREE_INT_CST_LOW (arg1) & ~0x1f)
10933 error ("argument 2 must be a 5-bit unsigned literal");
10939 || GET_MODE (target) != tmode
10940 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10941 target = gen_reg_rtx (tmode);
10943 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10944 op0 = copy_to_mode_reg (mode0, op0);
10945 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10946 op1 = copy_to_mode_reg (mode1, op1);
10948 pat = GEN_FCN (icode) (target, op0, op1);
10957 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10960 tree cr6_form = CALL_EXPR_ARG (exp, 0);
10961 tree arg0 = CALL_EXPR_ARG (exp, 1);
10962 tree arg1 = CALL_EXPR_ARG (exp, 2);
10963 rtx op0 = expand_normal (arg0);
10964 rtx op1 = expand_normal (arg1);
10965 enum machine_mode tmode = SImode;
10966 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10967 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10970 if (TREE_CODE (cr6_form) != INTEGER_CST)
10972 error ("argument 1 of __builtin_altivec_predicate must be a constant");
10976 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
10978 gcc_assert (mode0 == mode1);
10980 /* If we have invalid arguments, bail out before generating bad rtl. */
10981 if (arg0 == error_mark_node || arg1 == error_mark_node)
10985 || GET_MODE (target) != tmode
10986 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10987 target = gen_reg_rtx (tmode);
10989 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10990 op0 = copy_to_mode_reg (mode0, op0);
10991 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10992 op1 = copy_to_mode_reg (mode1, op1);
10994 scratch = gen_reg_rtx (mode0);
10996 pat = GEN_FCN (icode) (scratch, op0, op1);
11001 /* The vec_any* and vec_all* predicates use the same opcodes for two
11002 different operations, but the bits in CR6 will be different
11003 depending on what information we want. So we have to play tricks
11004 with CR6 to get the right bits out.
11006 If you think this is disgusting, look at the specs for the
11007 AltiVec predicates. */
11009 switch (cr6_form_int)
11012 emit_insn (gen_cr6_test_for_zero (target));
11015 emit_insn (gen_cr6_test_for_zero_reverse (target));
11018 emit_insn (gen_cr6_test_for_lt (target));
11021 emit_insn (gen_cr6_test_for_lt_reverse (target));
11024 error ("argument 1 of __builtin_altivec_predicate is out of range");
11032 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
11035 tree arg0 = CALL_EXPR_ARG (exp, 0);
11036 tree arg1 = CALL_EXPR_ARG (exp, 1);
11037 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11038 enum machine_mode mode0 = Pmode;
11039 enum machine_mode mode1 = Pmode;
11040 rtx op0 = expand_normal (arg0);
11041 rtx op1 = expand_normal (arg1);
11043 if (icode == CODE_FOR_nothing)
11044 /* Builtin not supported on this processor. */
11047 /* If we got invalid arguments bail out before generating bad rtl. */
11048 if (arg0 == error_mark_node || arg1 == error_mark_node)
11052 || GET_MODE (target) != tmode
11053 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11054 target = gen_reg_rtx (tmode);
11056 op1 = copy_to_mode_reg (mode1, op1);
11058 if (op0 == const0_rtx)
11060 addr = gen_rtx_MEM (tmode, op1);
11064 op0 = copy_to_mode_reg (mode0, op0);
11065 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
11068 pat = GEN_FCN (icode) (target, addr);
11078 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
11081 tree arg0 = CALL_EXPR_ARG (exp, 0);
11082 tree arg1 = CALL_EXPR_ARG (exp, 1);
11083 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11084 enum machine_mode mode0 = Pmode;
11085 enum machine_mode mode1 = Pmode;
11086 rtx op0 = expand_normal (arg0);
11087 rtx op1 = expand_normal (arg1);
11089 if (icode == CODE_FOR_nothing)
11090 /* Builtin not supported on this processor. */
11093 /* If we got invalid arguments bail out before generating bad rtl. */
11094 if (arg0 == error_mark_node || arg1 == error_mark_node)
11098 || GET_MODE (target) != tmode
11099 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11100 target = gen_reg_rtx (tmode);
11102 op1 = copy_to_mode_reg (mode1, op1);
11104 if (op0 == const0_rtx)
11106 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
11110 op0 = copy_to_mode_reg (mode0, op0);
11111 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
11114 pat = GEN_FCN (icode) (target, addr);
11124 spe_expand_stv_builtin (enum insn_code icode, tree exp)
11126 tree arg0 = CALL_EXPR_ARG (exp, 0);
11127 tree arg1 = CALL_EXPR_ARG (exp, 1);
11128 tree arg2 = CALL_EXPR_ARG (exp, 2);
11129 rtx op0 = expand_normal (arg0);
11130 rtx op1 = expand_normal (arg1);
11131 rtx op2 = expand_normal (arg2);
11133 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
11134 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
11135 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
11137 /* Invalid arguments. Bail before doing anything stoopid! */
11138 if (arg0 == error_mark_node
11139 || arg1 == error_mark_node
11140 || arg2 == error_mark_node)
11143 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
11144 op0 = copy_to_mode_reg (mode2, op0);
11145 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
11146 op1 = copy_to_mode_reg (mode0, op1);
11147 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
11148 op2 = copy_to_mode_reg (mode1, op2);
11150 pat = GEN_FCN (icode) (op1, op2, op0);
11157 paired_expand_stv_builtin (enum insn_code icode, tree exp)
11159 tree arg0 = CALL_EXPR_ARG (exp, 0);
11160 tree arg1 = CALL_EXPR_ARG (exp, 1);
11161 tree arg2 = CALL_EXPR_ARG (exp, 2);
11162 rtx op0 = expand_normal (arg0);
11163 rtx op1 = expand_normal (arg1);
11164 rtx op2 = expand_normal (arg2);
11166 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11167 enum machine_mode mode1 = Pmode;
11168 enum machine_mode mode2 = Pmode;
11170 /* Invalid arguments. Bail before doing anything stoopid! */
11171 if (arg0 == error_mark_node
11172 || arg1 == error_mark_node
11173 || arg2 == error_mark_node)
11176 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
11177 op0 = copy_to_mode_reg (tmode, op0);
11179 op2 = copy_to_mode_reg (mode2, op2);
11181 if (op1 == const0_rtx)
11183 addr = gen_rtx_MEM (tmode, op2);
11187 op1 = copy_to_mode_reg (mode1, op1);
11188 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
11191 pat = GEN_FCN (icode) (addr, op0);
11198 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
11200 tree arg0 = CALL_EXPR_ARG (exp, 0);
11201 tree arg1 = CALL_EXPR_ARG (exp, 1);
11202 tree arg2 = CALL_EXPR_ARG (exp, 2);
11203 rtx op0 = expand_normal (arg0);
11204 rtx op1 = expand_normal (arg1);
11205 rtx op2 = expand_normal (arg2);
11207 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11208 enum machine_mode smode = insn_data[icode].operand[1].mode;
11209 enum machine_mode mode1 = Pmode;
11210 enum machine_mode mode2 = Pmode;
11212 /* Invalid arguments. Bail before doing anything stoopid! */
11213 if (arg0 == error_mark_node
11214 || arg1 == error_mark_node
11215 || arg2 == error_mark_node)
11218 if (! (*insn_data[icode].operand[1].predicate) (op0, smode))
11219 op0 = copy_to_mode_reg (smode, op0);
11221 op2 = copy_to_mode_reg (mode2, op2);
11223 if (op1 == const0_rtx)
11225 addr = gen_rtx_MEM (tmode, op2);
11229 op1 = copy_to_mode_reg (mode1, op1);
11230 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
11233 pat = GEN_FCN (icode) (addr, op0);
11240 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
11243 tree arg0 = CALL_EXPR_ARG (exp, 0);
11244 tree arg1 = CALL_EXPR_ARG (exp, 1);
11245 tree arg2 = CALL_EXPR_ARG (exp, 2);
11246 rtx op0 = expand_normal (arg0);
11247 rtx op1 = expand_normal (arg1);
11248 rtx op2 = expand_normal (arg2);
11249 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11250 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11251 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11252 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
11254 if (icode == CODE_FOR_nothing)
11255 /* Builtin not supported on this processor. */
11258 /* If we got invalid arguments bail out before generating bad rtl. */
11259 if (arg0 == error_mark_node
11260 || arg1 == error_mark_node
11261 || arg2 == error_mark_node)
11264 /* Check and prepare argument depending on the instruction code.
11266 Note that a switch statement instead of the sequence of tests
11267 would be incorrect as many of the CODE_FOR values could be
11268 CODE_FOR_nothing and that would yield multiple alternatives
11269 with identical values. We'd never reach here at runtime in
11271 if (icode == CODE_FOR_altivec_vsldoi_v4sf
11272 || icode == CODE_FOR_altivec_vsldoi_v4si
11273 || icode == CODE_FOR_altivec_vsldoi_v8hi
11274 || icode == CODE_FOR_altivec_vsldoi_v16qi)
11276 /* Only allow 4-bit unsigned literals. */
11278 if (TREE_CODE (arg2) != INTEGER_CST
11279 || TREE_INT_CST_LOW (arg2) & ~0xf)
11281 error ("argument 3 must be a 4-bit unsigned literal");
11285 else if (icode == CODE_FOR_vsx_xxpermdi_v2df
11286 || icode == CODE_FOR_vsx_xxpermdi_v2di
11287 || icode == CODE_FOR_vsx_xxsldwi_v16qi
11288 || icode == CODE_FOR_vsx_xxsldwi_v8hi
11289 || icode == CODE_FOR_vsx_xxsldwi_v4si
11290 || icode == CODE_FOR_vsx_xxsldwi_v4sf
11291 || icode == CODE_FOR_vsx_xxsldwi_v2di
11292 || icode == CODE_FOR_vsx_xxsldwi_v2df)
11294 /* Only allow 2-bit unsigned literals. */
11296 if (TREE_CODE (arg2) != INTEGER_CST
11297 || TREE_INT_CST_LOW (arg2) & ~0x3)
11299 error ("argument 3 must be a 2-bit unsigned literal");
11303 else if (icode == CODE_FOR_vsx_set_v2df
11304 || icode == CODE_FOR_vsx_set_v2di)
11306 /* Only allow 1-bit unsigned literals. */
11308 if (TREE_CODE (arg2) != INTEGER_CST
11309 || TREE_INT_CST_LOW (arg2) & ~0x1)
11311 error ("argument 3 must be a 1-bit unsigned literal");
11317 || GET_MODE (target) != tmode
11318 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11319 target = gen_reg_rtx (tmode);
11321 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11322 op0 = copy_to_mode_reg (mode0, op0);
11323 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11324 op1 = copy_to_mode_reg (mode1, op1);
11325 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
11326 op2 = copy_to_mode_reg (mode2, op2);
11328 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
11329 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
11331 pat = GEN_FCN (icode) (target, op0, op1, op2);
11339 /* Expand the lvx builtins. */
11341 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
11343 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11344 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11346 enum machine_mode tmode, mode0;
11348 enum insn_code icode;
11352 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
11353 icode = CODE_FOR_vector_altivec_load_v16qi;
11355 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
11356 icode = CODE_FOR_vector_altivec_load_v8hi;
11358 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
11359 icode = CODE_FOR_vector_altivec_load_v4si;
11361 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
11362 icode = CODE_FOR_vector_altivec_load_v4sf;
11364 case ALTIVEC_BUILTIN_LD_INTERNAL_2df:
11365 icode = CODE_FOR_vector_altivec_load_v2df;
11367 case ALTIVEC_BUILTIN_LD_INTERNAL_2di:
11368 icode = CODE_FOR_vector_altivec_load_v2di;
11371 *expandedp = false;
11377 arg0 = CALL_EXPR_ARG (exp, 0);
11378 op0 = expand_normal (arg0);
11379 tmode = insn_data[icode].operand[0].mode;
11380 mode0 = insn_data[icode].operand[1].mode;
11383 || GET_MODE (target) != tmode
11384 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11385 target = gen_reg_rtx (tmode);
11387 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11388 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11390 pat = GEN_FCN (icode) (target, op0);
11397 /* Expand the stvx builtins. */
11399 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
11402 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11403 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11405 enum machine_mode mode0, mode1;
11407 enum insn_code icode;
11411 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
11412 icode = CODE_FOR_vector_altivec_store_v16qi;
11414 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
11415 icode = CODE_FOR_vector_altivec_store_v8hi;
11417 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
11418 icode = CODE_FOR_vector_altivec_store_v4si;
11420 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
11421 icode = CODE_FOR_vector_altivec_store_v4sf;
11423 case ALTIVEC_BUILTIN_ST_INTERNAL_2df:
11424 icode = CODE_FOR_vector_altivec_store_v2df;
11426 case ALTIVEC_BUILTIN_ST_INTERNAL_2di:
11427 icode = CODE_FOR_vector_altivec_store_v2di;
11430 *expandedp = false;
11434 arg0 = CALL_EXPR_ARG (exp, 0);
11435 arg1 = CALL_EXPR_ARG (exp, 1);
11436 op0 = expand_normal (arg0);
11437 op1 = expand_normal (arg1);
11438 mode0 = insn_data[icode].operand[0].mode;
11439 mode1 = insn_data[icode].operand[1].mode;
11441 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11442 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11443 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11444 op1 = copy_to_mode_reg (mode1, op1);
11446 pat = GEN_FCN (icode) (op0, op1);
11454 /* Expand the dst builtins. */
11456 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
11459 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11460 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11461 tree arg0, arg1, arg2;
11462 enum machine_mode mode0, mode1;
11463 rtx pat, op0, op1, op2;
11464 const struct builtin_description *d;
11467 *expandedp = false;
11469 /* Handle DST variants. */
11471 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
11472 if (d->code == fcode)
11474 arg0 = CALL_EXPR_ARG (exp, 0);
11475 arg1 = CALL_EXPR_ARG (exp, 1);
11476 arg2 = CALL_EXPR_ARG (exp, 2);
11477 op0 = expand_normal (arg0);
11478 op1 = expand_normal (arg1);
11479 op2 = expand_normal (arg2);
11480 mode0 = insn_data[d->icode].operand[0].mode;
11481 mode1 = insn_data[d->icode].operand[1].mode;
11483 /* Invalid arguments, bail out before generating bad rtl. */
11484 if (arg0 == error_mark_node
11485 || arg1 == error_mark_node
11486 || arg2 == error_mark_node)
11491 if (TREE_CODE (arg2) != INTEGER_CST
11492 || TREE_INT_CST_LOW (arg2) & ~0x3)
11494 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
11498 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
11499 op0 = copy_to_mode_reg (Pmode, op0);
11500 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
11501 op1 = copy_to_mode_reg (mode1, op1);
11503 pat = GEN_FCN (d->icode) (op0, op1, op2);
11513 /* Expand vec_init builtin. */
11515 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
11517 enum machine_mode tmode = TYPE_MODE (type);
11518 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
11519 int i, n_elt = GET_MODE_NUNITS (tmode);
11520 rtvec v = rtvec_alloc (n_elt);
11522 gcc_assert (VECTOR_MODE_P (tmode));
11523 gcc_assert (n_elt == call_expr_nargs (exp));
11525 for (i = 0; i < n_elt; ++i)
11527 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
11528 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
11531 if (!target || !register_operand (target, tmode))
11532 target = gen_reg_rtx (tmode);
11534 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
11538 /* Return the integer constant in ARG. Constrain it to be in the range
11539 of the subparts of VEC_TYPE; issue an error if not. */
11542 get_element_number (tree vec_type, tree arg)
11544 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
11546 if (!host_integerp (arg, 1)
11547 || (elt = tree_low_cst (arg, 1), elt > max))
11549 error ("selector must be an integer constant in the range 0..%wi", max);
11556 /* Expand vec_set builtin. */
11558 altivec_expand_vec_set_builtin (tree exp)
11560 enum machine_mode tmode, mode1;
11561 tree arg0, arg1, arg2;
11565 arg0 = CALL_EXPR_ARG (exp, 0);
11566 arg1 = CALL_EXPR_ARG (exp, 1);
11567 arg2 = CALL_EXPR_ARG (exp, 2);
11569 tmode = TYPE_MODE (TREE_TYPE (arg0));
11570 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11571 gcc_assert (VECTOR_MODE_P (tmode));
11573 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
11574 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
11575 elt = get_element_number (TREE_TYPE (arg0), arg2);
11577 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
11578 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
11580 op0 = force_reg (tmode, op0);
11581 op1 = force_reg (mode1, op1);
11583 rs6000_expand_vector_set (op0, op1, elt);
11588 /* Expand vec_ext builtin. */
11590 altivec_expand_vec_ext_builtin (tree exp, rtx target)
11592 enum machine_mode tmode, mode0;
11597 arg0 = CALL_EXPR_ARG (exp, 0);
11598 arg1 = CALL_EXPR_ARG (exp, 1);
11600 op0 = expand_normal (arg0);
11601 elt = get_element_number (TREE_TYPE (arg0), arg1);
11603 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11604 mode0 = TYPE_MODE (TREE_TYPE (arg0));
11605 gcc_assert (VECTOR_MODE_P (mode0));
11607 op0 = force_reg (mode0, op0);
11609 if (optimize || !target || !register_operand (target, tmode))
11610 target = gen_reg_rtx (tmode);
11612 rs6000_expand_vector_extract (target, op0, elt);
11617 /* Expand the builtin in EXP and store the result in TARGET. Store
11618 true in *EXPANDEDP if we found a builtin to expand. */
11620 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
11622 const struct builtin_description *d;
11623 const struct builtin_description_predicates *dp;
11625 enum insn_code icode;
11626 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11629 enum machine_mode tmode, mode0;
11630 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11632 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11633 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11634 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
11635 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
11638 error ("unresolved overload for Altivec builtin %qF", fndecl);
11642 target = altivec_expand_ld_builtin (exp, target, expandedp);
11646 target = altivec_expand_st_builtin (exp, target, expandedp);
11650 target = altivec_expand_dst_builtin (exp, target, expandedp);
11658 case ALTIVEC_BUILTIN_STVX:
11659 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v4si, exp);
11660 case ALTIVEC_BUILTIN_STVEBX:
11661 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
11662 case ALTIVEC_BUILTIN_STVEHX:
11663 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
11664 case ALTIVEC_BUILTIN_STVEWX:
11665 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
11666 case ALTIVEC_BUILTIN_STVXL:
11667 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
11669 case ALTIVEC_BUILTIN_STVLX:
11670 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
11671 case ALTIVEC_BUILTIN_STVLXL:
11672 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
11673 case ALTIVEC_BUILTIN_STVRX:
11674 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
11675 case ALTIVEC_BUILTIN_STVRXL:
11676 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
11678 case VSX_BUILTIN_STXVD2X_V2DF:
11679 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2df, exp);
11680 case VSX_BUILTIN_STXVD2X_V2DI:
11681 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2di, exp);
11682 case VSX_BUILTIN_STXVW4X_V4SF:
11683 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4sf, exp);
11684 case VSX_BUILTIN_STXVW4X_V4SI:
11685 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4si, exp);
11686 case VSX_BUILTIN_STXVW4X_V8HI:
11687 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v8hi, exp);
11688 case VSX_BUILTIN_STXVW4X_V16QI:
11689 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v16qi, exp);
11691 case ALTIVEC_BUILTIN_MFVSCR:
11692 icode = CODE_FOR_altivec_mfvscr;
11693 tmode = insn_data[icode].operand[0].mode;
11696 || GET_MODE (target) != tmode
11697 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11698 target = gen_reg_rtx (tmode);
11700 pat = GEN_FCN (icode) (target);
11706 case ALTIVEC_BUILTIN_MTVSCR:
11707 icode = CODE_FOR_altivec_mtvscr;
11708 arg0 = CALL_EXPR_ARG (exp, 0);
11709 op0 = expand_normal (arg0);
11710 mode0 = insn_data[icode].operand[0].mode;
11712 /* If we got invalid arguments bail out before generating bad rtl. */
11713 if (arg0 == error_mark_node)
11716 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11717 op0 = copy_to_mode_reg (mode0, op0);
11719 pat = GEN_FCN (icode) (op0);
11724 case ALTIVEC_BUILTIN_DSSALL:
11725 emit_insn (gen_altivec_dssall ());
11728 case ALTIVEC_BUILTIN_DSS:
11729 icode = CODE_FOR_altivec_dss;
11730 arg0 = CALL_EXPR_ARG (exp, 0);
11732 op0 = expand_normal (arg0);
11733 mode0 = insn_data[icode].operand[0].mode;
11735 /* If we got invalid arguments bail out before generating bad rtl. */
11736 if (arg0 == error_mark_node)
11739 if (TREE_CODE (arg0) != INTEGER_CST
11740 || TREE_INT_CST_LOW (arg0) & ~0x3)
11742 error ("argument to dss must be a 2-bit unsigned literal");
11746 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11747 op0 = copy_to_mode_reg (mode0, op0);
11749 emit_insn (gen_altivec_dss (op0));
11752 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
11753 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
11754 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
11755 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
11756 case VSX_BUILTIN_VEC_INIT_V2DF:
11757 case VSX_BUILTIN_VEC_INIT_V2DI:
11758 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
11760 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
11761 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
11762 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
11763 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
11764 case VSX_BUILTIN_VEC_SET_V2DF:
11765 case VSX_BUILTIN_VEC_SET_V2DI:
11766 return altivec_expand_vec_set_builtin (exp);
11768 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
11769 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
11770 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
11771 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
11772 case VSX_BUILTIN_VEC_EXT_V2DF:
11773 case VSX_BUILTIN_VEC_EXT_V2DI:
11774 return altivec_expand_vec_ext_builtin (exp, target);
11778 /* Fall through. */
11781 /* Expand abs* operations. */
11783 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11784 if (d->code == fcode)
11785 return altivec_expand_abs_builtin (d->icode, exp, target);
11787 /* Expand the AltiVec predicates. */
11788 dp = bdesc_altivec_preds;
11789 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11790 if (dp->code == fcode)
11791 return altivec_expand_predicate_builtin (dp->icode, exp, target);
11793 /* LV* are funky. We initialized them differently. */
11796 case ALTIVEC_BUILTIN_LVSL:
11797 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
11798 exp, target, false);
11799 case ALTIVEC_BUILTIN_LVSR:
11800 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
11801 exp, target, false);
11802 case ALTIVEC_BUILTIN_LVEBX:
11803 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
11804 exp, target, false);
11805 case ALTIVEC_BUILTIN_LVEHX:
11806 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
11807 exp, target, false);
11808 case ALTIVEC_BUILTIN_LVEWX:
11809 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
11810 exp, target, false);
11811 case ALTIVEC_BUILTIN_LVXL:
11812 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
11813 exp, target, false);
11814 case ALTIVEC_BUILTIN_LVX:
11815 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v4si,
11816 exp, target, false);
11817 case ALTIVEC_BUILTIN_LVLX:
11818 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
11819 exp, target, true);
11820 case ALTIVEC_BUILTIN_LVLXL:
11821 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
11822 exp, target, true);
11823 case ALTIVEC_BUILTIN_LVRX:
11824 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
11825 exp, target, true);
11826 case ALTIVEC_BUILTIN_LVRXL:
11827 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
11828 exp, target, true);
11829 case VSX_BUILTIN_LXVD2X_V2DF:
11830 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2df,
11831 exp, target, false);
11832 case VSX_BUILTIN_LXVD2X_V2DI:
11833 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2di,
11834 exp, target, false);
11835 case VSX_BUILTIN_LXVW4X_V4SF:
11836 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4sf,
11837 exp, target, false);
11838 case VSX_BUILTIN_LXVW4X_V4SI:
11839 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4si,
11840 exp, target, false);
11841 case VSX_BUILTIN_LXVW4X_V8HI:
11842 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v8hi,
11843 exp, target, false);
11844 case VSX_BUILTIN_LXVW4X_V16QI:
11845 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v16qi,
11846 exp, target, false);
11850 /* Fall through. */
11853 *expandedp = false;
11857 /* Expand the builtin in EXP and store the result in TARGET. Store
11858 true in *EXPANDEDP if we found a builtin to expand. */
11860 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
11862 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11863 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11864 const struct builtin_description *d;
11871 case PAIRED_BUILTIN_STX:
11872 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
11873 case PAIRED_BUILTIN_LX:
11874 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
11877 /* Fall through. */
11880 /* Expand the paired predicates. */
11881 d = bdesc_paired_preds;
11882 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
11883 if (d->code == fcode)
11884 return paired_expand_predicate_builtin (d->icode, exp, target);
11886 *expandedp = false;
11890 /* Binops that need to be initialized manually, but can be expanded
11891 automagically by rs6000_expand_binop_builtin. */
11892 static struct builtin_description bdesc_2arg_spe[] =
11894 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
11895 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
11896 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
11897 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
11898 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
11899 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
11900 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
11901 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
11902 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
11903 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
11904 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
11905 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
11906 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
11907 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
11908 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
11909 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
11910 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
11911 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
11912 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
11913 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
11914 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
11915 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
11918 /* Expand the builtin in EXP and store the result in TARGET. Store
11919 true in *EXPANDEDP if we found a builtin to expand.
11921 This expands the SPE builtins that are not simple unary and binary
11924 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
11926 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11928 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11929 enum insn_code icode;
11930 enum machine_mode tmode, mode0;
11932 struct builtin_description *d;
11937 /* Syntax check for a 5-bit unsigned immediate. */
11940 case SPE_BUILTIN_EVSTDD:
11941 case SPE_BUILTIN_EVSTDH:
11942 case SPE_BUILTIN_EVSTDW:
11943 case SPE_BUILTIN_EVSTWHE:
11944 case SPE_BUILTIN_EVSTWHO:
11945 case SPE_BUILTIN_EVSTWWE:
11946 case SPE_BUILTIN_EVSTWWO:
11947 arg1 = CALL_EXPR_ARG (exp, 2);
11948 if (TREE_CODE (arg1) != INTEGER_CST
11949 || TREE_INT_CST_LOW (arg1) & ~0x1f)
11951 error ("argument 2 must be a 5-bit unsigned literal");
11959 /* The evsplat*i instructions are not quite generic. */
11962 case SPE_BUILTIN_EVSPLATFI:
11963 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
11965 case SPE_BUILTIN_EVSPLATI:
11966 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
11972 d = (struct builtin_description *) bdesc_2arg_spe;
11973 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
11974 if (d->code == fcode)
11975 return rs6000_expand_binop_builtin (d->icode, exp, target);
11977 d = (struct builtin_description *) bdesc_spe_predicates;
11978 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
11979 if (d->code == fcode)
11980 return spe_expand_predicate_builtin (d->icode, exp, target);
11982 d = (struct builtin_description *) bdesc_spe_evsel;
11983 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
11984 if (d->code == fcode)
11985 return spe_expand_evsel_builtin (d->icode, exp, target);
11989 case SPE_BUILTIN_EVSTDDX:
11990 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
11991 case SPE_BUILTIN_EVSTDHX:
11992 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
11993 case SPE_BUILTIN_EVSTDWX:
11994 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
11995 case SPE_BUILTIN_EVSTWHEX:
11996 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
11997 case SPE_BUILTIN_EVSTWHOX:
11998 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
11999 case SPE_BUILTIN_EVSTWWEX:
12000 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
12001 case SPE_BUILTIN_EVSTWWOX:
12002 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
12003 case SPE_BUILTIN_EVSTDD:
12004 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
12005 case SPE_BUILTIN_EVSTDH:
12006 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
12007 case SPE_BUILTIN_EVSTDW:
12008 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
12009 case SPE_BUILTIN_EVSTWHE:
12010 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
12011 case SPE_BUILTIN_EVSTWHO:
12012 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
12013 case SPE_BUILTIN_EVSTWWE:
12014 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
12015 case SPE_BUILTIN_EVSTWWO:
12016 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
12017 case SPE_BUILTIN_MFSPEFSCR:
12018 icode = CODE_FOR_spe_mfspefscr;
12019 tmode = insn_data[icode].operand[0].mode;
12022 || GET_MODE (target) != tmode
12023 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
12024 target = gen_reg_rtx (tmode);
12026 pat = GEN_FCN (icode) (target);
12031 case SPE_BUILTIN_MTSPEFSCR:
12032 icode = CODE_FOR_spe_mtspefscr;
12033 arg0 = CALL_EXPR_ARG (exp, 0);
12034 op0 = expand_normal (arg0);
12035 mode0 = insn_data[icode].operand[0].mode;
12037 if (arg0 == error_mark_node)
12040 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
12041 op0 = copy_to_mode_reg (mode0, op0);
12043 pat = GEN_FCN (icode) (op0);
12051 *expandedp = false;
12056 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
12058 rtx pat, scratch, tmp;
12059 tree form = CALL_EXPR_ARG (exp, 0);
12060 tree arg0 = CALL_EXPR_ARG (exp, 1);
12061 tree arg1 = CALL_EXPR_ARG (exp, 2);
12062 rtx op0 = expand_normal (arg0);
12063 rtx op1 = expand_normal (arg1);
12064 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
12065 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
12067 enum rtx_code code;
12069 if (TREE_CODE (form) != INTEGER_CST)
12071 error ("argument 1 of __builtin_paired_predicate must be a constant");
12075 form_int = TREE_INT_CST_LOW (form);
12077 gcc_assert (mode0 == mode1);
12079 if (arg0 == error_mark_node || arg1 == error_mark_node)
12083 || GET_MODE (target) != SImode
12084 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
12085 target = gen_reg_rtx (SImode);
12086 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
12087 op0 = copy_to_mode_reg (mode0, op0);
12088 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
12089 op1 = copy_to_mode_reg (mode1, op1);
12091 scratch = gen_reg_rtx (CCFPmode);
12093 pat = GEN_FCN (icode) (scratch, op0, op1);
12115 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
12118 error ("argument 1 of __builtin_paired_predicate is out of range");
12122 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
12123 emit_move_insn (target, tmp);
12128 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
12130 rtx pat, scratch, tmp;
12131 tree form = CALL_EXPR_ARG (exp, 0);
12132 tree arg0 = CALL_EXPR_ARG (exp, 1);
12133 tree arg1 = CALL_EXPR_ARG (exp, 2);
12134 rtx op0 = expand_normal (arg0);
12135 rtx op1 = expand_normal (arg1);
12136 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
12137 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
12139 enum rtx_code code;
12141 if (TREE_CODE (form) != INTEGER_CST)
12143 error ("argument 1 of __builtin_spe_predicate must be a constant");
12147 form_int = TREE_INT_CST_LOW (form);
12149 gcc_assert (mode0 == mode1);
12151 if (arg0 == error_mark_node || arg1 == error_mark_node)
12155 || GET_MODE (target) != SImode
12156 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
12157 target = gen_reg_rtx (SImode);
12159 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
12160 op0 = copy_to_mode_reg (mode0, op0);
12161 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
12162 op1 = copy_to_mode_reg (mode1, op1);
12164 scratch = gen_reg_rtx (CCmode);
12166 pat = GEN_FCN (icode) (scratch, op0, op1);
12171 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
12172 _lower_. We use one compare, but look in different bits of the
12173 CR for each variant.
12175 There are 2 elements in each SPE simd type (upper/lower). The CR
12176 bits are set as follows:
12178 BIT0 | BIT 1 | BIT 2 | BIT 3
12179 U | L | (U | L) | (U & L)
12181 So, for an "all" relationship, BIT 3 would be set.
12182 For an "any" relationship, BIT 2 would be set. Etc.
12184 Following traditional nomenclature, these bits map to:
12186 BIT0 | BIT 1 | BIT 2 | BIT 3
12189 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
12194 /* All variant. OV bit. */
12196 /* We need to get to the OV bit, which is the ORDERED bit. We
12197 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
12198 that's ugly and will make validate_condition_mode die.
12199 So let's just use another pattern. */
12200 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
12202 /* Any variant. EQ bit. */
12206 /* Upper variant. LT bit. */
12210 /* Lower variant. GT bit. */
12215 error ("argument 1 of __builtin_spe_predicate is out of range");
12219 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
12220 emit_move_insn (target, tmp);
12225 /* The evsel builtins look like this:
12227 e = __builtin_spe_evsel_OP (a, b, c, d);
12229 and work like this:
12231 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
12232 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
12236 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
12239 tree arg0 = CALL_EXPR_ARG (exp, 0);
12240 tree arg1 = CALL_EXPR_ARG (exp, 1);
12241 tree arg2 = CALL_EXPR_ARG (exp, 2);
12242 tree arg3 = CALL_EXPR_ARG (exp, 3);
12243 rtx op0 = expand_normal (arg0);
12244 rtx op1 = expand_normal (arg1);
12245 rtx op2 = expand_normal (arg2);
12246 rtx op3 = expand_normal (arg3);
12247 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
12248 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
12250 gcc_assert (mode0 == mode1);
12252 if (arg0 == error_mark_node || arg1 == error_mark_node
12253 || arg2 == error_mark_node || arg3 == error_mark_node)
12257 || GET_MODE (target) != mode0
12258 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
12259 target = gen_reg_rtx (mode0);
12261 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
12262 op0 = copy_to_mode_reg (mode0, op0);
12263 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
12264 op1 = copy_to_mode_reg (mode0, op1);
12265 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
12266 op2 = copy_to_mode_reg (mode0, op2);
12267 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
12268 op3 = copy_to_mode_reg (mode0, op3);
12270 /* Generate the compare. */
12271 scratch = gen_reg_rtx (CCmode);
12272 pat = GEN_FCN (icode) (scratch, op0, op1);
12277 if (mode0 == V2SImode)
12278 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
12280 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
12285 /* Expand an expression EXP that calls a built-in function,
12286 with result going to TARGET if that's convenient
12287 (and in mode MODE if that's convenient).
12288 SUBTARGET may be used as the target for computing one of EXP's operands.
12289 IGNORE is nonzero if the value is to be ignored. */
12292 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
12293 enum machine_mode mode ATTRIBUTE_UNUSED,
12294 int ignore ATTRIBUTE_UNUSED)
12296 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
12297 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
12298 const struct builtin_description *d;
12305 case RS6000_BUILTIN_RECIP:
12306 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
12308 case RS6000_BUILTIN_RECIPF:
12309 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
12311 case RS6000_BUILTIN_RSQRTF:
12312 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
12314 case RS6000_BUILTIN_RSQRT:
12315 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2, exp, target);
12317 case RS6000_BUILTIN_BSWAP_HI:
12318 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
12320 case POWER7_BUILTIN_BPERMD:
12321 return rs6000_expand_binop_builtin (((TARGET_64BIT)
12322 ? CODE_FOR_bpermd_di
12323 : CODE_FOR_bpermd_si), exp, target);
12325 case ALTIVEC_BUILTIN_MASK_FOR_LOAD:
12326 case ALTIVEC_BUILTIN_MASK_FOR_STORE:
12328 int icode = (int) CODE_FOR_altivec_lvsr;
12329 enum machine_mode tmode = insn_data[icode].operand[0].mode;
12330 enum machine_mode mode = insn_data[icode].operand[1].mode;
12334 gcc_assert (TARGET_ALTIVEC);
12336 arg = CALL_EXPR_ARG (exp, 0);
12337 gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg)));
12338 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
12339 addr = memory_address (mode, op);
12340 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
12344 /* For the load case need to negate the address. */
12345 op = gen_reg_rtx (GET_MODE (addr));
12346 emit_insn (gen_rtx_SET (VOIDmode, op,
12347 gen_rtx_NEG (GET_MODE (addr), addr)));
12349 op = gen_rtx_MEM (mode, op);
12352 || GET_MODE (target) != tmode
12353 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
12354 target = gen_reg_rtx (tmode);
12356 /*pat = gen_altivec_lvsr (target, op);*/
12357 pat = GEN_FCN (icode) (target, op);
12365 case ALTIVEC_BUILTIN_VCFUX:
12366 case ALTIVEC_BUILTIN_VCFSX:
12367 case ALTIVEC_BUILTIN_VCTUXS:
12368 case ALTIVEC_BUILTIN_VCTSXS:
12369 /* FIXME: There's got to be a nicer way to handle this case than
12370 constructing a new CALL_EXPR. */
12371 if (call_expr_nargs (exp) == 1)
12373 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
12374 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
12382 if (TARGET_ALTIVEC)
12384 ret = altivec_expand_builtin (exp, target, &success);
12391 ret = spe_expand_builtin (exp, target, &success);
12396 if (TARGET_PAIRED_FLOAT)
12398 ret = paired_expand_builtin (exp, target, &success);
12404 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
12406 /* Handle simple unary operations. */
12407 d = (struct builtin_description *) bdesc_1arg;
12408 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
12409 if (d->code == fcode)
12410 return rs6000_expand_unop_builtin (d->icode, exp, target);
12412 /* Handle simple binary operations. */
12413 d = (struct builtin_description *) bdesc_2arg;
12414 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
12415 if (d->code == fcode)
12416 return rs6000_expand_binop_builtin (d->icode, exp, target);
12418 /* Handle simple ternary operations. */
12420 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
12421 if (d->code == fcode)
12422 return rs6000_expand_ternop_builtin (d->icode, exp, target);
12424 gcc_unreachable ();
12428 rs6000_init_builtins (void)
12433 V2SI_type_node = build_vector_type (intSI_type_node, 2);
12434 V2SF_type_node = build_vector_type (float_type_node, 2);
12435 V2DI_type_node = build_vector_type (intDI_type_node, 2);
12436 V2DF_type_node = build_vector_type (double_type_node, 2);
12437 V4HI_type_node = build_vector_type (intHI_type_node, 4);
12438 V4SI_type_node = build_vector_type (intSI_type_node, 4);
12439 V4SF_type_node = build_vector_type (float_type_node, 4);
12440 V8HI_type_node = build_vector_type (intHI_type_node, 8);
12441 V16QI_type_node = build_vector_type (intQI_type_node, 16);
12443 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
12444 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
12445 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
12446 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
12448 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
12449 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
12450 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
12451 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
12453 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
12454 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
12455 'vector unsigned short'. */
12457 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
12458 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12459 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
12460 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
12461 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12463 long_integer_type_internal_node = long_integer_type_node;
12464 long_unsigned_type_internal_node = long_unsigned_type_node;
12465 long_long_integer_type_internal_node = long_long_integer_type_node;
12466 long_long_unsigned_type_internal_node = long_long_unsigned_type_node;
12467 intQI_type_internal_node = intQI_type_node;
12468 uintQI_type_internal_node = unsigned_intQI_type_node;
12469 intHI_type_internal_node = intHI_type_node;
12470 uintHI_type_internal_node = unsigned_intHI_type_node;
12471 intSI_type_internal_node = intSI_type_node;
12472 uintSI_type_internal_node = unsigned_intSI_type_node;
12473 intDI_type_internal_node = intDI_type_node;
12474 uintDI_type_internal_node = unsigned_intDI_type_node;
12475 float_type_internal_node = float_type_node;
12476 double_type_internal_node = double_type_node;
12477 void_type_internal_node = void_type_node;
12479 /* Initialize the modes for builtin_function_type, mapping a machine mode to
12481 builtin_mode_to_type[QImode][0] = integer_type_node;
12482 builtin_mode_to_type[HImode][0] = integer_type_node;
12483 builtin_mode_to_type[SImode][0] = intSI_type_node;
12484 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
12485 builtin_mode_to_type[DImode][0] = intDI_type_node;
12486 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
12487 builtin_mode_to_type[SFmode][0] = float_type_node;
12488 builtin_mode_to_type[DFmode][0] = double_type_node;
12489 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
12490 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
12491 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
12492 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
12493 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
12494 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
12495 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
12496 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
12497 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
12498 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
12499 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
12500 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
12501 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
12503 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12504 get_identifier ("__bool char"),
12505 bool_char_type_node);
12506 TYPE_NAME (bool_char_type_node) = tdecl;
12507 (*lang_hooks.decls.pushdecl) (tdecl);
12508 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12509 get_identifier ("__bool short"),
12510 bool_short_type_node);
12511 TYPE_NAME (bool_short_type_node) = tdecl;
12512 (*lang_hooks.decls.pushdecl) (tdecl);
12513 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12514 get_identifier ("__bool int"),
12515 bool_int_type_node);
12516 TYPE_NAME (bool_int_type_node) = tdecl;
12517 (*lang_hooks.decls.pushdecl) (tdecl);
12518 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
12520 TYPE_NAME (pixel_type_node) = tdecl;
12521 (*lang_hooks.decls.pushdecl) (tdecl);
12523 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
12524 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
12525 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
12526 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
12527 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
12529 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12530 get_identifier ("__vector unsigned char"),
12531 unsigned_V16QI_type_node);
12532 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
12533 (*lang_hooks.decls.pushdecl) (tdecl);
12534 tdecl = build_decl (BUILTINS_LOCATION,
12535 TYPE_DECL, get_identifier ("__vector signed char"),
12537 TYPE_NAME (V16QI_type_node) = tdecl;
12538 (*lang_hooks.decls.pushdecl) (tdecl);
12539 tdecl = build_decl (BUILTINS_LOCATION,
12540 TYPE_DECL, get_identifier ("__vector __bool char"),
12541 bool_V16QI_type_node);
12542 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
12543 (*lang_hooks.decls.pushdecl) (tdecl);
12545 tdecl = build_decl (BUILTINS_LOCATION,
12546 TYPE_DECL, get_identifier ("__vector unsigned short"),
12547 unsigned_V8HI_type_node);
12548 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
12549 (*lang_hooks.decls.pushdecl) (tdecl);
12550 tdecl = build_decl (BUILTINS_LOCATION,
12551 TYPE_DECL, get_identifier ("__vector signed short"),
12553 TYPE_NAME (V8HI_type_node) = tdecl;
12554 (*lang_hooks.decls.pushdecl) (tdecl);
12555 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12556 get_identifier ("__vector __bool short"),
12557 bool_V8HI_type_node);
12558 TYPE_NAME (bool_V8HI_type_node) = tdecl;
12559 (*lang_hooks.decls.pushdecl) (tdecl);
12561 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12562 get_identifier ("__vector unsigned int"),
12563 unsigned_V4SI_type_node);
12564 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
12565 (*lang_hooks.decls.pushdecl) (tdecl);
12566 tdecl = build_decl (BUILTINS_LOCATION,
12567 TYPE_DECL, get_identifier ("__vector signed int"),
12569 TYPE_NAME (V4SI_type_node) = tdecl;
12570 (*lang_hooks.decls.pushdecl) (tdecl);
12571 tdecl = build_decl (BUILTINS_LOCATION,
12572 TYPE_DECL, get_identifier ("__vector __bool int"),
12573 bool_V4SI_type_node);
12574 TYPE_NAME (bool_V4SI_type_node) = tdecl;
12575 (*lang_hooks.decls.pushdecl) (tdecl);
12577 tdecl = build_decl (BUILTINS_LOCATION,
12578 TYPE_DECL, get_identifier ("__vector float"),
12580 TYPE_NAME (V4SF_type_node) = tdecl;
12581 (*lang_hooks.decls.pushdecl) (tdecl);
12582 tdecl = build_decl (BUILTINS_LOCATION,
12583 TYPE_DECL, get_identifier ("__vector __pixel"),
12584 pixel_V8HI_type_node);
12585 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
12586 (*lang_hooks.decls.pushdecl) (tdecl);
12590 tdecl = build_decl (BUILTINS_LOCATION,
12591 TYPE_DECL, get_identifier ("__vector double"),
12593 TYPE_NAME (V2DF_type_node) = tdecl;
12594 (*lang_hooks.decls.pushdecl) (tdecl);
12596 tdecl = build_decl (BUILTINS_LOCATION,
12597 TYPE_DECL, get_identifier ("__vector long"),
12599 TYPE_NAME (V2DI_type_node) = tdecl;
12600 (*lang_hooks.decls.pushdecl) (tdecl);
12602 tdecl = build_decl (BUILTINS_LOCATION,
12603 TYPE_DECL, get_identifier ("__vector unsigned long"),
12604 unsigned_V2DI_type_node);
12605 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
12606 (*lang_hooks.decls.pushdecl) (tdecl);
12608 tdecl = build_decl (BUILTINS_LOCATION,
12609 TYPE_DECL, get_identifier ("__vector __bool long"),
12610 bool_V2DI_type_node);
12611 TYPE_NAME (bool_V2DI_type_node) = tdecl;
12612 (*lang_hooks.decls.pushdecl) (tdecl);
12615 if (TARGET_PAIRED_FLOAT)
12616 paired_init_builtins ();
12618 spe_init_builtins ();
12619 if (TARGET_ALTIVEC)
12620 altivec_init_builtins ();
12621 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
12622 rs6000_common_init_builtins ();
12625 ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
12626 RS6000_BUILTIN_RECIP,
12627 "__builtin_recipdiv");
12628 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
12629 RS6000_BUILTIN_RECIP);
12633 ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
12634 RS6000_BUILTIN_RECIPF,
12635 "__builtin_recipdivf");
12636 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
12637 RS6000_BUILTIN_RECIPF);
12639 if (TARGET_FRSQRTE)
12641 ftype = builtin_function_type (DFmode, DFmode, VOIDmode, VOIDmode,
12642 RS6000_BUILTIN_RSQRT,
12643 "__builtin_rsqrt");
12644 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrt", ftype,
12645 RS6000_BUILTIN_RSQRT);
12647 if (TARGET_FRSQRTES)
12649 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
12650 RS6000_BUILTIN_RSQRTF,
12651 "__builtin_rsqrtf");
12652 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
12653 RS6000_BUILTIN_RSQRTF);
12655 if (TARGET_POPCNTD)
12657 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
12658 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
12659 POWER7_BUILTIN_BPERMD,
12660 "__builtin_bpermd");
12661 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
12662 POWER7_BUILTIN_BPERMD);
12664 if (TARGET_POWERPC)
12666 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
12667 tree ftype = build_function_type_list (unsigned_intHI_type_node,
12668 unsigned_intHI_type_node,
12670 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
12671 RS6000_BUILTIN_BSWAP_HI);
12675 /* AIX libm provides clog as __clog. */
12676 if (built_in_decls [BUILT_IN_CLOG])
12677 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
12680 #ifdef SUBTARGET_INIT_BUILTINS
12681 SUBTARGET_INIT_BUILTINS;
12685 /* Returns the rs6000 builtin decl for CODE. */
12688 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
12690 if (code >= RS6000_BUILTIN_COUNT)
12691 return error_mark_node;
12693 return rs6000_builtin_decls[code];
12696 /* Search through a set of builtins and enable the mask bits.
12697 DESC is an array of builtins.
12698 SIZE is the total number of builtins.
12699 START is the builtin enum at which to start.
12700 END is the builtin enum at which to end. */
12702 enable_mask_for_builtins (struct builtin_description *desc, int size,
12703 enum rs6000_builtins start,
12704 enum rs6000_builtins end)
12708 for (i = 0; i < size; ++i)
12709 if (desc[i].code == start)
12715 for (; i < size; ++i)
12717 /* Flip all the bits on. */
12718 desc[i].mask = target_flags;
12719 if (desc[i].code == end)
12725 spe_init_builtins (void)
12727 tree endlink = void_list_node;
12728 tree puint_type_node = build_pointer_type (unsigned_type_node);
12729 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
12730 struct builtin_description *d;
12733 tree v2si_ftype_4_v2si
12734 = build_function_type
12735 (opaque_V2SI_type_node,
12736 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12737 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12738 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12739 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12742 tree v2sf_ftype_4_v2sf
12743 = build_function_type
12744 (opaque_V2SF_type_node,
12745 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12746 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12747 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12748 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12751 tree int_ftype_int_v2si_v2si
12752 = build_function_type
12753 (integer_type_node,
12754 tree_cons (NULL_TREE, integer_type_node,
12755 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12756 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12759 tree int_ftype_int_v2sf_v2sf
12760 = build_function_type
12761 (integer_type_node,
12762 tree_cons (NULL_TREE, integer_type_node,
12763 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12764 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12767 tree void_ftype_v2si_puint_int
12768 = build_function_type (void_type_node,
12769 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12770 tree_cons (NULL_TREE, puint_type_node,
12771 tree_cons (NULL_TREE,
12775 tree void_ftype_v2si_puint_char
12776 = build_function_type (void_type_node,
12777 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12778 tree_cons (NULL_TREE, puint_type_node,
12779 tree_cons (NULL_TREE,
12783 tree void_ftype_v2si_pv2si_int
12784 = build_function_type (void_type_node,
12785 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12786 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12787 tree_cons (NULL_TREE,
12791 tree void_ftype_v2si_pv2si_char
12792 = build_function_type (void_type_node,
12793 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12794 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12795 tree_cons (NULL_TREE,
12799 tree void_ftype_int
12800 = build_function_type (void_type_node,
12801 tree_cons (NULL_TREE, integer_type_node, endlink));
12803 tree int_ftype_void
12804 = build_function_type (integer_type_node, endlink);
12806 tree v2si_ftype_pv2si_int
12807 = build_function_type (opaque_V2SI_type_node,
12808 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12809 tree_cons (NULL_TREE, integer_type_node,
12812 tree v2si_ftype_puint_int
12813 = build_function_type (opaque_V2SI_type_node,
12814 tree_cons (NULL_TREE, puint_type_node,
12815 tree_cons (NULL_TREE, integer_type_node,
12818 tree v2si_ftype_pushort_int
12819 = build_function_type (opaque_V2SI_type_node,
12820 tree_cons (NULL_TREE, pushort_type_node,
12821 tree_cons (NULL_TREE, integer_type_node,
12824 tree v2si_ftype_signed_char
12825 = build_function_type (opaque_V2SI_type_node,
12826 tree_cons (NULL_TREE, signed_char_type_node,
12829 /* The initialization of the simple binary and unary builtins is
12830 done in rs6000_common_init_builtins, but we have to enable the
12831 mask bits here manually because we have run out of `target_flags'
12832 bits. We really need to redesign this mask business. */
12834 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
12835 ARRAY_SIZE (bdesc_2arg),
12836 SPE_BUILTIN_EVADDW,
12837 SPE_BUILTIN_EVXOR);
12838 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
12839 ARRAY_SIZE (bdesc_1arg),
12841 SPE_BUILTIN_EVSUBFUSIAAW);
12842 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
12843 ARRAY_SIZE (bdesc_spe_predicates),
12844 SPE_BUILTIN_EVCMPEQ,
12845 SPE_BUILTIN_EVFSTSTLT);
12846 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
12847 ARRAY_SIZE (bdesc_spe_evsel),
12848 SPE_BUILTIN_EVSEL_CMPGTS,
12849 SPE_BUILTIN_EVSEL_FSTSTEQ);
12851 (*lang_hooks.decls.pushdecl)
12852 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
12853 get_identifier ("__ev64_opaque__"),
12854 opaque_V2SI_type_node));
12856 /* Initialize irregular SPE builtins. */
12858 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
12859 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
12860 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
12861 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
12862 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
12863 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
12864 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
12865 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
12866 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
12867 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
12868 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
12869 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
12870 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
12871 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
12872 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
12873 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
12874 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
12875 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
12878 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
12879 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
12880 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
12881 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
12882 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
12883 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
12884 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
12885 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
12886 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
12887 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
12888 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
12889 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
12890 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
12891 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
12892 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
12893 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
12894 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
12895 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
12896 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
12897 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
12898 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
12899 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
12902 d = (struct builtin_description *) bdesc_spe_predicates;
12903 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
12907 switch (insn_data[d->icode].operand[1].mode)
12910 type = int_ftype_int_v2si_v2si;
12913 type = int_ftype_int_v2sf_v2sf;
12916 gcc_unreachable ();
12919 def_builtin (d->mask, d->name, type, d->code);
12922 /* Evsel predicates. */
12923 d = (struct builtin_description *) bdesc_spe_evsel;
12924 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
12928 switch (insn_data[d->icode].operand[1].mode)
12931 type = v2si_ftype_4_v2si;
12934 type = v2sf_ftype_4_v2sf;
12937 gcc_unreachable ();
12940 def_builtin (d->mask, d->name, type, d->code);
12945 paired_init_builtins (void)
12947 const struct builtin_description *d;
12949 tree endlink = void_list_node;
12951 tree int_ftype_int_v2sf_v2sf
12952 = build_function_type
12953 (integer_type_node,
12954 tree_cons (NULL_TREE, integer_type_node,
12955 tree_cons (NULL_TREE, V2SF_type_node,
12956 tree_cons (NULL_TREE, V2SF_type_node,
12958 tree pcfloat_type_node =
12959 build_pointer_type (build_qualified_type
12960 (float_type_node, TYPE_QUAL_CONST));
12962 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
12963 long_integer_type_node,
12966 tree void_ftype_v2sf_long_pcfloat =
12967 build_function_type_list (void_type_node,
12969 long_integer_type_node,
12974 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
12975 PAIRED_BUILTIN_LX);
12978 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
12979 PAIRED_BUILTIN_STX);
12982 d = bdesc_paired_preds;
12983 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
12987 switch (insn_data[d->icode].operand[1].mode)
12990 type = int_ftype_int_v2sf_v2sf;
12993 gcc_unreachable ();
12996 def_builtin (d->mask, d->name, type, d->code);
13001 altivec_init_builtins (void)
13003 const struct builtin_description *d;
13004 const struct builtin_description_predicates *dp;
13008 tree pvoid_type_node = build_pointer_type (void_type_node);
13010 tree pcvoid_type_node
13011 = build_pointer_type (build_qualified_type (void_type_node,
13014 tree int_ftype_opaque
13015 = build_function_type_list (integer_type_node,
13016 opaque_V4SI_type_node, NULL_TREE);
13017 tree opaque_ftype_opaque
13018 = build_function_type (integer_type_node,
13020 tree opaque_ftype_opaque_int
13021 = build_function_type_list (opaque_V4SI_type_node,
13022 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
13023 tree opaque_ftype_opaque_opaque_int
13024 = build_function_type_list (opaque_V4SI_type_node,
13025 opaque_V4SI_type_node, opaque_V4SI_type_node,
13026 integer_type_node, NULL_TREE);
13027 tree int_ftype_int_opaque_opaque
13028 = build_function_type_list (integer_type_node,
13029 integer_type_node, opaque_V4SI_type_node,
13030 opaque_V4SI_type_node, NULL_TREE);
13031 tree int_ftype_int_v4si_v4si
13032 = build_function_type_list (integer_type_node,
13033 integer_type_node, V4SI_type_node,
13034 V4SI_type_node, NULL_TREE);
13035 tree void_ftype_v4si
13036 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
13037 tree v8hi_ftype_void
13038 = build_function_type (V8HI_type_node, void_list_node);
13039 tree void_ftype_void
13040 = build_function_type (void_type_node, void_list_node);
13041 tree void_ftype_int
13042 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
13044 tree opaque_ftype_long_pcvoid
13045 = build_function_type_list (opaque_V4SI_type_node,
13046 long_integer_type_node, pcvoid_type_node,
13048 tree v16qi_ftype_long_pcvoid
13049 = build_function_type_list (V16QI_type_node,
13050 long_integer_type_node, pcvoid_type_node,
13052 tree v8hi_ftype_long_pcvoid
13053 = build_function_type_list (V8HI_type_node,
13054 long_integer_type_node, pcvoid_type_node,
13056 tree v4si_ftype_long_pcvoid
13057 = build_function_type_list (V4SI_type_node,
13058 long_integer_type_node, pcvoid_type_node,
13060 tree v4sf_ftype_long_pcvoid
13061 = build_function_type_list (V4SF_type_node,
13062 long_integer_type_node, pcvoid_type_node,
13064 tree v2df_ftype_long_pcvoid
13065 = build_function_type_list (V2DF_type_node,
13066 long_integer_type_node, pcvoid_type_node,
13068 tree v2di_ftype_long_pcvoid
13069 = build_function_type_list (V2DI_type_node,
13070 long_integer_type_node, pcvoid_type_node,
13073 tree void_ftype_opaque_long_pvoid
13074 = build_function_type_list (void_type_node,
13075 opaque_V4SI_type_node, long_integer_type_node,
13076 pvoid_type_node, NULL_TREE);
13077 tree void_ftype_v4si_long_pvoid
13078 = build_function_type_list (void_type_node,
13079 V4SI_type_node, long_integer_type_node,
13080 pvoid_type_node, NULL_TREE);
13081 tree void_ftype_v16qi_long_pvoid
13082 = build_function_type_list (void_type_node,
13083 V16QI_type_node, long_integer_type_node,
13084 pvoid_type_node, NULL_TREE);
13085 tree void_ftype_v8hi_long_pvoid
13086 = build_function_type_list (void_type_node,
13087 V8HI_type_node, long_integer_type_node,
13088 pvoid_type_node, NULL_TREE);
13089 tree void_ftype_v4sf_long_pvoid
13090 = build_function_type_list (void_type_node,
13091 V4SF_type_node, long_integer_type_node,
13092 pvoid_type_node, NULL_TREE);
13093 tree void_ftype_v2df_long_pvoid
13094 = build_function_type_list (void_type_node,
13095 V2DF_type_node, long_integer_type_node,
13096 pvoid_type_node, NULL_TREE);
13097 tree void_ftype_v2di_long_pvoid
13098 = build_function_type_list (void_type_node,
13099 V2DI_type_node, long_integer_type_node,
13100 pvoid_type_node, NULL_TREE);
13101 tree int_ftype_int_v8hi_v8hi
13102 = build_function_type_list (integer_type_node,
13103 integer_type_node, V8HI_type_node,
13104 V8HI_type_node, NULL_TREE);
13105 tree int_ftype_int_v16qi_v16qi
13106 = build_function_type_list (integer_type_node,
13107 integer_type_node, V16QI_type_node,
13108 V16QI_type_node, NULL_TREE);
13109 tree int_ftype_int_v4sf_v4sf
13110 = build_function_type_list (integer_type_node,
13111 integer_type_node, V4SF_type_node,
13112 V4SF_type_node, NULL_TREE);
13113 tree int_ftype_int_v2df_v2df
13114 = build_function_type_list (integer_type_node,
13115 integer_type_node, V2DF_type_node,
13116 V2DF_type_node, NULL_TREE);
13117 tree v4si_ftype_v4si
13118 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
13119 tree v8hi_ftype_v8hi
13120 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
13121 tree v16qi_ftype_v16qi
13122 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
13123 tree v4sf_ftype_v4sf
13124 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
13125 tree v2df_ftype_v2df
13126 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
13127 tree void_ftype_pcvoid_int_int
13128 = build_function_type_list (void_type_node,
13129 pcvoid_type_node, integer_type_node,
13130 integer_type_node, NULL_TREE);
13132 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
13133 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
13134 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
13135 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
13136 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
13137 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
13138 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
13139 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
13140 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
13141 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
13142 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
13143 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
13144 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
13145 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
13146 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
13147 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
13148 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
13149 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
13150 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
13151 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
13152 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
13153 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
13154 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
13155 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
13156 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
13157 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
13158 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
13159 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
13160 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
13161 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
13163 def_builtin (MASK_VSX, "__builtin_vsx_lxvd2x_v2df", v2df_ftype_long_pcvoid,
13164 VSX_BUILTIN_LXVD2X_V2DF);
13165 def_builtin (MASK_VSX, "__builtin_vsx_lxvd2x_v2di", v2di_ftype_long_pcvoid,
13166 VSX_BUILTIN_LXVD2X_V2DI);
13167 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v4sf", v4sf_ftype_long_pcvoid,
13168 VSX_BUILTIN_LXVW4X_V4SF);
13169 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v4si", v4si_ftype_long_pcvoid,
13170 VSX_BUILTIN_LXVW4X_V4SI);
13171 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v8hi",
13172 v8hi_ftype_long_pcvoid, VSX_BUILTIN_LXVW4X_V8HI);
13173 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v16qi",
13174 v16qi_ftype_long_pcvoid, VSX_BUILTIN_LXVW4X_V16QI);
13175 def_builtin (MASK_VSX, "__builtin_vsx_stxvd2x_v2df",
13176 void_ftype_v2df_long_pvoid, VSX_BUILTIN_STXVD2X_V2DF);
13177 def_builtin (MASK_VSX, "__builtin_vsx_stxvd2x_v2di",
13178 void_ftype_v2di_long_pvoid, VSX_BUILTIN_STXVD2X_V2DI);
13179 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v4sf",
13180 void_ftype_v4sf_long_pvoid, VSX_BUILTIN_STXVW4X_V4SF);
13181 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v4si",
13182 void_ftype_v4si_long_pvoid, VSX_BUILTIN_STXVW4X_V4SI);
13183 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v8hi",
13184 void_ftype_v8hi_long_pvoid, VSX_BUILTIN_STXVW4X_V8HI);
13185 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v16qi",
13186 void_ftype_v16qi_long_pvoid, VSX_BUILTIN_STXVW4X_V16QI);
13187 def_builtin (MASK_VSX, "__builtin_vec_vsx_ld", opaque_ftype_long_pcvoid,
13188 VSX_BUILTIN_VEC_LD);
13189 def_builtin (MASK_VSX, "__builtin_vec_vsx_st", void_ftype_opaque_long_pvoid,
13190 VSX_BUILTIN_VEC_ST);
13192 if (rs6000_cpu == PROCESSOR_CELL)
13194 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
13195 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
13196 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
13197 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
13199 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
13200 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
13201 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
13202 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
13204 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
13205 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
13206 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
13207 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
13209 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
13210 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
13211 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
13212 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
13214 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
13215 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
13216 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
13218 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
13219 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
13220 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
13221 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
13222 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
13223 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
13224 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
13225 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
13226 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
13227 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
13228 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
13229 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
13231 /* Add the DST variants. */
13233 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
13234 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
13236 /* Initialize the predicates. */
13237 dp = bdesc_altivec_preds;
13238 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
13240 enum machine_mode mode1;
13242 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13243 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13244 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
13245 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
13250 mode1 = insn_data[dp->icode].operand[1].mode;
13255 type = int_ftype_int_opaque_opaque;
13258 type = int_ftype_int_v4si_v4si;
13261 type = int_ftype_int_v8hi_v8hi;
13264 type = int_ftype_int_v16qi_v16qi;
13267 type = int_ftype_int_v4sf_v4sf;
13270 type = int_ftype_int_v2df_v2df;
13273 gcc_unreachable ();
13276 def_builtin (dp->mask, dp->name, type, dp->code);
13279 /* Initialize the abs* operators. */
13281 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
13283 enum machine_mode mode0;
13286 mode0 = insn_data[d->icode].operand[0].mode;
13291 type = v4si_ftype_v4si;
13294 type = v8hi_ftype_v8hi;
13297 type = v16qi_ftype_v16qi;
13300 type = v4sf_ftype_v4sf;
13303 type = v2df_ftype_v2df;
13306 gcc_unreachable ();
13309 def_builtin (d->mask, d->name, type, d->code);
13312 if (TARGET_ALTIVEC)
13316 /* Initialize target builtin that implements
13317 targetm.vectorize.builtin_mask_for_load. */
13319 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
13320 v16qi_ftype_long_pcvoid,
13321 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
13322 BUILT_IN_MD, NULL, NULL_TREE);
13323 TREE_READONLY (decl) = 1;
13324 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
13325 altivec_builtin_mask_for_load = decl;
13328 /* Access to the vec_init patterns. */
13329 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
13330 integer_type_node, integer_type_node,
13331 integer_type_node, NULL_TREE);
13332 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
13333 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
13335 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
13336 short_integer_type_node,
13337 short_integer_type_node,
13338 short_integer_type_node,
13339 short_integer_type_node,
13340 short_integer_type_node,
13341 short_integer_type_node,
13342 short_integer_type_node, NULL_TREE);
13343 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
13344 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
13346 ftype = build_function_type_list (V16QI_type_node, char_type_node,
13347 char_type_node, char_type_node,
13348 char_type_node, char_type_node,
13349 char_type_node, char_type_node,
13350 char_type_node, char_type_node,
13351 char_type_node, char_type_node,
13352 char_type_node, char_type_node,
13353 char_type_node, char_type_node,
13354 char_type_node, NULL_TREE);
13355 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
13356 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
13358 ftype = build_function_type_list (V4SF_type_node, float_type_node,
13359 float_type_node, float_type_node,
13360 float_type_node, NULL_TREE);
13361 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
13362 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
13366 ftype = build_function_type_list (V2DF_type_node, double_type_node,
13367 double_type_node, NULL_TREE);
13368 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
13369 VSX_BUILTIN_VEC_INIT_V2DF);
13371 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
13372 intDI_type_node, NULL_TREE);
13373 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
13374 VSX_BUILTIN_VEC_INIT_V2DI);
13377 /* Access to the vec_set patterns. */
13378 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
13380 integer_type_node, NULL_TREE);
13381 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
13382 ALTIVEC_BUILTIN_VEC_SET_V4SI);
13384 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
13386 integer_type_node, NULL_TREE);
13387 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
13388 ALTIVEC_BUILTIN_VEC_SET_V8HI);
13390 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
13392 integer_type_node, NULL_TREE);
13393 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
13394 ALTIVEC_BUILTIN_VEC_SET_V16QI);
13396 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
13398 integer_type_node, NULL_TREE);
13399 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
13400 ALTIVEC_BUILTIN_VEC_SET_V4SF);
13404 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
13406 integer_type_node, NULL_TREE);
13407 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
13408 VSX_BUILTIN_VEC_SET_V2DF);
13410 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
13412 integer_type_node, NULL_TREE);
13413 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
13414 VSX_BUILTIN_VEC_SET_V2DI);
13417 /* Access to the vec_extract patterns. */
13418 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
13419 integer_type_node, NULL_TREE);
13420 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
13421 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
13423 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
13424 integer_type_node, NULL_TREE);
13425 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
13426 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
13428 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
13429 integer_type_node, NULL_TREE);
13430 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
13431 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
13433 ftype = build_function_type_list (float_type_node, V4SF_type_node,
13434 integer_type_node, NULL_TREE);
13435 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
13436 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
13440 ftype = build_function_type_list (double_type_node, V2DF_type_node,
13441 integer_type_node, NULL_TREE);
13442 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
13443 VSX_BUILTIN_VEC_EXT_V2DF);
13445 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
13446 integer_type_node, NULL_TREE);
13447 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
13448 VSX_BUILTIN_VEC_EXT_V2DI);
13452 /* Hash function for builtin functions with up to 3 arguments and a return
13455 builtin_hash_function (const void *hash_entry)
13459 const struct builtin_hash_struct *bh =
13460 (const struct builtin_hash_struct *) hash_entry;
13462 for (i = 0; i < 4; i++)
13464 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
13465 ret = (ret * 2) + bh->uns_p[i];
13471 /* Compare builtin hash entries H1 and H2 for equivalence. */
13473 builtin_hash_eq (const void *h1, const void *h2)
13475 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
13476 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
13478 return ((p1->mode[0] == p2->mode[0])
13479 && (p1->mode[1] == p2->mode[1])
13480 && (p1->mode[2] == p2->mode[2])
13481 && (p1->mode[3] == p2->mode[3])
13482 && (p1->uns_p[0] == p2->uns_p[0])
13483 && (p1->uns_p[1] == p2->uns_p[1])
13484 && (p1->uns_p[2] == p2->uns_p[2])
13485 && (p1->uns_p[3] == p2->uns_p[3]));
13488 /* Map types for builtin functions with an explicit return type and up to 3
13489 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
13490 of the argument. */
13492 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
13493 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
13494 enum rs6000_builtins builtin, const char *name)
13496 struct builtin_hash_struct h;
13497 struct builtin_hash_struct *h2;
13501 tree ret_type = NULL_TREE;
13502 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
13505 /* Create builtin_hash_table. */
13506 if (builtin_hash_table == NULL)
13507 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
13508 builtin_hash_eq, NULL);
13510 h.type = NULL_TREE;
13511 h.mode[0] = mode_ret;
13512 h.mode[1] = mode_arg0;
13513 h.mode[2] = mode_arg1;
13514 h.mode[3] = mode_arg2;
13520 /* If the builtin is a type that produces unsigned results or takes unsigned
13521 arguments, and it is returned as a decl for the vectorizer (such as
13522 widening multiplies, permute), make sure the arguments and return value
13523 are type correct. */
13526 /* unsigned 2 argument functions. */
13527 case ALTIVEC_BUILTIN_VMULEUB_UNS:
13528 case ALTIVEC_BUILTIN_VMULEUH_UNS:
13529 case ALTIVEC_BUILTIN_VMULOUB_UNS:
13530 case ALTIVEC_BUILTIN_VMULOUH_UNS:
13536 /* unsigned 3 argument functions. */
13537 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
13538 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
13539 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
13540 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
13541 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
13542 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
13543 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
13544 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
13545 case VSX_BUILTIN_VPERM_16QI_UNS:
13546 case VSX_BUILTIN_VPERM_8HI_UNS:
13547 case VSX_BUILTIN_VPERM_4SI_UNS:
13548 case VSX_BUILTIN_VPERM_2DI_UNS:
13549 case VSX_BUILTIN_XXSEL_16QI_UNS:
13550 case VSX_BUILTIN_XXSEL_8HI_UNS:
13551 case VSX_BUILTIN_XXSEL_4SI_UNS:
13552 case VSX_BUILTIN_XXSEL_2DI_UNS:
13559 /* signed permute functions with unsigned char mask. */
13560 case ALTIVEC_BUILTIN_VPERM_16QI:
13561 case ALTIVEC_BUILTIN_VPERM_8HI:
13562 case ALTIVEC_BUILTIN_VPERM_4SI:
13563 case ALTIVEC_BUILTIN_VPERM_4SF:
13564 case ALTIVEC_BUILTIN_VPERM_2DI:
13565 case ALTIVEC_BUILTIN_VPERM_2DF:
13566 case VSX_BUILTIN_VPERM_16QI:
13567 case VSX_BUILTIN_VPERM_8HI:
13568 case VSX_BUILTIN_VPERM_4SI:
13569 case VSX_BUILTIN_VPERM_4SF:
13570 case VSX_BUILTIN_VPERM_2DI:
13571 case VSX_BUILTIN_VPERM_2DF:
13575 /* unsigned args, signed return. */
13576 case VSX_BUILTIN_XVCVUXDDP_UNS:
13577 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
13581 /* signed args, unsigned return. */
13582 case VSX_BUILTIN_XVCVDPUXDS_UNS:
13583 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
13591 /* Figure out how many args are present. */
13592 while (num_args > 0 && h.mode[num_args] == VOIDmode)
13596 fatal_error ("internal error: builtin function %s had no type", name);
13598 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
13599 if (!ret_type && h.uns_p[0])
13600 ret_type = builtin_mode_to_type[h.mode[0]][0];
13603 fatal_error ("internal error: builtin function %s had an unexpected "
13604 "return type %s", name, GET_MODE_NAME (h.mode[0]));
13606 for (i = 0; i < num_args; i++)
13608 int m = (int) h.mode[i+1];
13609 int uns_p = h.uns_p[i+1];
13611 arg_type[i] = builtin_mode_to_type[m][uns_p];
13612 if (!arg_type[i] && uns_p)
13613 arg_type[i] = builtin_mode_to_type[m][0];
13616 fatal_error ("internal error: builtin function %s, argument %d "
13617 "had unexpected argument type %s", name, i,
13618 GET_MODE_NAME (m));
13621 found = htab_find_slot (builtin_hash_table, &h, INSERT);
13622 if (*found == NULL)
13624 h2 = ggc_alloc_builtin_hash_struct ();
13626 *found = (void *)h2;
13627 args = void_list_node;
13629 for (i = num_args - 1; i >= 0; i--)
13630 args = tree_cons (NULL_TREE, arg_type[i], args);
13632 h2->type = build_function_type (ret_type, args);
13635 return ((struct builtin_hash_struct *)(*found))->type;
13639 rs6000_common_init_builtins (void)
13641 const struct builtin_description *d;
13644 tree opaque_ftype_opaque = NULL_TREE;
13645 tree opaque_ftype_opaque_opaque = NULL_TREE;
13646 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
13647 tree v2si_ftype_qi = NULL_TREE;
13648 tree v2si_ftype_v2si_qi = NULL_TREE;
13649 tree v2si_ftype_int_qi = NULL_TREE;
13651 if (!TARGET_PAIRED_FLOAT)
13653 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
13654 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
13657 /* Add the ternary operators. */
13659 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
13662 int mask = d->mask;
13664 if ((mask != 0 && (mask & target_flags) == 0)
13665 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13668 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13669 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13670 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13671 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13673 if (! (type = opaque_ftype_opaque_opaque_opaque))
13674 type = opaque_ftype_opaque_opaque_opaque
13675 = build_function_type_list (opaque_V4SI_type_node,
13676 opaque_V4SI_type_node,
13677 opaque_V4SI_type_node,
13678 opaque_V4SI_type_node,
13683 enum insn_code icode = d->icode;
13684 if (d->name == 0 || icode == CODE_FOR_nothing)
13687 type = builtin_function_type (insn_data[icode].operand[0].mode,
13688 insn_data[icode].operand[1].mode,
13689 insn_data[icode].operand[2].mode,
13690 insn_data[icode].operand[3].mode,
13694 def_builtin (d->mask, d->name, type, d->code);
13697 /* Add the binary operators. */
13699 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
13701 enum machine_mode mode0, mode1, mode2;
13703 int mask = d->mask;
13705 if ((mask != 0 && (mask & target_flags) == 0)
13706 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13709 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13710 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13711 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13712 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13714 if (! (type = opaque_ftype_opaque_opaque))
13715 type = opaque_ftype_opaque_opaque
13716 = build_function_type_list (opaque_V4SI_type_node,
13717 opaque_V4SI_type_node,
13718 opaque_V4SI_type_node,
13723 enum insn_code icode = d->icode;
13724 if (d->name == 0 || icode == CODE_FOR_nothing)
13727 mode0 = insn_data[icode].operand[0].mode;
13728 mode1 = insn_data[icode].operand[1].mode;
13729 mode2 = insn_data[icode].operand[2].mode;
13731 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
13733 if (! (type = v2si_ftype_v2si_qi))
13734 type = v2si_ftype_v2si_qi
13735 = build_function_type_list (opaque_V2SI_type_node,
13736 opaque_V2SI_type_node,
13741 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
13742 && mode2 == QImode)
13744 if (! (type = v2si_ftype_int_qi))
13745 type = v2si_ftype_int_qi
13746 = build_function_type_list (opaque_V2SI_type_node,
13753 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
13757 def_builtin (d->mask, d->name, type, d->code);
13760 /* Add the simple unary operators. */
13761 d = (struct builtin_description *) bdesc_1arg;
13762 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
13764 enum machine_mode mode0, mode1;
13766 int mask = d->mask;
13768 if ((mask != 0 && (mask & target_flags) == 0)
13769 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13772 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13773 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13774 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13775 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13777 if (! (type = opaque_ftype_opaque))
13778 type = opaque_ftype_opaque
13779 = build_function_type_list (opaque_V4SI_type_node,
13780 opaque_V4SI_type_node,
13785 enum insn_code icode = d->icode;
13786 if (d->name == 0 || icode == CODE_FOR_nothing)
13789 mode0 = insn_data[icode].operand[0].mode;
13790 mode1 = insn_data[icode].operand[1].mode;
13792 if (mode0 == V2SImode && mode1 == QImode)
13794 if (! (type = v2si_ftype_qi))
13795 type = v2si_ftype_qi
13796 = build_function_type_list (opaque_V2SI_type_node,
13802 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
13806 def_builtin (d->mask, d->name, type, d->code);
13811 rs6000_init_libfuncs (void)
13813 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
13814 && !TARGET_POWER2 && !TARGET_POWERPC)
13816 /* AIX library routines for float->int conversion. */
13817 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
13818 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
13819 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
13820 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
13823 if (!TARGET_IEEEQUAD)
13824 /* AIX/Darwin/64-bit Linux quad floating point routines. */
13825 if (!TARGET_XL_COMPAT)
13827 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
13828 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
13829 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
13830 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
13832 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
13834 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
13835 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
13836 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
13837 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
13838 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
13839 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
13840 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
13842 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
13843 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
13844 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
13845 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
13846 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
13847 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
13848 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
13849 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
13852 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
13853 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
13857 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
13858 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
13859 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
13860 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
13864 /* 32-bit SVR4 quad floating point routines. */
13866 set_optab_libfunc (add_optab, TFmode, "_q_add");
13867 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
13868 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
13869 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
13870 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
13871 if (TARGET_PPC_GPOPT || TARGET_POWER2)
13872 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
13874 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
13875 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
13876 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
13877 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
13878 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
13879 set_optab_libfunc (le_optab, TFmode, "_q_fle");
13881 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
13882 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
13883 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
13884 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
13885 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
13886 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
13887 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
13888 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
13893 /* Expand a block clear operation, and return 1 if successful. Return 0
13894 if we should let the compiler generate normal code.
13896 operands[0] is the destination
13897 operands[1] is the length
13898 operands[3] is the alignment */
13901 expand_block_clear (rtx operands[])
13903 rtx orig_dest = operands[0];
13904 rtx bytes_rtx = operands[1];
13905 rtx align_rtx = operands[3];
13906 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
13907 HOST_WIDE_INT align;
13908 HOST_WIDE_INT bytes;
13913 /* If this is not a fixed size move, just call memcpy */
13917 /* This must be a fixed size alignment */
13918 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13919 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13921 /* Anything to clear? */
13922 bytes = INTVAL (bytes_rtx);
13926 /* Use the builtin memset after a point, to avoid huge code bloat.
13927 When optimize_size, avoid any significant code bloat; calling
13928 memset is about 4 instructions, so allow for one instruction to
13929 load zero and three to do clearing. */
13930 if (TARGET_ALTIVEC && align >= 128)
13932 else if (TARGET_POWERPC64 && align >= 32)
13934 else if (TARGET_SPE && align >= 64)
13939 if (optimize_size && bytes > 3 * clear_step)
13941 if (! optimize_size && bytes > 8 * clear_step)
13944 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
13946 enum machine_mode mode = BLKmode;
13949 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
13954 else if (bytes >= 8 && TARGET_SPE && align >= 64)
13959 else if (bytes >= 8 && TARGET_POWERPC64
13960 /* 64-bit loads and stores require word-aligned
13962 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13967 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13968 { /* move 4 bytes */
13972 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13973 { /* move 2 bytes */
13977 else /* move 1 byte at a time */
13983 dest = adjust_address (orig_dest, mode, offset);
13985 emit_move_insn (dest, CONST0_RTX (mode));
13992 /* Expand a block move operation, and return 1 if successful. Return 0
13993 if we should let the compiler generate normal code.
13995 operands[0] is the destination
13996 operands[1] is the source
13997 operands[2] is the length
13998 operands[3] is the alignment */
14000 #define MAX_MOVE_REG 4
14003 expand_block_move (rtx operands[])
14005 rtx orig_dest = operands[0];
14006 rtx orig_src = operands[1];
14007 rtx bytes_rtx = operands[2];
14008 rtx align_rtx = operands[3];
14009 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
14014 rtx stores[MAX_MOVE_REG];
14017 /* If this is not a fixed size move, just call memcpy */
14021 /* This must be a fixed size alignment */
14022 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
14023 align = INTVAL (align_rtx) * BITS_PER_UNIT;
14025 /* Anything to move? */
14026 bytes = INTVAL (bytes_rtx);
14030 if (bytes > rs6000_block_move_inline_limit)
14033 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
14036 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
14037 rtx (*mov) (rtx, rtx);
14039 enum machine_mode mode = BLKmode;
14042 /* Altivec first, since it will be faster than a string move
14043 when it applies, and usually not significantly larger. */
14044 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
14048 gen_func.mov = gen_movv4si;
14050 else if (TARGET_SPE && bytes >= 8 && align >= 64)
14054 gen_func.mov = gen_movv2si;
14056 else if (TARGET_STRING
14057 && bytes > 24 /* move up to 32 bytes at a time */
14063 && ! fixed_regs[10]
14064 && ! fixed_regs[11]
14065 && ! fixed_regs[12])
14067 move_bytes = (bytes > 32) ? 32 : bytes;
14068 gen_func.movmemsi = gen_movmemsi_8reg;
14070 else if (TARGET_STRING
14071 && bytes > 16 /* move up to 24 bytes at a time */
14077 && ! fixed_regs[10])
14079 move_bytes = (bytes > 24) ? 24 : bytes;
14080 gen_func.movmemsi = gen_movmemsi_6reg;
14082 else if (TARGET_STRING
14083 && bytes > 8 /* move up to 16 bytes at a time */
14087 && ! fixed_regs[8])
14089 move_bytes = (bytes > 16) ? 16 : bytes;
14090 gen_func.movmemsi = gen_movmemsi_4reg;
14092 else if (bytes >= 8 && TARGET_POWERPC64
14093 /* 64-bit loads and stores require word-aligned
14095 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
14099 gen_func.mov = gen_movdi;
14101 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
14102 { /* move up to 8 bytes at a time */
14103 move_bytes = (bytes > 8) ? 8 : bytes;
14104 gen_func.movmemsi = gen_movmemsi_2reg;
14106 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
14107 { /* move 4 bytes */
14110 gen_func.mov = gen_movsi;
14112 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
14113 { /* move 2 bytes */
14116 gen_func.mov = gen_movhi;
14118 else if (TARGET_STRING && bytes > 1)
14119 { /* move up to 4 bytes at a time */
14120 move_bytes = (bytes > 4) ? 4 : bytes;
14121 gen_func.movmemsi = gen_movmemsi_1reg;
14123 else /* move 1 byte at a time */
14127 gen_func.mov = gen_movqi;
14130 src = adjust_address (orig_src, mode, offset);
14131 dest = adjust_address (orig_dest, mode, offset);
14133 if (mode != BLKmode)
14135 rtx tmp_reg = gen_reg_rtx (mode);
14137 emit_insn ((*gen_func.mov) (tmp_reg, src));
14138 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
14141 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
14144 for (i = 0; i < num_reg; i++)
14145 emit_insn (stores[i]);
14149 if (mode == BLKmode)
14151 /* Move the address into scratch registers. The movmemsi
14152 patterns require zero offset. */
14153 if (!REG_P (XEXP (src, 0)))
14155 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
14156 src = replace_equiv_address (src, src_reg);
14158 set_mem_size (src, GEN_INT (move_bytes));
14160 if (!REG_P (XEXP (dest, 0)))
14162 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
14163 dest = replace_equiv_address (dest, dest_reg);
14165 set_mem_size (dest, GEN_INT (move_bytes));
14167 emit_insn ((*gen_func.movmemsi) (dest, src,
14168 GEN_INT (move_bytes & 31),
14177 /* Return a string to perform a load_multiple operation.
14178 operands[0] is the vector.
14179 operands[1] is the source address.
14180 operands[2] is the first destination register. */
14183 rs6000_output_load_multiple (rtx operands[3])
14185 /* We have to handle the case where the pseudo used to contain the address
14186 is assigned to one of the output registers. */
14188 int words = XVECLEN (operands[0], 0);
14191 if (XVECLEN (operands[0], 0) == 1)
14192 return "{l|lwz} %2,0(%1)";
14194 for (i = 0; i < words; i++)
14195 if (refers_to_regno_p (REGNO (operands[2]) + i,
14196 REGNO (operands[2]) + i + 1, operands[1], 0))
14200 xop[0] = GEN_INT (4 * (words-1));
14201 xop[1] = operands[1];
14202 xop[2] = operands[2];
14203 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
14208 xop[0] = GEN_INT (4 * (words-1));
14209 xop[1] = operands[1];
14210 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
14211 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);
14216 for (j = 0; j < words; j++)
14219 xop[0] = GEN_INT (j * 4);
14220 xop[1] = operands[1];
14221 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
14222 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
14224 xop[0] = GEN_INT (i * 4);
14225 xop[1] = operands[1];
14226 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
14231 return "{lsi|lswi} %2,%1,%N0";
14235 /* A validation routine: say whether CODE, a condition code, and MODE
14236 match. The other alternatives either don't make sense or should
14237 never be generated. */
14240 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
14242 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
14243 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
14244 && GET_MODE_CLASS (mode) == MODE_CC);
14246 /* These don't make sense. */
14247 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
14248 || mode != CCUNSmode);
14250 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
14251 || mode == CCUNSmode);
14253 gcc_assert (mode == CCFPmode
14254 || (code != ORDERED && code != UNORDERED
14255 && code != UNEQ && code != LTGT
14256 && code != UNGT && code != UNLT
14257 && code != UNGE && code != UNLE));
14259 /* These should never be generated except for
14260 flag_finite_math_only. */
14261 gcc_assert (mode != CCFPmode
14262 || flag_finite_math_only
14263 || (code != LE && code != GE
14264 && code != UNEQ && code != LTGT
14265 && code != UNGT && code != UNLT));
14267 /* These are invalid; the information is not there. */
14268 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
14272 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
14273 mask required to convert the result of a rotate insn into a shift
14274 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
14277 includes_lshift_p (rtx shiftop, rtx andop)
14279 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
14281 shift_mask <<= INTVAL (shiftop);
14283 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
14286 /* Similar, but for right shift. */
14289 includes_rshift_p (rtx shiftop, rtx andop)
14291 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
14293 shift_mask >>= INTVAL (shiftop);
14295 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
14298 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
14299 to perform a left shift. It must have exactly SHIFTOP least
14300 significant 0's, then one or more 1's, then zero or more 0's. */
14303 includes_rldic_lshift_p (rtx shiftop, rtx andop)
14305 if (GET_CODE (andop) == CONST_INT)
14307 HOST_WIDE_INT c, lsb, shift_mask;
14309 c = INTVAL (andop);
14310 if (c == 0 || c == ~0)
14314 shift_mask <<= INTVAL (shiftop);
14316 /* Find the least significant one bit. */
14319 /* It must coincide with the LSB of the shift mask. */
14320 if (-lsb != shift_mask)
14323 /* Invert to look for the next transition (if any). */
14326 /* Remove the low group of ones (originally low group of zeros). */
14329 /* Again find the lsb, and check we have all 1's above. */
14333 else if (GET_CODE (andop) == CONST_DOUBLE
14334 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
14336 HOST_WIDE_INT low, high, lsb;
14337 HOST_WIDE_INT shift_mask_low, shift_mask_high;
14339 low = CONST_DOUBLE_LOW (andop);
14340 if (HOST_BITS_PER_WIDE_INT < 64)
14341 high = CONST_DOUBLE_HIGH (andop);
14343 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
14344 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
14347 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
14349 shift_mask_high = ~0;
14350 if (INTVAL (shiftop) > 32)
14351 shift_mask_high <<= INTVAL (shiftop) - 32;
14353 lsb = high & -high;
14355 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
14361 lsb = high & -high;
14362 return high == -lsb;
14365 shift_mask_low = ~0;
14366 shift_mask_low <<= INTVAL (shiftop);
14370 if (-lsb != shift_mask_low)
14373 if (HOST_BITS_PER_WIDE_INT < 64)
14378 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
14380 lsb = high & -high;
14381 return high == -lsb;
14385 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
14391 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
14392 to perform a left shift. It must have SHIFTOP or more least
14393 significant 0's, with the remainder of the word 1's. */
14396 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
14398 if (GET_CODE (andop) == CONST_INT)
14400 HOST_WIDE_INT c, lsb, shift_mask;
14403 shift_mask <<= INTVAL (shiftop);
14404 c = INTVAL (andop);
14406 /* Find the least significant one bit. */
14409 /* It must be covered by the shift mask.
14410 This test also rejects c == 0. */
14411 if ((lsb & shift_mask) == 0)
14414 /* Check we have all 1's above the transition, and reject all 1's. */
14415 return c == -lsb && lsb != 1;
14417 else if (GET_CODE (andop) == CONST_DOUBLE
14418 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
14420 HOST_WIDE_INT low, lsb, shift_mask_low;
14422 low = CONST_DOUBLE_LOW (andop);
14424 if (HOST_BITS_PER_WIDE_INT < 64)
14426 HOST_WIDE_INT high, shift_mask_high;
14428 high = CONST_DOUBLE_HIGH (andop);
14432 shift_mask_high = ~0;
14433 if (INTVAL (shiftop) > 32)
14434 shift_mask_high <<= INTVAL (shiftop) - 32;
14436 lsb = high & -high;
14438 if ((lsb & shift_mask_high) == 0)
14441 return high == -lsb;
14447 shift_mask_low = ~0;
14448 shift_mask_low <<= INTVAL (shiftop);
14452 if ((lsb & shift_mask_low) == 0)
14455 return low == -lsb && lsb != 1;
14461 /* Return 1 if operands will generate a valid arguments to rlwimi
14462 instruction for insert with right shift in 64-bit mode. The mask may
14463 not start on the first bit or stop on the last bit because wrap-around
14464 effects of instruction do not correspond to semantics of RTL insn. */
14467 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
14469 if (INTVAL (startop) > 32
14470 && INTVAL (startop) < 64
14471 && INTVAL (sizeop) > 1
14472 && INTVAL (sizeop) + INTVAL (startop) < 64
14473 && INTVAL (shiftop) > 0
14474 && INTVAL (sizeop) + INTVAL (shiftop) < 32
14475 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
14481 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
14482 for lfq and stfq insns iff the registers are hard registers. */
14485 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
14487 /* We might have been passed a SUBREG. */
14488 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
14491 /* We might have been passed non floating point registers. */
14492 if (!FP_REGNO_P (REGNO (reg1))
14493 || !FP_REGNO_P (REGNO (reg2)))
14496 return (REGNO (reg1) == REGNO (reg2) - 1);
14499 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
14500 addr1 and addr2 must be in consecutive memory locations
14501 (addr2 == addr1 + 8). */
14504 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
14507 unsigned int reg1, reg2;
14508 int offset1, offset2;
14510 /* The mems cannot be volatile. */
14511 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
14514 addr1 = XEXP (mem1, 0);
14515 addr2 = XEXP (mem2, 0);
14517 /* Extract an offset (if used) from the first addr. */
14518 if (GET_CODE (addr1) == PLUS)
14520 /* If not a REG, return zero. */
14521 if (GET_CODE (XEXP (addr1, 0)) != REG)
14525 reg1 = REGNO (XEXP (addr1, 0));
14526 /* The offset must be constant! */
14527 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
14529 offset1 = INTVAL (XEXP (addr1, 1));
14532 else if (GET_CODE (addr1) != REG)
14536 reg1 = REGNO (addr1);
14537 /* This was a simple (mem (reg)) expression. Offset is 0. */
14541 /* And now for the second addr. */
14542 if (GET_CODE (addr2) == PLUS)
14544 /* If not a REG, return zero. */
14545 if (GET_CODE (XEXP (addr2, 0)) != REG)
14549 reg2 = REGNO (XEXP (addr2, 0));
14550 /* The offset must be constant. */
14551 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
14553 offset2 = INTVAL (XEXP (addr2, 1));
14556 else if (GET_CODE (addr2) != REG)
14560 reg2 = REGNO (addr2);
14561 /* This was a simple (mem (reg)) expression. Offset is 0. */
14565 /* Both of these must have the same base register. */
14569 /* The offset for the second addr must be 8 more than the first addr. */
14570 if (offset2 != offset1 + 8)
14573 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
14580 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
14582 static bool eliminated = false;
14585 if (mode != SDmode)
14586 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
14589 rtx mem = cfun->machine->sdmode_stack_slot;
14590 gcc_assert (mem != NULL_RTX);
14594 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
14595 cfun->machine->sdmode_stack_slot = mem;
14601 if (TARGET_DEBUG_ADDR)
14603 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
14604 GET_MODE_NAME (mode));
14606 fprintf (stderr, "\tNULL_RTX\n");
14615 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
14617 /* Don't walk into types. */
14618 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
14620 *walk_subtrees = 0;
14624 switch (TREE_CODE (*tp))
14633 case VIEW_CONVERT_EXPR:
14634 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
14644 enum reload_reg_type {
14646 VECTOR_REGISTER_TYPE,
14647 OTHER_REGISTER_TYPE
14650 static enum reload_reg_type
14651 rs6000_reload_register_type (enum reg_class rclass)
14657 return GPR_REGISTER_TYPE;
14662 return VECTOR_REGISTER_TYPE;
14665 return OTHER_REGISTER_TYPE;
14669 /* Inform reload about cases where moving X with a mode MODE to a register in
14670 RCLASS requires an extra scratch or immediate register. Return the class
14671 needed for the immediate register.
14673 For VSX and Altivec, we may need a register to convert sp+offset into
14677 rs6000_secondary_reload (bool in_p,
14679 reg_class_t rclass_i,
14680 enum machine_mode mode,
14681 secondary_reload_info *sri)
14683 enum reg_class rclass = (enum reg_class) rclass_i;
14684 reg_class_t ret = ALL_REGS;
14685 enum insn_code icode;
14686 bool default_p = false;
14688 sri->icode = CODE_FOR_nothing;
14690 /* Convert vector loads and stores into gprs to use an additional base
14692 icode = rs6000_vector_reload[mode][in_p != false];
14693 if (icode != CODE_FOR_nothing)
14696 sri->icode = CODE_FOR_nothing;
14697 sri->extra_cost = 0;
14699 if (GET_CODE (x) == MEM)
14701 rtx addr = XEXP (x, 0);
14703 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
14704 an extra register in that case, but it would need an extra
14705 register if the addressing is reg+reg or (reg+reg)&(-16). */
14706 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
14708 if (!legitimate_indirect_address_p (addr, false)
14709 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14711 sri->icode = icode;
14712 /* account for splitting the loads, and converting the
14713 address from reg+reg to reg. */
14714 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
14715 + ((GET_CODE (addr) == AND) ? 1 : 0));
14718 /* Loads to and stores from vector registers can only do reg+reg
14719 addressing. Altivec registers can also do (reg+reg)&(-16). */
14720 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
14721 || rclass == FLOAT_REGS || rclass == NO_REGS)
14723 if (!VECTOR_MEM_ALTIVEC_P (mode)
14724 && GET_CODE (addr) == AND
14725 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14726 && INTVAL (XEXP (addr, 1)) == -16
14727 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
14728 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
14730 sri->icode = icode;
14731 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
14734 else if (!legitimate_indirect_address_p (addr, false)
14735 && (rclass == NO_REGS
14736 || !legitimate_indexed_address_p (addr, false)))
14738 sri->icode = icode;
14739 sri->extra_cost = 1;
14742 icode = CODE_FOR_nothing;
14744 /* Any other loads, including to pseudo registers which haven't been
14745 assigned to a register yet, default to require a scratch
14749 sri->icode = icode;
14750 sri->extra_cost = 2;
14753 else if (REG_P (x))
14755 int regno = true_regnum (x);
14757 icode = CODE_FOR_nothing;
14758 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
14762 enum reg_class xclass = REGNO_REG_CLASS (regno);
14763 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
14764 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
14766 /* If memory is needed, use default_secondary_reload to create the
14768 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
14781 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
14783 gcc_assert (ret != ALL_REGS);
14785 if (TARGET_DEBUG_ADDR)
14788 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
14790 reg_class_names[ret],
14791 in_p ? "true" : "false",
14792 reg_class_names[rclass],
14793 GET_MODE_NAME (mode));
14796 fprintf (stderr, ", default secondary reload");
14798 if (sri->icode != CODE_FOR_nothing)
14799 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
14800 insn_data[sri->icode].name, sri->extra_cost);
14802 fprintf (stderr, "\n");
14810 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
14811 to SP+reg addressing. */
14814 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
14816 int regno = true_regnum (reg);
14817 enum machine_mode mode = GET_MODE (reg);
14818 enum reg_class rclass;
14820 rtx and_op2 = NULL_RTX;
14823 rtx scratch_or_premodify = scratch;
14827 if (TARGET_DEBUG_ADDR)
14829 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
14830 store_p ? "store" : "load");
14831 fprintf (stderr, "reg:\n");
14833 fprintf (stderr, "mem:\n");
14835 fprintf (stderr, "scratch:\n");
14836 debug_rtx (scratch);
14839 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
14840 gcc_assert (GET_CODE (mem) == MEM);
14841 rclass = REGNO_REG_CLASS (regno);
14842 addr = XEXP (mem, 0);
14846 /* GPRs can handle reg + small constant, all other addresses need to use
14847 the scratch register. */
14850 if (GET_CODE (addr) == AND)
14852 and_op2 = XEXP (addr, 1);
14853 addr = XEXP (addr, 0);
14856 if (GET_CODE (addr) == PRE_MODIFY)
14858 scratch_or_premodify = XEXP (addr, 0);
14859 gcc_assert (REG_P (scratch_or_premodify));
14860 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14861 addr = XEXP (addr, 1);
14864 if (GET_CODE (addr) == PLUS
14865 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
14866 || and_op2 != NULL_RTX))
14868 addr_op1 = XEXP (addr, 0);
14869 addr_op2 = XEXP (addr, 1);
14870 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
14872 if (!REG_P (addr_op2)
14873 && (GET_CODE (addr_op2) != CONST_INT
14874 || !satisfies_constraint_I (addr_op2)))
14876 if (TARGET_DEBUG_ADDR)
14879 "\nMove plus addr to register %s, mode = %s: ",
14880 rs6000_reg_names[REGNO (scratch)],
14881 GET_MODE_NAME (mode));
14882 debug_rtx (addr_op2);
14884 rs6000_emit_move (scratch, addr_op2, Pmode);
14885 addr_op2 = scratch;
14888 emit_insn (gen_rtx_SET (VOIDmode,
14889 scratch_or_premodify,
14890 gen_rtx_PLUS (Pmode,
14894 addr = scratch_or_premodify;
14895 scratch_or_premodify = scratch;
14897 else if (!legitimate_indirect_address_p (addr, false)
14898 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14900 if (TARGET_DEBUG_ADDR)
14902 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14903 rs6000_reg_names[REGNO (scratch_or_premodify)],
14904 GET_MODE_NAME (mode));
14907 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14908 addr = scratch_or_premodify;
14909 scratch_or_premodify = scratch;
14913 /* Float/Altivec registers can only handle reg+reg addressing. Move
14914 other addresses into a scratch register. */
14919 /* With float regs, we need to handle the AND ourselves, since we can't
14920 use the Altivec instruction with an implicit AND -16. Allow scalar
14921 loads to float registers to use reg+offset even if VSX. */
14922 if (GET_CODE (addr) == AND
14923 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
14924 || GET_CODE (XEXP (addr, 1)) != CONST_INT
14925 || INTVAL (XEXP (addr, 1)) != -16
14926 || !VECTOR_MEM_ALTIVEC_P (mode)))
14928 and_op2 = XEXP (addr, 1);
14929 addr = XEXP (addr, 0);
14932 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
14933 as the address later. */
14934 if (GET_CODE (addr) == PRE_MODIFY
14935 && (!VECTOR_MEM_VSX_P (mode)
14936 || and_op2 != NULL_RTX
14937 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
14939 scratch_or_premodify = XEXP (addr, 0);
14940 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
14942 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14943 addr = XEXP (addr, 1);
14946 if (legitimate_indirect_address_p (addr, false) /* reg */
14947 || legitimate_indexed_address_p (addr, false) /* reg+reg */
14948 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
14949 || (GET_CODE (addr) == AND /* Altivec memory */
14950 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14951 && INTVAL (XEXP (addr, 1)) == -16
14952 && VECTOR_MEM_ALTIVEC_P (mode))
14953 || (rclass == FLOAT_REGS /* legacy float mem */
14954 && GET_MODE_SIZE (mode) == 8
14955 && and_op2 == NULL_RTX
14956 && scratch_or_premodify == scratch
14957 && rs6000_legitimate_offset_address_p (mode, addr, false)))
14960 else if (GET_CODE (addr) == PLUS)
14962 addr_op1 = XEXP (addr, 0);
14963 addr_op2 = XEXP (addr, 1);
14964 gcc_assert (REG_P (addr_op1));
14966 if (TARGET_DEBUG_ADDR)
14968 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
14969 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14970 debug_rtx (addr_op2);
14972 rs6000_emit_move (scratch, addr_op2, Pmode);
14973 emit_insn (gen_rtx_SET (VOIDmode,
14974 scratch_or_premodify,
14975 gen_rtx_PLUS (Pmode,
14978 addr = scratch_or_premodify;
14979 scratch_or_premodify = scratch;
14982 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
14983 || GET_CODE (addr) == CONST_INT || REG_P (addr))
14985 if (TARGET_DEBUG_ADDR)
14987 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14988 rs6000_reg_names[REGNO (scratch_or_premodify)],
14989 GET_MODE_NAME (mode));
14993 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14994 addr = scratch_or_premodify;
14995 scratch_or_premodify = scratch;
14999 gcc_unreachable ();
15004 gcc_unreachable ();
15007 /* If the original address involved a pre-modify that we couldn't use the VSX
15008 memory instruction with update, and we haven't taken care of already,
15009 store the address in the pre-modify register and use that as the
15011 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
15013 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
15014 addr = scratch_or_premodify;
15017 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
15018 memory instruction, recreate the AND now, including the clobber which is
15019 generated by the general ANDSI3/ANDDI3 patterns for the
15020 andi. instruction. */
15021 if (and_op2 != NULL_RTX)
15023 if (! legitimate_indirect_address_p (addr, false))
15025 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
15029 if (TARGET_DEBUG_ADDR)
15031 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
15032 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
15033 debug_rtx (and_op2);
15036 and_rtx = gen_rtx_SET (VOIDmode,
15038 gen_rtx_AND (Pmode,
15042 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
15043 emit_insn (gen_rtx_PARALLEL (VOIDmode,
15044 gen_rtvec (2, and_rtx, cc_clobber)));
15048 /* Adjust the address if it changed. */
15049 if (addr != XEXP (mem, 0))
15051 mem = change_address (mem, mode, addr);
15052 if (TARGET_DEBUG_ADDR)
15053 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
15056 /* Now create the move. */
15058 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
15060 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
15065 /* Target hook to return the cover classes for Integrated Register Allocator.
15066 Cover classes is a set of non-intersected register classes covering all hard
15067 registers used for register allocation purpose. Any move between two
15068 registers of a cover class should be cheaper than load or store of the
15069 registers. The value is array of register classes with LIM_REG_CLASSES used
15072 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
15073 account for the Altivec and Floating registers being subsets of the VSX
15074 register set under VSX, but distinct register sets on pre-VSX machines. */
15076 static const reg_class_t *
15077 rs6000_ira_cover_classes (void)
15079 static const reg_class_t cover_pre_vsx[] = IRA_COVER_CLASSES_PRE_VSX;
15080 static const reg_class_t cover_vsx[] = IRA_COVER_CLASSES_VSX;
15082 return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
15085 /* Allocate a 64-bit stack slot to be used for copying SDmode
15086 values through if this function has any SDmode references. */
15089 rs6000_alloc_sdmode_stack_slot (void)
15093 gimple_stmt_iterator gsi;
15095 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
15098 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
15100 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
15103 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
15104 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
15110 /* Check for any SDmode parameters of the function. */
15111 for (t = DECL_ARGUMENTS (cfun->decl); t; t = DECL_CHAIN (t))
15113 if (TREE_TYPE (t) == error_mark_node)
15116 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
15117 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
15119 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
15120 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
15128 rs6000_instantiate_decls (void)
15130 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
15131 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
15134 /* Given an rtx X being reloaded into a reg required to be
15135 in class CLASS, return the class of reg to actually use.
15136 In general this is just CLASS; but on some machines
15137 in some cases it is preferable to use a more restrictive class.
15139 On the RS/6000, we have to return NO_REGS when we want to reload a
15140 floating-point CONST_DOUBLE to force it to be copied to memory.
15142 We also don't want to reload integer values into floating-point
15143 registers if we can at all help it. In fact, this can
15144 cause reload to die, if it tries to generate a reload of CTR
15145 into a FP register and discovers it doesn't have the memory location
15148 ??? Would it be a good idea to have reload do the converse, that is
15149 try to reload floating modes into FP registers if possible?
15152 static enum reg_class
15153 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
15155 enum machine_mode mode = GET_MODE (x);
15157 if (VECTOR_UNIT_VSX_P (mode)
15158 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
15161 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
15162 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
15163 && easy_vector_constant (x, mode))
15164 return ALTIVEC_REGS;
15166 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
15169 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
15170 return GENERAL_REGS;
15172 /* For VSX, prefer the traditional registers for 64-bit values because we can
15173 use the non-VSX loads. Prefer the Altivec registers if Altivec is
15174 handling the vector operations (i.e. V16QI, V8HI, and V4SI), or if we
15175 prefer Altivec loads.. */
15176 if (rclass == VSX_REGS)
15178 if (GET_MODE_SIZE (mode) <= 8)
15181 if (VECTOR_UNIT_ALTIVEC_P (mode) || VECTOR_MEM_ALTIVEC_P (mode))
15182 return ALTIVEC_REGS;
15190 /* Debug version of rs6000_preferred_reload_class. */
15191 static enum reg_class
15192 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
15194 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
15197 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
15199 reg_class_names[ret], reg_class_names[rclass],
15200 GET_MODE_NAME (GET_MODE (x)));
15206 /* If we are copying between FP or AltiVec registers and anything else, we need
15207 a memory location. The exception is when we are targeting ppc64 and the
15208 move to/from fpr to gpr instructions are available. Also, under VSX, you
15209 can copy vector registers from the FP register set to the Altivec register
15210 set and vice versa. */
15213 rs6000_secondary_memory_needed (enum reg_class class1,
15214 enum reg_class class2,
15215 enum machine_mode mode)
15217 if (class1 == class2)
15220 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
15221 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
15222 between these classes. But we need memory for other things that can go in
15223 FLOAT_REGS like SFmode. */
15225 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
15226 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
15227 || class1 == FLOAT_REGS))
15228 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
15229 && class2 != FLOAT_REGS);
15231 if (class1 == VSX_REGS || class2 == VSX_REGS)
15234 if (class1 == FLOAT_REGS
15235 && (!TARGET_MFPGPR || !TARGET_POWERPC64
15236 || ((mode != DFmode)
15237 && (mode != DDmode)
15238 && (mode != DImode))))
15241 if (class2 == FLOAT_REGS
15242 && (!TARGET_MFPGPR || !TARGET_POWERPC64
15243 || ((mode != DFmode)
15244 && (mode != DDmode)
15245 && (mode != DImode))))
15248 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
15254 /* Debug version of rs6000_secondary_memory_needed. */
15256 rs6000_debug_secondary_memory_needed (enum reg_class class1,
15257 enum reg_class class2,
15258 enum machine_mode mode)
15260 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
15263 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
15264 "class2 = %s, mode = %s\n",
15265 ret ? "true" : "false", reg_class_names[class1],
15266 reg_class_names[class2], GET_MODE_NAME (mode));
15271 /* Return the register class of a scratch register needed to copy IN into
15272 or out of a register in RCLASS in MODE. If it can be done directly,
15273 NO_REGS is returned. */
15275 static enum reg_class
15276 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
15281 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
15283 && MACHOPIC_INDIRECT
15287 /* We cannot copy a symbolic operand directly into anything
15288 other than BASE_REGS for TARGET_ELF. So indicate that a
15289 register from BASE_REGS is needed as an intermediate
15292 On Darwin, pic addresses require a load from memory, which
15293 needs a base register. */
15294 if (rclass != BASE_REGS
15295 && (GET_CODE (in) == SYMBOL_REF
15296 || GET_CODE (in) == HIGH
15297 || GET_CODE (in) == LABEL_REF
15298 || GET_CODE (in) == CONST))
15302 if (GET_CODE (in) == REG)
15304 regno = REGNO (in);
15305 if (regno >= FIRST_PSEUDO_REGISTER)
15307 regno = true_regnum (in);
15308 if (regno >= FIRST_PSEUDO_REGISTER)
15312 else if (GET_CODE (in) == SUBREG)
15314 regno = true_regnum (in);
15315 if (regno >= FIRST_PSEUDO_REGISTER)
15321 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
15323 if (rclass == GENERAL_REGS || rclass == BASE_REGS
15324 || (regno >= 0 && INT_REGNO_P (regno)))
15327 /* Constants, memory, and FP registers can go into FP registers. */
15328 if ((regno == -1 || FP_REGNO_P (regno))
15329 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
15330 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
15332 /* Memory, and FP/altivec registers can go into fp/altivec registers under
15335 && (regno == -1 || VSX_REGNO_P (regno))
15336 && VSX_REG_CLASS_P (rclass))
15339 /* Memory, and AltiVec registers can go into AltiVec registers. */
15340 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
15341 && rclass == ALTIVEC_REGS)
15344 /* We can copy among the CR registers. */
15345 if ((rclass == CR_REGS || rclass == CR0_REGS)
15346 && regno >= 0 && CR_REGNO_P (regno))
15349 /* Otherwise, we need GENERAL_REGS. */
15350 return GENERAL_REGS;
15353 /* Debug version of rs6000_secondary_reload_class. */
15354 static enum reg_class
15355 rs6000_debug_secondary_reload_class (enum reg_class rclass,
15356 enum machine_mode mode, rtx in)
15358 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
15360 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
15361 "mode = %s, input rtx:\n",
15362 reg_class_names[ret], reg_class_names[rclass],
15363 GET_MODE_NAME (mode));
15369 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
15372 rs6000_cannot_change_mode_class (enum machine_mode from,
15373 enum machine_mode to,
15374 enum reg_class rclass)
15376 unsigned from_size = GET_MODE_SIZE (from);
15377 unsigned to_size = GET_MODE_SIZE (to);
15379 if (from_size != to_size)
15381 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
15382 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
15383 && reg_classes_intersect_p (xclass, rclass));
15386 if (TARGET_E500_DOUBLE
15387 && ((((to) == DFmode) + ((from) == DFmode)) == 1
15388 || (((to) == TFmode) + ((from) == TFmode)) == 1
15389 || (((to) == DDmode) + ((from) == DDmode)) == 1
15390 || (((to) == TDmode) + ((from) == TDmode)) == 1
15391 || (((to) == DImode) + ((from) == DImode)) == 1))
15394 /* Since the VSX register set includes traditional floating point registers
15395 and altivec registers, just check for the size being different instead of
15396 trying to check whether the modes are vector modes. Otherwise it won't
15397 allow say DF and DI to change classes. */
15398 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
15399 return (from_size != 8 && from_size != 16);
15401 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
15402 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
15405 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
15406 && reg_classes_intersect_p (GENERAL_REGS, rclass))
15412 /* Debug version of rs6000_cannot_change_mode_class. */
15414 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
15415 enum machine_mode to,
15416 enum reg_class rclass)
15418 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
15421 "rs6000_cannot_change_mode_class, return %s, from = %s, "
15422 "to = %s, rclass = %s\n",
15423 ret ? "true" : "false",
15424 GET_MODE_NAME (from), GET_MODE_NAME (to),
15425 reg_class_names[rclass]);
15430 /* Given a comparison operation, return the bit number in CCR to test. We
15431 know this is a valid comparison.
15433 SCC_P is 1 if this is for an scc. That means that %D will have been
15434 used instead of %C, so the bits will be in different places.
15436 Return -1 if OP isn't a valid comparison for some reason. */
15439 ccr_bit (rtx op, int scc_p)
15441 enum rtx_code code = GET_CODE (op);
15442 enum machine_mode cc_mode;
15447 if (!COMPARISON_P (op))
15450 reg = XEXP (op, 0);
15452 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
15454 cc_mode = GET_MODE (reg);
15455 cc_regnum = REGNO (reg);
15456 base_bit = 4 * (cc_regnum - CR0_REGNO);
15458 validate_condition_mode (code, cc_mode);
15460 /* When generating a sCOND operation, only positive conditions are
15463 || code == EQ || code == GT || code == LT || code == UNORDERED
15464 || code == GTU || code == LTU);
15469 return scc_p ? base_bit + 3 : base_bit + 2;
15471 return base_bit + 2;
15472 case GT: case GTU: case UNLE:
15473 return base_bit + 1;
15474 case LT: case LTU: case UNGE:
15476 case ORDERED: case UNORDERED:
15477 return base_bit + 3;
15480 /* If scc, we will have done a cror to put the bit in the
15481 unordered position. So test that bit. For integer, this is ! LT
15482 unless this is an scc insn. */
15483 return scc_p ? base_bit + 3 : base_bit;
15486 return scc_p ? base_bit + 3 : base_bit + 1;
15489 gcc_unreachable ();
15493 /* Return the GOT register. */
15496 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
15498 /* The second flow pass currently (June 1999) can't update
15499 regs_ever_live without disturbing other parts of the compiler, so
15500 update it here to make the prolog/epilogue code happy. */
15501 if (!can_create_pseudo_p ()
15502 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
15503 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
15505 crtl->uses_pic_offset_table = 1;
15507 return pic_offset_table_rtx;
15510 static rs6000_stack_t stack_info;
15512 /* Function to init struct machine_function.
15513 This will be called, via a pointer variable,
15514 from push_function_context. */
15516 static struct machine_function *
15517 rs6000_init_machine_status (void)
15519 stack_info.reload_completed = 0;
15520 return ggc_alloc_cleared_machine_function ();
15523 /* These macros test for integers and extract the low-order bits. */
15525 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
15526 && GET_MODE (X) == VOIDmode)
15528 #define INT_LOWPART(X) \
15529 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
15532 extract_MB (rtx op)
15535 unsigned long val = INT_LOWPART (op);
15537 /* If the high bit is zero, the value is the first 1 bit we find
15539 if ((val & 0x80000000) == 0)
15541 gcc_assert (val & 0xffffffff);
15544 while (((val <<= 1) & 0x80000000) == 0)
15549 /* If the high bit is set and the low bit is not, or the mask is all
15550 1's, the value is zero. */
15551 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
15554 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15557 while (((val >>= 1) & 1) != 0)
15564 extract_ME (rtx op)
15567 unsigned long val = INT_LOWPART (op);
15569 /* If the low bit is zero, the value is the first 1 bit we find from
15571 if ((val & 1) == 0)
15573 gcc_assert (val & 0xffffffff);
15576 while (((val >>= 1) & 1) == 0)
15582 /* If the low bit is set and the high bit is not, or the mask is all
15583 1's, the value is 31. */
15584 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
15587 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15590 while (((val <<= 1) & 0x80000000) != 0)
15596 /* Locate some local-dynamic symbol still in use by this function
15597 so that we can print its name in some tls_ld pattern. */
15599 static const char *
15600 rs6000_get_some_local_dynamic_name (void)
15604 if (cfun->machine->some_ld_name)
15605 return cfun->machine->some_ld_name;
15607 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
15609 && for_each_rtx (&PATTERN (insn),
15610 rs6000_get_some_local_dynamic_name_1, 0))
15611 return cfun->machine->some_ld_name;
15613 gcc_unreachable ();
15616 /* Helper function for rs6000_get_some_local_dynamic_name. */
15619 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
15623 if (GET_CODE (x) == SYMBOL_REF)
15625 const char *str = XSTR (x, 0);
15626 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
15628 cfun->machine->some_ld_name = str;
15636 /* Write out a function code label. */
15639 rs6000_output_function_entry (FILE *file, const char *fname)
15641 if (fname[0] != '.')
15643 switch (DEFAULT_ABI)
15646 gcc_unreachable ();
15652 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
15661 RS6000_OUTPUT_BASENAME (file, fname);
15664 /* Print an operand. Recognize special options, documented below. */
15667 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
15668 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
15670 #define SMALL_DATA_RELOC "sda21"
15671 #define SMALL_DATA_REG 0
15675 print_operand (FILE *file, rtx x, int code)
15679 unsigned HOST_WIDE_INT uval;
15684 /* Write out an instruction after the call which may be replaced
15685 with glue code by the loader. This depends on the AIX version. */
15686 asm_fprintf (file, RS6000_CALL_GLUE);
15689 /* %a is output_address. */
15692 /* If X is a constant integer whose low-order 5 bits are zero,
15693 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
15694 in the AIX assembler where "sri" with a zero shift count
15695 writes a trash instruction. */
15696 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
15703 /* If constant, low-order 16 bits of constant, unsigned.
15704 Otherwise, write normally. */
15706 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
15708 print_operand (file, x, 0);
15712 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
15713 for 64-bit mask direction. */
15714 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
15717 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
15721 /* X is a CR register. Print the number of the GT bit of the CR. */
15722 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15723 output_operand_lossage ("invalid %%c value");
15725 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
15729 /* Like 'J' but get to the GT bit only. */
15730 gcc_assert (GET_CODE (x) == REG);
15732 /* Bit 1 is GT bit. */
15733 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
15735 /* Add one for shift count in rlinm for scc. */
15736 fprintf (file, "%d", i + 1);
15740 /* X is a CR register. Print the number of the EQ bit of the CR */
15741 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15742 output_operand_lossage ("invalid %%E value");
15744 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
15748 /* X is a CR register. Print the shift count needed to move it
15749 to the high-order four bits. */
15750 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15751 output_operand_lossage ("invalid %%f value");
15753 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
15757 /* Similar, but print the count for the rotate in the opposite
15759 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15760 output_operand_lossage ("invalid %%F value");
15762 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
15766 /* X is a constant integer. If it is negative, print "m",
15767 otherwise print "z". This is to make an aze or ame insn. */
15768 if (GET_CODE (x) != CONST_INT)
15769 output_operand_lossage ("invalid %%G value");
15770 else if (INTVAL (x) >= 0)
15777 /* If constant, output low-order five bits. Otherwise, write
15780 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
15782 print_operand (file, x, 0);
15786 /* If constant, output low-order six bits. Otherwise, write
15789 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
15791 print_operand (file, x, 0);
15795 /* Print `i' if this is a constant, else nothing. */
15801 /* Write the bit number in CCR for jump. */
15802 i = ccr_bit (x, 0);
15804 output_operand_lossage ("invalid %%j code");
15806 fprintf (file, "%d", i);
15810 /* Similar, but add one for shift count in rlinm for scc and pass
15811 scc flag to `ccr_bit'. */
15812 i = ccr_bit (x, 1);
15814 output_operand_lossage ("invalid %%J code");
15816 /* If we want bit 31, write a shift count of zero, not 32. */
15817 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15821 /* X must be a constant. Write the 1's complement of the
15824 output_operand_lossage ("invalid %%k value");
15826 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
15830 /* X must be a symbolic constant on ELF. Write an
15831 expression suitable for an 'addi' that adds in the low 16
15832 bits of the MEM. */
15833 if (GET_CODE (x) == CONST)
15835 if (GET_CODE (XEXP (x, 0)) != PLUS
15836 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
15837 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
15838 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
15839 output_operand_lossage ("invalid %%K value");
15841 print_operand_address (file, x);
15842 fputs ("@l", file);
15845 /* %l is output_asm_label. */
15848 /* Write second word of DImode or DFmode reference. Works on register
15849 or non-indexed memory only. */
15850 if (GET_CODE (x) == REG)
15851 fputs (reg_names[REGNO (x) + 1], file);
15852 else if (GET_CODE (x) == MEM)
15854 /* Handle possible auto-increment. Since it is pre-increment and
15855 we have already done it, we can just use an offset of word. */
15856 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15857 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15858 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15860 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15861 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15864 output_address (XEXP (adjust_address_nv (x, SImode,
15868 if (small_data_operand (x, GET_MODE (x)))
15869 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15870 reg_names[SMALL_DATA_REG]);
15875 /* MB value for a mask operand. */
15876 if (! mask_operand (x, SImode))
15877 output_operand_lossage ("invalid %%m value");
15879 fprintf (file, "%d", extract_MB (x));
15883 /* ME value for a mask operand. */
15884 if (! mask_operand (x, SImode))
15885 output_operand_lossage ("invalid %%M value");
15887 fprintf (file, "%d", extract_ME (x));
15890 /* %n outputs the negative of its operand. */
15893 /* Write the number of elements in the vector times 4. */
15894 if (GET_CODE (x) != PARALLEL)
15895 output_operand_lossage ("invalid %%N value");
15897 fprintf (file, "%d", XVECLEN (x, 0) * 4);
15901 /* Similar, but subtract 1 first. */
15902 if (GET_CODE (x) != PARALLEL)
15903 output_operand_lossage ("invalid %%O value");
15905 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
15909 /* X is a CONST_INT that is a power of two. Output the logarithm. */
15911 || INT_LOWPART (x) < 0
15912 || (i = exact_log2 (INT_LOWPART (x))) < 0)
15913 output_operand_lossage ("invalid %%p value");
15915 fprintf (file, "%d", i);
15919 /* The operand must be an indirect memory reference. The result
15920 is the register name. */
15921 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
15922 || REGNO (XEXP (x, 0)) >= 32)
15923 output_operand_lossage ("invalid %%P value");
15925 fputs (reg_names[REGNO (XEXP (x, 0))], file);
15929 /* This outputs the logical code corresponding to a boolean
15930 expression. The expression may have one or both operands
15931 negated (if one, only the first one). For condition register
15932 logical operations, it will also treat the negated
15933 CR codes as NOTs, but not handle NOTs of them. */
15935 const char *const *t = 0;
15937 enum rtx_code code = GET_CODE (x);
15938 static const char * const tbl[3][3] = {
15939 { "and", "andc", "nor" },
15940 { "or", "orc", "nand" },
15941 { "xor", "eqv", "xor" } };
15945 else if (code == IOR)
15947 else if (code == XOR)
15950 output_operand_lossage ("invalid %%q value");
15952 if (GET_CODE (XEXP (x, 0)) != NOT)
15956 if (GET_CODE (XEXP (x, 1)) == NOT)
15974 /* X is a CR register. Print the mask for `mtcrf'. */
15975 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15976 output_operand_lossage ("invalid %%R value");
15978 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
15982 /* Low 5 bits of 32 - value */
15984 output_operand_lossage ("invalid %%s value");
15986 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
15990 /* PowerPC64 mask position. All 0's is excluded.
15991 CONST_INT 32-bit mask is considered sign-extended so any
15992 transition must occur within the CONST_INT, not on the boundary. */
15993 if (! mask64_operand (x, DImode))
15994 output_operand_lossage ("invalid %%S value");
15996 uval = INT_LOWPART (x);
15998 if (uval & 1) /* Clear Left */
16000 #if HOST_BITS_PER_WIDE_INT > 64
16001 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
16005 else /* Clear Right */
16008 #if HOST_BITS_PER_WIDE_INT > 64
16009 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
16015 gcc_assert (i >= 0);
16016 fprintf (file, "%d", i);
16020 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
16021 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
16023 /* Bit 3 is OV bit. */
16024 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
16026 /* If we want bit 31, write a shift count of zero, not 32. */
16027 fprintf (file, "%d", i == 31 ? 0 : i + 1);
16031 /* Print the symbolic name of a branch target register. */
16032 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
16033 && REGNO (x) != CTR_REGNO))
16034 output_operand_lossage ("invalid %%T value");
16035 else if (REGNO (x) == LR_REGNO)
16036 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
16038 fputs ("ctr", file);
16042 /* High-order 16 bits of constant for use in unsigned operand. */
16044 output_operand_lossage ("invalid %%u value");
16046 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
16047 (INT_LOWPART (x) >> 16) & 0xffff);
16051 /* High-order 16 bits of constant for use in signed operand. */
16053 output_operand_lossage ("invalid %%v value");
16055 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
16056 (INT_LOWPART (x) >> 16) & 0xffff);
16060 /* Print `u' if this has an auto-increment or auto-decrement. */
16061 if (GET_CODE (x) == MEM
16062 && (GET_CODE (XEXP (x, 0)) == PRE_INC
16063 || GET_CODE (XEXP (x, 0)) == PRE_DEC
16064 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
16069 /* Print the trap code for this operand. */
16070 switch (GET_CODE (x))
16073 fputs ("eq", file); /* 4 */
16076 fputs ("ne", file); /* 24 */
16079 fputs ("lt", file); /* 16 */
16082 fputs ("le", file); /* 20 */
16085 fputs ("gt", file); /* 8 */
16088 fputs ("ge", file); /* 12 */
16091 fputs ("llt", file); /* 2 */
16094 fputs ("lle", file); /* 6 */
16097 fputs ("lgt", file); /* 1 */
16100 fputs ("lge", file); /* 5 */
16103 gcc_unreachable ();
16108 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
16111 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
16112 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
16114 print_operand (file, x, 0);
16118 /* MB value for a PowerPC64 rldic operand. */
16119 val = (GET_CODE (x) == CONST_INT
16120 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
16125 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
16126 if ((val <<= 1) < 0)
16129 #if HOST_BITS_PER_WIDE_INT == 32
16130 if (GET_CODE (x) == CONST_INT && i >= 0)
16131 i += 32; /* zero-extend high-part was all 0's */
16132 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
16134 val = CONST_DOUBLE_LOW (x);
16140 for ( ; i < 64; i++)
16141 if ((val <<= 1) < 0)
16146 fprintf (file, "%d", i + 1);
16150 /* X is a FPR or Altivec register used in a VSX context. */
16151 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
16152 output_operand_lossage ("invalid %%x value");
16155 int reg = REGNO (x);
16156 int vsx_reg = (FP_REGNO_P (reg)
16158 : reg - FIRST_ALTIVEC_REGNO + 32);
16160 #ifdef TARGET_REGNAMES
16161 if (TARGET_REGNAMES)
16162 fprintf (file, "%%vs%d", vsx_reg);
16165 fprintf (file, "%d", vsx_reg);
16170 if (GET_CODE (x) == MEM
16171 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
16172 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
16173 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
16178 /* Like 'L', for third word of TImode */
16179 if (GET_CODE (x) == REG)
16180 fputs (reg_names[REGNO (x) + 2], file);
16181 else if (GET_CODE (x) == MEM)
16183 if (GET_CODE (XEXP (x, 0)) == PRE_INC
16184 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
16185 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
16186 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
16187 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
16189 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
16190 if (small_data_operand (x, GET_MODE (x)))
16191 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16192 reg_names[SMALL_DATA_REG]);
16197 /* X is a SYMBOL_REF. Write out the name preceded by a
16198 period and without any trailing data in brackets. Used for function
16199 names. If we are configured for System V (or the embedded ABI) on
16200 the PowerPC, do not emit the period, since those systems do not use
16201 TOCs and the like. */
16202 gcc_assert (GET_CODE (x) == SYMBOL_REF);
16204 /* Mark the decl as referenced so that cgraph will output the
16206 if (SYMBOL_REF_DECL (x))
16207 mark_decl_referenced (SYMBOL_REF_DECL (x));
16209 /* For macho, check to see if we need a stub. */
16212 const char *name = XSTR (x, 0);
16214 if (darwin_emit_branch_islands
16215 && MACHOPIC_INDIRECT
16216 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
16217 name = machopic_indirection_name (x, /*stub_p=*/true);
16219 assemble_name (file, name);
16221 else if (!DOT_SYMBOLS)
16222 assemble_name (file, XSTR (x, 0));
16224 rs6000_output_function_entry (file, XSTR (x, 0));
16228 /* Like 'L', for last word of TImode. */
16229 if (GET_CODE (x) == REG)
16230 fputs (reg_names[REGNO (x) + 3], file);
16231 else if (GET_CODE (x) == MEM)
16233 if (GET_CODE (XEXP (x, 0)) == PRE_INC
16234 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
16235 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
16236 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
16237 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
16239 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
16240 if (small_data_operand (x, GET_MODE (x)))
16241 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16242 reg_names[SMALL_DATA_REG]);
16246 /* Print AltiVec or SPE memory operand. */
16251 gcc_assert (GET_CODE (x) == MEM);
16255 /* Ugly hack because %y is overloaded. */
16256 if ((TARGET_SPE || TARGET_E500_DOUBLE)
16257 && (GET_MODE_SIZE (GET_MODE (x)) == 8
16258 || GET_MODE (x) == TFmode
16259 || GET_MODE (x) == TImode))
16261 /* Handle [reg]. */
16262 if (GET_CODE (tmp) == REG)
16264 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
16267 /* Handle [reg+UIMM]. */
16268 else if (GET_CODE (tmp) == PLUS &&
16269 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
16273 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
16275 x = INTVAL (XEXP (tmp, 1));
16276 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
16280 /* Fall through. Must be [reg+reg]. */
16282 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
16283 && GET_CODE (tmp) == AND
16284 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
16285 && INTVAL (XEXP (tmp, 1)) == -16)
16286 tmp = XEXP (tmp, 0);
16287 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
16288 && GET_CODE (tmp) == PRE_MODIFY)
16289 tmp = XEXP (tmp, 1);
16290 if (GET_CODE (tmp) == REG)
16291 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
16294 if (!GET_CODE (tmp) == PLUS
16295 || !REG_P (XEXP (tmp, 0))
16296 || !REG_P (XEXP (tmp, 1)))
16298 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
16302 if (REGNO (XEXP (tmp, 0)) == 0)
16303 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
16304 reg_names[ REGNO (XEXP (tmp, 0)) ]);
16306 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
16307 reg_names[ REGNO (XEXP (tmp, 1)) ]);
16313 if (GET_CODE (x) == REG)
16314 fprintf (file, "%s", reg_names[REGNO (x)]);
16315 else if (GET_CODE (x) == MEM)
16317 /* We need to handle PRE_INC and PRE_DEC here, since we need to
16318 know the width from the mode. */
16319 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
16320 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
16321 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
16322 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
16323 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
16324 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
16325 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
16326 output_address (XEXP (XEXP (x, 0), 1));
16328 output_address (XEXP (x, 0));
16332 if (toc_relative_expr_p (x))
16333 /* This hack along with a corresponding hack in
16334 rs6000_output_addr_const_extra arranges to output addends
16335 where the assembler expects to find them. eg.
16336 (const (plus (unspec [symbol_ref ("x") tocrel]) 4))
16337 without this hack would be output as "x@toc+4". We
16339 output_addr_const (file, tocrel_base);
16341 output_addr_const (file, x);
16346 assemble_name (file, rs6000_get_some_local_dynamic_name ());
16350 output_operand_lossage ("invalid %%xn code");
16354 /* Print the address of an operand. */
16357 print_operand_address (FILE *file, rtx x)
16359 if (GET_CODE (x) == REG)
16360 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
16361 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
16362 || GET_CODE (x) == LABEL_REF)
16364 output_addr_const (file, x);
16365 if (small_data_operand (x, GET_MODE (x)))
16366 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16367 reg_names[SMALL_DATA_REG]);
16369 gcc_assert (!TARGET_TOC);
16371 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
16373 gcc_assert (REG_P (XEXP (x, 0)));
16374 if (REGNO (XEXP (x, 0)) == 0)
16375 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
16376 reg_names[ REGNO (XEXP (x, 0)) ]);
16378 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
16379 reg_names[ REGNO (XEXP (x, 1)) ]);
16381 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
16382 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
16383 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
16385 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
16386 && CONSTANT_P (XEXP (x, 1)))
16388 fprintf (file, "lo16(");
16389 output_addr_const (file, XEXP (x, 1));
16390 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16393 else if (legitimate_constant_pool_address_p (x, true))
16395 /* This hack along with a corresponding hack in
16396 rs6000_output_addr_const_extra arranges to output addends
16397 where the assembler expects to find them. eg.
16399 . (const (plus (unspec [symbol_ref ("x") tocrel]) 8)))
16400 without this hack would be output as "x@toc+8@l(9)". We
16401 want "x+8@toc@l(9)". */
16402 output_addr_const (file, tocrel_base);
16403 if (GET_CODE (x) == LO_SUM)
16404 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16406 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
16409 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
16410 && CONSTANT_P (XEXP (x, 1)))
16412 output_addr_const (file, XEXP (x, 1));
16413 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16417 gcc_unreachable ();
16420 /* Implement TARGET_OUTPUT_ADDR_CONST_EXTRA. */
16423 rs6000_output_addr_const_extra (FILE *file, rtx x)
16425 if (GET_CODE (x) == UNSPEC)
16426 switch (XINT (x, 1))
16428 case UNSPEC_TOCREL:
16429 gcc_assert (GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF);
16430 output_addr_const (file, XVECEXP (x, 0, 0));
16431 if (x == tocrel_base && tocrel_offset != const0_rtx)
16433 if (INTVAL (tocrel_offset) >= 0)
16434 fprintf (file, "+");
16435 output_addr_const (file, tocrel_offset);
16437 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
16440 assemble_name (file, toc_label_name);
16442 else if (TARGET_ELF)
16443 fputs ("@toc", file);
16447 case UNSPEC_MACHOPIC_OFFSET:
16448 output_addr_const (file, XVECEXP (x, 0, 0));
16450 machopic_output_function_base_name (file);
16457 /* Target hook for assembling integer objects. The PowerPC version has
16458 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
16459 is defined. It also needs to handle DI-mode objects on 64-bit
16463 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
16465 #ifdef RELOCATABLE_NEEDS_FIXUP
16466 /* Special handling for SI values. */
16467 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
16469 static int recurse = 0;
16471 /* For -mrelocatable, we mark all addresses that need to be fixed up
16472 in the .fixup section. */
16473 if (TARGET_RELOCATABLE
16474 && in_section != toc_section
16475 && in_section != text_section
16476 && !unlikely_text_section_p (in_section)
16478 && GET_CODE (x) != CONST_INT
16479 && GET_CODE (x) != CONST_DOUBLE
16485 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
16487 ASM_OUTPUT_LABEL (asm_out_file, buf);
16488 fprintf (asm_out_file, "\t.long\t(");
16489 output_addr_const (asm_out_file, x);
16490 fprintf (asm_out_file, ")@fixup\n");
16491 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
16492 ASM_OUTPUT_ALIGN (asm_out_file, 2);
16493 fprintf (asm_out_file, "\t.long\t");
16494 assemble_name (asm_out_file, buf);
16495 fprintf (asm_out_file, "\n\t.previous\n");
16499 /* Remove initial .'s to turn a -mcall-aixdesc function
16500 address into the address of the descriptor, not the function
16502 else if (GET_CODE (x) == SYMBOL_REF
16503 && XSTR (x, 0)[0] == '.'
16504 && DEFAULT_ABI == ABI_AIX)
16506 const char *name = XSTR (x, 0);
16507 while (*name == '.')
16510 fprintf (asm_out_file, "\t.long\t%s\n", name);
16514 #endif /* RELOCATABLE_NEEDS_FIXUP */
16515 return default_assemble_integer (x, size, aligned_p);
16518 #ifdef HAVE_GAS_HIDDEN
16519 /* Emit an assembler directive to set symbol visibility for DECL to
16520 VISIBILITY_TYPE. */
16523 rs6000_assemble_visibility (tree decl, int vis)
16525 /* Functions need to have their entry point symbol visibility set as
16526 well as their descriptor symbol visibility. */
16527 if (DEFAULT_ABI == ABI_AIX
16529 && TREE_CODE (decl) == FUNCTION_DECL)
16531 static const char * const visibility_types[] = {
16532 NULL, "internal", "hidden", "protected"
16535 const char *name, *type;
16537 name = ((* targetm.strip_name_encoding)
16538 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
16539 type = visibility_types[vis];
16541 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
16542 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
16545 default_assemble_visibility (decl, vis);
16550 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
16552 /* Reversal of FP compares takes care -- an ordered compare
16553 becomes an unordered compare and vice versa. */
16554 if (mode == CCFPmode
16555 && (!flag_finite_math_only
16556 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
16557 || code == UNEQ || code == LTGT))
16558 return reverse_condition_maybe_unordered (code);
16560 return reverse_condition (code);
16563 /* Generate a compare for CODE. Return a brand-new rtx that
16564 represents the result of the compare. */
16567 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
16569 enum machine_mode comp_mode;
16570 rtx compare_result;
16571 enum rtx_code code = GET_CODE (cmp);
16572 rtx op0 = XEXP (cmp, 0);
16573 rtx op1 = XEXP (cmp, 1);
16575 if (FLOAT_MODE_P (mode))
16576 comp_mode = CCFPmode;
16577 else if (code == GTU || code == LTU
16578 || code == GEU || code == LEU)
16579 comp_mode = CCUNSmode;
16580 else if ((code == EQ || code == NE)
16581 && GET_CODE (op0) == SUBREG
16582 && GET_CODE (op1) == SUBREG
16583 && SUBREG_PROMOTED_UNSIGNED_P (op0)
16584 && SUBREG_PROMOTED_UNSIGNED_P (op1))
16585 /* These are unsigned values, perhaps there will be a later
16586 ordering compare that can be shared with this one.
16587 Unfortunately we cannot detect the signedness of the operands
16588 for non-subregs. */
16589 comp_mode = CCUNSmode;
16591 comp_mode = CCmode;
16593 /* First, the compare. */
16594 compare_result = gen_reg_rtx (comp_mode);
16596 /* E500 FP compare instructions on the GPRs. Yuck! */
16597 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
16598 && FLOAT_MODE_P (mode))
16600 rtx cmp, or_result, compare_result2;
16601 enum machine_mode op_mode = GET_MODE (op0);
16603 if (op_mode == VOIDmode)
16604 op_mode = GET_MODE (op1);
16606 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
16607 This explains the following mess. */
16611 case EQ: case UNEQ: case NE: case LTGT:
16615 cmp = (flag_finite_math_only && !flag_trapping_math)
16616 ? gen_tstsfeq_gpr (compare_result, op0, op1)
16617 : gen_cmpsfeq_gpr (compare_result, op0, op1);
16621 cmp = (flag_finite_math_only && !flag_trapping_math)
16622 ? gen_tstdfeq_gpr (compare_result, op0, op1)
16623 : gen_cmpdfeq_gpr (compare_result, op0, op1);
16627 cmp = (flag_finite_math_only && !flag_trapping_math)
16628 ? gen_tsttfeq_gpr (compare_result, op0, op1)
16629 : gen_cmptfeq_gpr (compare_result, op0, op1);
16633 gcc_unreachable ();
16637 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
16641 cmp = (flag_finite_math_only && !flag_trapping_math)
16642 ? gen_tstsfgt_gpr (compare_result, op0, op1)
16643 : gen_cmpsfgt_gpr (compare_result, op0, op1);
16647 cmp = (flag_finite_math_only && !flag_trapping_math)
16648 ? gen_tstdfgt_gpr (compare_result, op0, op1)
16649 : gen_cmpdfgt_gpr (compare_result, op0, op1);
16653 cmp = (flag_finite_math_only && !flag_trapping_math)
16654 ? gen_tsttfgt_gpr (compare_result, op0, op1)
16655 : gen_cmptfgt_gpr (compare_result, op0, op1);
16659 gcc_unreachable ();
16663 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
16667 cmp = (flag_finite_math_only && !flag_trapping_math)
16668 ? gen_tstsflt_gpr (compare_result, op0, op1)
16669 : gen_cmpsflt_gpr (compare_result, op0, op1);
16673 cmp = (flag_finite_math_only && !flag_trapping_math)
16674 ? gen_tstdflt_gpr (compare_result, op0, op1)
16675 : gen_cmpdflt_gpr (compare_result, op0, op1);
16679 cmp = (flag_finite_math_only && !flag_trapping_math)
16680 ? gen_tsttflt_gpr (compare_result, op0, op1)
16681 : gen_cmptflt_gpr (compare_result, op0, op1);
16685 gcc_unreachable ();
16689 gcc_unreachable ();
16692 /* Synthesize LE and GE from LT/GT || EQ. */
16693 if (code == LE || code == GE || code == LEU || code == GEU)
16699 case LE: code = LT; break;
16700 case GE: code = GT; break;
16701 case LEU: code = LT; break;
16702 case GEU: code = GT; break;
16703 default: gcc_unreachable ();
16706 compare_result2 = gen_reg_rtx (CCFPmode);
16712 cmp = (flag_finite_math_only && !flag_trapping_math)
16713 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
16714 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
16718 cmp = (flag_finite_math_only && !flag_trapping_math)
16719 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
16720 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
16724 cmp = (flag_finite_math_only && !flag_trapping_math)
16725 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
16726 : gen_cmptfeq_gpr (compare_result2, op0, op1);
16730 gcc_unreachable ();
16734 /* OR them together. */
16735 or_result = gen_reg_rtx (CCFPmode);
16736 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
16738 compare_result = or_result;
16743 if (code == NE || code == LTGT)
16753 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
16754 CLOBBERs to match cmptf_internal2 pattern. */
16755 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
16756 && GET_MODE (op0) == TFmode
16757 && !TARGET_IEEEQUAD
16758 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
16759 emit_insn (gen_rtx_PARALLEL (VOIDmode,
16761 gen_rtx_SET (VOIDmode,
16763 gen_rtx_COMPARE (comp_mode, op0, op1)),
16764 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16765 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16766 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16767 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16768 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16769 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16770 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16771 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16772 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (Pmode)))));
16773 else if (GET_CODE (op1) == UNSPEC
16774 && XINT (op1, 1) == UNSPEC_SP_TEST)
16776 rtx op1b = XVECEXP (op1, 0, 0);
16777 comp_mode = CCEQmode;
16778 compare_result = gen_reg_rtx (CCEQmode);
16780 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
16782 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
16785 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
16786 gen_rtx_COMPARE (comp_mode, op0, op1)));
16789 /* Some kinds of FP comparisons need an OR operation;
16790 under flag_finite_math_only we don't bother. */
16791 if (FLOAT_MODE_P (mode)
16792 && !flag_finite_math_only
16793 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
16794 && (code == LE || code == GE
16795 || code == UNEQ || code == LTGT
16796 || code == UNGT || code == UNLT))
16798 enum rtx_code or1, or2;
16799 rtx or1_rtx, or2_rtx, compare2_rtx;
16800 rtx or_result = gen_reg_rtx (CCEQmode);
16804 case LE: or1 = LT; or2 = EQ; break;
16805 case GE: or1 = GT; or2 = EQ; break;
16806 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
16807 case LTGT: or1 = LT; or2 = GT; break;
16808 case UNGT: or1 = UNORDERED; or2 = GT; break;
16809 case UNLT: or1 = UNORDERED; or2 = LT; break;
16810 default: gcc_unreachable ();
16812 validate_condition_mode (or1, comp_mode);
16813 validate_condition_mode (or2, comp_mode);
16814 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
16815 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
16816 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
16817 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
16819 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
16821 compare_result = or_result;
16825 validate_condition_mode (code, GET_MODE (compare_result));
16827 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
16831 /* Emit the RTL for an sISEL pattern. */
16834 rs6000_emit_sISEL (enum machine_mode mode ATTRIBUTE_UNUSED, rtx operands[])
16836 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
16840 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
16843 enum machine_mode op_mode;
16844 enum rtx_code cond_code;
16845 rtx result = operands[0];
16847 if (TARGET_ISEL && (mode == SImode || mode == DImode))
16849 rs6000_emit_sISEL (mode, operands);
16853 condition_rtx = rs6000_generate_compare (operands[1], mode);
16854 cond_code = GET_CODE (condition_rtx);
16856 if (FLOAT_MODE_P (mode)
16857 && !TARGET_FPRS && TARGET_HARD_FLOAT)
16861 PUT_MODE (condition_rtx, SImode);
16862 t = XEXP (condition_rtx, 0);
16864 gcc_assert (cond_code == NE || cond_code == EQ);
16866 if (cond_code == NE)
16867 emit_insn (gen_e500_flip_gt_bit (t, t));
16869 emit_insn (gen_move_from_CR_gt_bit (result, t));
16873 if (cond_code == NE
16874 || cond_code == GE || cond_code == LE
16875 || cond_code == GEU || cond_code == LEU
16876 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
16878 rtx not_result = gen_reg_rtx (CCEQmode);
16879 rtx not_op, rev_cond_rtx;
16880 enum machine_mode cc_mode;
16882 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
16884 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
16885 SImode, XEXP (condition_rtx, 0), const0_rtx);
16886 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
16887 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
16888 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
16891 op_mode = GET_MODE (XEXP (operands[1], 0));
16892 if (op_mode == VOIDmode)
16893 op_mode = GET_MODE (XEXP (operands[1], 1));
16895 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
16897 PUT_MODE (condition_rtx, DImode);
16898 convert_move (result, condition_rtx, 0);
16902 PUT_MODE (condition_rtx, SImode);
16903 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
16907 /* Emit a branch of kind CODE to location LOC. */
16910 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
16912 rtx condition_rtx, loc_ref;
16914 condition_rtx = rs6000_generate_compare (operands[0], mode);
16915 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
16916 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
16917 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
16918 loc_ref, pc_rtx)));
16921 /* Return the string to output a conditional branch to LABEL, which is
16922 the operand number of the label, or -1 if the branch is really a
16923 conditional return.
16925 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
16926 condition code register and its mode specifies what kind of
16927 comparison we made.
16929 REVERSED is nonzero if we should reverse the sense of the comparison.
16931 INSN is the insn. */
16934 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
16936 static char string[64];
16937 enum rtx_code code = GET_CODE (op);
16938 rtx cc_reg = XEXP (op, 0);
16939 enum machine_mode mode = GET_MODE (cc_reg);
16940 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
16941 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
16942 int really_reversed = reversed ^ need_longbranch;
16948 validate_condition_mode (code, mode);
16950 /* Work out which way this really branches. We could use
16951 reverse_condition_maybe_unordered here always but this
16952 makes the resulting assembler clearer. */
16953 if (really_reversed)
16955 /* Reversal of FP compares takes care -- an ordered compare
16956 becomes an unordered compare and vice versa. */
16957 if (mode == CCFPmode)
16958 code = reverse_condition_maybe_unordered (code);
16960 code = reverse_condition (code);
16963 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
16965 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
16970 /* Opposite of GT. */
16979 gcc_unreachable ();
16985 /* Not all of these are actually distinct opcodes, but
16986 we distinguish them for clarity of the resulting assembler. */
16987 case NE: case LTGT:
16988 ccode = "ne"; break;
16989 case EQ: case UNEQ:
16990 ccode = "eq"; break;
16992 ccode = "ge"; break;
16993 case GT: case GTU: case UNGT:
16994 ccode = "gt"; break;
16996 ccode = "le"; break;
16997 case LT: case LTU: case UNLT:
16998 ccode = "lt"; break;
16999 case UNORDERED: ccode = "un"; break;
17000 case ORDERED: ccode = "nu"; break;
17001 case UNGE: ccode = "nl"; break;
17002 case UNLE: ccode = "ng"; break;
17004 gcc_unreachable ();
17007 /* Maybe we have a guess as to how likely the branch is.
17008 The old mnemonics don't have a way to specify this information. */
17010 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
17011 if (note != NULL_RTX)
17013 /* PROB is the difference from 50%. */
17014 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
17016 /* Only hint for highly probable/improbable branches on newer
17017 cpus as static prediction overrides processor dynamic
17018 prediction. For older cpus we may as well always hint, but
17019 assume not taken for branches that are very close to 50% as a
17020 mispredicted taken branch is more expensive than a
17021 mispredicted not-taken branch. */
17022 if (rs6000_always_hint
17023 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
17024 && br_prob_note_reliable_p (note)))
17026 if (abs (prob) > REG_BR_PROB_BASE / 20
17027 && ((prob > 0) ^ need_longbranch))
17035 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
17037 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
17039 /* We need to escape any '%' characters in the reg_names string.
17040 Assume they'd only be the first character.... */
17041 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
17043 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
17047 /* If the branch distance was too far, we may have to use an
17048 unconditional branch to go the distance. */
17049 if (need_longbranch)
17050 s += sprintf (s, ",$+8\n\tb %s", label);
17052 s += sprintf (s, ",%s", label);
17058 /* Return the string to flip the GT bit on a CR. */
17060 output_e500_flip_gt_bit (rtx dst, rtx src)
17062 static char string[64];
17065 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
17066 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
17069 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
17070 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
17072 sprintf (string, "crnot %d,%d", a, b);
17076 /* Return insn for VSX or Altivec comparisons. */
17079 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
17082 enum machine_mode mode = GET_MODE (op0);
17090 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
17096 mask = gen_reg_rtx (mode);
17097 emit_insn (gen_rtx_SET (VOIDmode,
17099 gen_rtx_fmt_ee (code, mode, op0, op1)));
17106 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
17107 DMODE is expected destination mode. This is a recursive function. */
17110 rs6000_emit_vector_compare (enum rtx_code rcode,
17112 enum machine_mode dmode)
17115 bool swap_operands = false;
17116 bool try_again = false;
17118 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
17119 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
17121 /* See if the comparison works as is. */
17122 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
17130 swap_operands = true;
17135 swap_operands = true;
17143 /* Invert condition and try again.
17144 e.g., A != B becomes ~(A==B). */
17146 enum rtx_code rev_code;
17147 enum insn_code nor_code;
17150 rev_code = reverse_condition_maybe_unordered (rcode);
17151 if (rev_code == UNKNOWN)
17154 nor_code = optab_handler (one_cmpl_optab, dmode);
17155 if (nor_code == CODE_FOR_nothing)
17158 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
17162 mask = gen_reg_rtx (dmode);
17163 emit_insn (GEN_FCN (nor_code) (mask, mask2));
17171 /* Try GT/GTU/LT/LTU OR EQ */
17174 enum insn_code ior_code;
17175 enum rtx_code new_code;
17196 gcc_unreachable ();
17199 ior_code = optab_handler (ior_optab, dmode);
17200 if (ior_code == CODE_FOR_nothing)
17203 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
17207 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
17211 mask = gen_reg_rtx (dmode);
17212 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
17230 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
17235 /* You only get two chances. */
17239 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
17240 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
17241 operands for the relation operation COND. */
17244 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
17245 rtx cond, rtx cc_op0, rtx cc_op1)
17247 enum machine_mode dest_mode = GET_MODE (dest);
17248 enum rtx_code rcode = GET_CODE (cond);
17249 enum machine_mode cc_mode = CCmode;
17253 bool invert_move = false;
17255 if (VECTOR_UNIT_NONE_P (dest_mode))
17260 /* Swap operands if we can, and fall back to doing the operation as
17261 specified, and doing a NOR to invert the test. */
17267 /* Invert condition and try again.
17268 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
17269 invert_move = true;
17270 rcode = reverse_condition_maybe_unordered (rcode);
17271 if (rcode == UNKNOWN)
17275 /* Mark unsigned tests with CCUNSmode. */
17280 cc_mode = CCUNSmode;
17287 /* Get the vector mask for the given relational operations. */
17288 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
17296 op_true = op_false;
17300 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
17301 emit_insn (gen_rtx_SET (VOIDmode,
17303 gen_rtx_IF_THEN_ELSE (dest_mode,
17310 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
17311 operands of the last comparison is nonzero/true, FALSE_COND if it
17312 is zero/false. Return 0 if the hardware has no such operation. */
17315 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
17317 enum rtx_code code = GET_CODE (op);
17318 rtx op0 = XEXP (op, 0);
17319 rtx op1 = XEXP (op, 1);
17320 REAL_VALUE_TYPE c1;
17321 enum machine_mode compare_mode = GET_MODE (op0);
17322 enum machine_mode result_mode = GET_MODE (dest);
17324 bool is_against_zero;
17326 /* These modes should always match. */
17327 if (GET_MODE (op1) != compare_mode
17328 /* In the isel case however, we can use a compare immediate, so
17329 op1 may be a small constant. */
17330 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
17332 if (GET_MODE (true_cond) != result_mode)
17334 if (GET_MODE (false_cond) != result_mode)
17337 /* First, work out if the hardware can do this at all, or
17338 if it's too slow.... */
17339 if (!FLOAT_MODE_P (compare_mode))
17342 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
17345 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
17346 && SCALAR_FLOAT_MODE_P (compare_mode))
17349 is_against_zero = op1 == CONST0_RTX (compare_mode);
17351 /* A floating-point subtract might overflow, underflow, or produce
17352 an inexact result, thus changing the floating-point flags, so it
17353 can't be generated if we care about that. It's safe if one side
17354 of the construct is zero, since then no subtract will be
17356 if (SCALAR_FLOAT_MODE_P (compare_mode)
17357 && flag_trapping_math && ! is_against_zero)
17360 /* Eliminate half of the comparisons by switching operands, this
17361 makes the remaining code simpler. */
17362 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
17363 || code == LTGT || code == LT || code == UNLE)
17365 code = reverse_condition_maybe_unordered (code);
17367 true_cond = false_cond;
17371 /* UNEQ and LTGT take four instructions for a comparison with zero,
17372 it'll probably be faster to use a branch here too. */
17373 if (code == UNEQ && HONOR_NANS (compare_mode))
17376 if (GET_CODE (op1) == CONST_DOUBLE)
17377 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
17379 /* We're going to try to implement comparisons by performing
17380 a subtract, then comparing against zero. Unfortunately,
17381 Inf - Inf is NaN which is not zero, and so if we don't
17382 know that the operand is finite and the comparison
17383 would treat EQ different to UNORDERED, we can't do it. */
17384 if (HONOR_INFINITIES (compare_mode)
17385 && code != GT && code != UNGE
17386 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
17387 /* Constructs of the form (a OP b ? a : b) are safe. */
17388 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
17389 || (! rtx_equal_p (op0, true_cond)
17390 && ! rtx_equal_p (op1, true_cond))))
17393 /* At this point we know we can use fsel. */
17395 /* Reduce the comparison to a comparison against zero. */
17396 if (! is_against_zero)
17398 temp = gen_reg_rtx (compare_mode);
17399 emit_insn (gen_rtx_SET (VOIDmode, temp,
17400 gen_rtx_MINUS (compare_mode, op0, op1)));
17402 op1 = CONST0_RTX (compare_mode);
17405 /* If we don't care about NaNs we can reduce some of the comparisons
17406 down to faster ones. */
17407 if (! HONOR_NANS (compare_mode))
17413 true_cond = false_cond;
17426 /* Now, reduce everything down to a GE. */
17433 temp = gen_reg_rtx (compare_mode);
17434 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17439 temp = gen_reg_rtx (compare_mode);
17440 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
17445 temp = gen_reg_rtx (compare_mode);
17446 emit_insn (gen_rtx_SET (VOIDmode, temp,
17447 gen_rtx_NEG (compare_mode,
17448 gen_rtx_ABS (compare_mode, op0))));
17453 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
17454 temp = gen_reg_rtx (result_mode);
17455 emit_insn (gen_rtx_SET (VOIDmode, temp,
17456 gen_rtx_IF_THEN_ELSE (result_mode,
17457 gen_rtx_GE (VOIDmode,
17459 true_cond, false_cond)));
17460 false_cond = true_cond;
17463 temp = gen_reg_rtx (compare_mode);
17464 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17469 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
17470 temp = gen_reg_rtx (result_mode);
17471 emit_insn (gen_rtx_SET (VOIDmode, temp,
17472 gen_rtx_IF_THEN_ELSE (result_mode,
17473 gen_rtx_GE (VOIDmode,
17475 true_cond, false_cond)));
17476 true_cond = false_cond;
17479 temp = gen_reg_rtx (compare_mode);
17480 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17485 gcc_unreachable ();
17488 emit_insn (gen_rtx_SET (VOIDmode, dest,
17489 gen_rtx_IF_THEN_ELSE (result_mode,
17490 gen_rtx_GE (VOIDmode,
17492 true_cond, false_cond)));
17496 /* Same as above, but for ints (isel). */
17499 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
17501 rtx condition_rtx, cr;
17502 enum machine_mode mode = GET_MODE (dest);
17503 enum rtx_code cond_code;
17504 rtx (*isel_func) (rtx, rtx, rtx, rtx, rtx);
17507 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
17510 /* We still have to do the compare, because isel doesn't do a
17511 compare, it just looks at the CRx bits set by a previous compare
17513 condition_rtx = rs6000_generate_compare (op, mode);
17514 cond_code = GET_CODE (condition_rtx);
17515 cr = XEXP (condition_rtx, 0);
17516 signedp = GET_MODE (cr) == CCmode;
17518 isel_func = (mode == SImode
17519 ? (signedp ? gen_isel_signed_si : gen_isel_unsigned_si)
17520 : (signedp ? gen_isel_signed_di : gen_isel_unsigned_di));
17524 case LT: case GT: case LTU: case GTU: case EQ:
17525 /* isel handles these directly. */
17529 /* We need to swap the sense of the comparison. */
17532 true_cond = false_cond;
17534 PUT_CODE (condition_rtx, reverse_condition (cond_code));
17539 false_cond = force_reg (mode, false_cond);
17540 if (true_cond != const0_rtx)
17541 true_cond = force_reg (mode, true_cond);
17543 emit_insn (isel_func (dest, condition_rtx, true_cond, false_cond, cr));
17549 output_isel (rtx *operands)
17551 enum rtx_code code;
17553 code = GET_CODE (operands[1]);
17555 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
17557 gcc_assert (GET_CODE (operands[2]) == REG
17558 && GET_CODE (operands[3]) == REG);
17559 PUT_CODE (operands[1], reverse_condition (code));
17560 return "isel %0,%3,%2,%j1";
17563 return "isel %0,%2,%3,%j1";
17567 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
17569 enum machine_mode mode = GET_MODE (op0);
17573 /* VSX/altivec have direct min/max insns. */
17574 if ((code == SMAX || code == SMIN)
17575 && (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
17576 || (mode == SFmode && VECTOR_UNIT_VSX_P (DFmode))))
17578 emit_insn (gen_rtx_SET (VOIDmode,
17580 gen_rtx_fmt_ee (code, mode, op0, op1)));
17584 if (code == SMAX || code == SMIN)
17589 if (code == SMAX || code == UMAX)
17590 target = emit_conditional_move (dest, c, op0, op1, mode,
17591 op0, op1, mode, 0);
17593 target = emit_conditional_move (dest, c, op0, op1, mode,
17594 op1, op0, mode, 0);
17595 gcc_assert (target);
17596 if (target != dest)
17597 emit_move_insn (dest, target);
17600 /* Emit instructions to perform a load-reserved/store-conditional operation.
17601 The operation performed is an atomic
17602 (set M (CODE:MODE M OP))
17603 If not NULL, BEFORE is atomically set to M before the operation, and
17604 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
17605 If SYNC_P then a memory barrier is emitted before the operation.
17606 Either OP or M may be wrapped in a NOT operation. */
17609 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
17610 rtx m, rtx op, rtx before_param, rtx after_param,
17613 enum machine_mode used_mode;
17614 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
17617 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17618 rtx shift = NULL_RTX;
17621 emit_insn (gen_lwsync ());
17625 /* If this is smaller than SImode, we'll have to use SImode with
17627 if (mode == QImode || mode == HImode)
17631 if (MEM_ALIGN (used_m) >= 32)
17634 if (BYTES_BIG_ENDIAN)
17635 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
17637 shift = GEN_INT (ishift);
17638 used_m = change_address (used_m, SImode, 0);
17642 rtx addrSI, aligned_addr;
17643 int shift_mask = mode == QImode ? 0x18 : 0x10;
17645 addrSI = gen_lowpart_common (SImode,
17646 force_reg (Pmode, XEXP (used_m, 0)));
17647 addrSI = force_reg (SImode, addrSI);
17648 shift = gen_reg_rtx (SImode);
17650 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17651 GEN_INT (shift_mask)));
17652 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17654 aligned_addr = expand_binop (Pmode, and_optab,
17656 GEN_INT (-4), NULL_RTX,
17657 1, OPTAB_LIB_WIDEN);
17658 used_m = change_address (used_m, SImode, aligned_addr);
17659 set_mem_align (used_m, 32);
17661 /* It's safe to keep the old alias set of USED_M, because
17662 the operation is atomic and only affects the original
17666 if (GET_CODE (op) == NOT)
17668 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
17669 oldop = gen_rtx_NOT (SImode, oldop);
17672 oldop = lowpart_subreg (SImode, op, mode);
17678 newop = expand_binop (SImode, and_optab,
17679 oldop, GEN_INT (imask), NULL_RTX,
17680 1, OPTAB_LIB_WIDEN);
17681 emit_insn (gen_ashlsi3 (newop, newop, shift));
17684 case NOT: /* NAND */
17685 newop = expand_binop (SImode, ior_optab,
17686 oldop, GEN_INT (~imask), NULL_RTX,
17687 1, OPTAB_LIB_WIDEN);
17688 emit_insn (gen_rotlsi3 (newop, newop, shift));
17692 newop = expand_binop (SImode, ior_optab,
17693 oldop, GEN_INT (~imask), NULL_RTX,
17694 1, OPTAB_LIB_WIDEN);
17695 emit_insn (gen_rotlsi3 (newop, newop, shift));
17703 newop = expand_binop (SImode, and_optab,
17704 oldop, GEN_INT (imask), NULL_RTX,
17705 1, OPTAB_LIB_WIDEN);
17706 emit_insn (gen_ashlsi3 (newop, newop, shift));
17708 mask = gen_reg_rtx (SImode);
17709 emit_move_insn (mask, GEN_INT (imask));
17710 emit_insn (gen_ashlsi3 (mask, mask, shift));
17713 newop = gen_rtx_PLUS (SImode, m, newop);
17715 newop = gen_rtx_MINUS (SImode, m, newop);
17716 newop = gen_rtx_AND (SImode, newop, mask);
17717 newop = gen_rtx_IOR (SImode, newop,
17718 gen_rtx_AND (SImode,
17719 gen_rtx_NOT (SImode, mask),
17725 gcc_unreachable ();
17729 used_mode = SImode;
17730 before = gen_reg_rtx (used_mode);
17731 after = gen_reg_rtx (used_mode);
17736 before = before_param;
17737 after = after_param;
17739 if (before == NULL_RTX)
17740 before = gen_reg_rtx (used_mode);
17741 if (after == NULL_RTX)
17742 after = gen_reg_rtx (used_mode);
17745 if ((code == PLUS || code == MINUS)
17746 && used_mode != mode)
17747 the_op = op; /* Computed above. */
17748 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
17749 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
17750 else if (code == NOT)
17751 the_op = gen_rtx_fmt_ee (IOR, used_mode,
17752 gen_rtx_NOT (used_mode, m),
17753 gen_rtx_NOT (used_mode, op));
17755 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
17757 set_after = gen_rtx_SET (VOIDmode, after, the_op);
17758 set_before = gen_rtx_SET (VOIDmode, before, used_m);
17759 set_atomic = gen_rtx_SET (VOIDmode, used_m,
17760 gen_rtx_UNSPEC (used_mode,
17761 gen_rtvec (1, the_op),
17763 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
17765 if ((code == PLUS || code == MINUS) && used_mode != mode)
17766 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
17767 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
17769 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
17770 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
17772 /* Shift and mask the return values properly. */
17773 if (used_mode != mode && before_param)
17775 emit_insn (gen_lshrsi3 (before, before, shift));
17776 convert_move (before_param, before, 1);
17779 if (used_mode != mode && after_param)
17781 emit_insn (gen_lshrsi3 (after, after, shift));
17782 convert_move (after_param, after, 1);
17785 /* The previous sequence will end with a branch that's dependent on
17786 the conditional store, so placing an isync will ensure that no
17787 other instructions (especially, no load or store instructions)
17788 can start before the atomic operation completes. */
17790 emit_insn (gen_isync ());
17793 /* A subroutine of the atomic operation splitters. Jump to LABEL if
17794 COND is true. Mark the jump as unlikely to be taken. */
17797 emit_unlikely_jump (rtx cond, rtx label)
17799 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
17802 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
17803 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
17804 add_reg_note (x, REG_BR_PROB, very_unlikely);
17807 /* A subroutine of the atomic operation splitters. Emit a load-locked
17808 instruction in MODE. */
17811 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
17813 rtx (*fn) (rtx, rtx) = NULL;
17814 if (mode == SImode)
17815 fn = gen_load_locked_si;
17816 else if (mode == DImode)
17817 fn = gen_load_locked_di;
17818 emit_insn (fn (reg, mem));
17821 /* A subroutine of the atomic operation splitters. Emit a store-conditional
17822 instruction in MODE. */
17825 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
17827 rtx (*fn) (rtx, rtx, rtx) = NULL;
17828 if (mode == SImode)
17829 fn = gen_store_conditional_si;
17830 else if (mode == DImode)
17831 fn = gen_store_conditional_di;
17833 /* Emit sync before stwcx. to address PPC405 Erratum. */
17834 if (PPC405_ERRATUM77)
17835 emit_insn (gen_memory_barrier ());
17837 emit_insn (fn (res, mem, val));
17840 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
17841 to perform. MEM is the memory on which to operate. VAL is the second
17842 operand of the binary operator. BEFORE and AFTER are optional locations to
17843 return the value of MEM either before of after the operation. SCRATCH is
17844 a scratch register. */
17847 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
17848 rtx before, rtx after, rtx scratch)
17850 enum machine_mode mode = GET_MODE (mem);
17851 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17853 emit_insn (gen_lwsync ());
17855 label = gen_label_rtx ();
17856 emit_label (label);
17857 label = gen_rtx_LABEL_REF (VOIDmode, label);
17859 if (before == NULL_RTX)
17861 emit_load_locked (mode, before, mem);
17864 x = gen_rtx_IOR (mode,
17865 gen_rtx_NOT (mode, before),
17866 gen_rtx_NOT (mode, val));
17867 else if (code == AND)
17868 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
17870 x = gen_rtx_fmt_ee (code, mode, before, val);
17872 if (after != NULL_RTX)
17873 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
17874 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
17876 emit_store_conditional (mode, cond, mem, scratch);
17878 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17879 emit_unlikely_jump (x, label);
17881 emit_insn (gen_isync ());
17884 /* Expand an atomic compare and swap operation. MEM is the memory on which
17885 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
17886 value to be stored. SCRATCH is a scratch GPR. */
17889 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
17892 enum machine_mode mode = GET_MODE (mem);
17893 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17895 emit_insn (gen_lwsync ());
17897 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17898 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17899 emit_label (XEXP (label1, 0));
17901 emit_load_locked (mode, retval, mem);
17903 x = gen_rtx_COMPARE (CCmode, retval, oldval);
17904 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
17906 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17907 emit_unlikely_jump (x, label2);
17909 emit_move_insn (scratch, newval);
17910 emit_store_conditional (mode, cond, mem, scratch);
17912 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17913 emit_unlikely_jump (x, label1);
17915 emit_insn (gen_isync ());
17916 emit_label (XEXP (label2, 0));
17919 /* Expand an atomic test and set operation. MEM is the memory on which
17920 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
17923 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
17925 enum machine_mode mode = GET_MODE (mem);
17926 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17928 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17929 emit_label (XEXP (label, 0));
17931 emit_load_locked (mode, retval, mem);
17932 emit_move_insn (scratch, val);
17933 emit_store_conditional (mode, cond, mem, scratch);
17935 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17936 emit_unlikely_jump (x, label);
17938 emit_insn (gen_isync ());
17942 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
17944 enum machine_mode mode = GET_MODE (mem);
17945 rtx addrSI, align, wdst, shift, mask;
17946 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
17947 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17949 /* Shift amount for subword relative to aligned word. */
17950 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
17951 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
17952 shift = gen_reg_rtx (SImode);
17953 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17954 GEN_INT (shift_mask)));
17955 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17957 /* Shift and mask old value into position within word. */
17958 oldval = convert_modes (SImode, mode, oldval, 1);
17959 oldval = expand_binop (SImode, and_optab,
17960 oldval, GEN_INT (imask), NULL_RTX,
17961 1, OPTAB_LIB_WIDEN);
17962 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
17964 /* Shift and mask new value into position within word. */
17965 newval = convert_modes (SImode, mode, newval, 1);
17966 newval = expand_binop (SImode, and_optab,
17967 newval, GEN_INT (imask), NULL_RTX,
17968 1, OPTAB_LIB_WIDEN);
17969 emit_insn (gen_ashlsi3 (newval, newval, shift));
17971 /* Mask for insertion. */
17972 mask = gen_reg_rtx (SImode);
17973 emit_move_insn (mask, GEN_INT (imask));
17974 emit_insn (gen_ashlsi3 (mask, mask, shift));
17976 /* Address of aligned word containing subword. */
17977 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
17978 NULL_RTX, 1, OPTAB_LIB_WIDEN);
17979 mem = change_address (mem, SImode, align);
17980 set_mem_align (mem, 32);
17981 MEM_VOLATILE_P (mem) = 1;
17983 wdst = gen_reg_rtx (SImode);
17984 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
17985 oldval, newval, mem));
17987 /* Shift the result back. */
17988 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
17990 emit_move_insn (dst, gen_lowpart (mode, wdst));
17994 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
17995 rtx oldval, rtx newval, rtx mem,
17998 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
18000 emit_insn (gen_lwsync ());
18001 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
18002 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
18003 emit_label (XEXP (label1, 0));
18005 emit_load_locked (SImode, scratch, mem);
18007 /* Mask subword within loaded value for comparison with oldval.
18008 Use UNSPEC_AND to avoid clobber.*/
18009 emit_insn (gen_rtx_SET (SImode, dest,
18010 gen_rtx_UNSPEC (SImode,
18011 gen_rtvec (2, scratch, mask),
18014 x = gen_rtx_COMPARE (CCmode, dest, oldval);
18015 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
18017 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18018 emit_unlikely_jump (x, label2);
18020 /* Clear subword within loaded value for insertion of new value. */
18021 emit_insn (gen_rtx_SET (SImode, scratch,
18022 gen_rtx_AND (SImode,
18023 gen_rtx_NOT (SImode, mask), scratch)));
18024 emit_insn (gen_iorsi3 (scratch, scratch, newval));
18025 emit_store_conditional (SImode, cond, mem, scratch);
18027 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18028 emit_unlikely_jump (x, label1);
18030 emit_insn (gen_isync ());
18031 emit_label (XEXP (label2, 0));
18035 /* Emit instructions to move SRC to DST. Called by splitters for
18036 multi-register moves. It will emit at most one instruction for
18037 each register that is accessed; that is, it won't emit li/lis pairs
18038 (or equivalent for 64-bit code). One of SRC or DST must be a hard
18042 rs6000_split_multireg_move (rtx dst, rtx src)
18044 /* The register number of the first register being moved. */
18046 /* The mode that is to be moved. */
18047 enum machine_mode mode;
18048 /* The mode that the move is being done in, and its size. */
18049 enum machine_mode reg_mode;
18051 /* The number of registers that will be moved. */
18054 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
18055 mode = GET_MODE (dst);
18056 nregs = hard_regno_nregs[reg][mode];
18057 if (FP_REGNO_P (reg))
18058 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
18059 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
18060 else if (ALTIVEC_REGNO_P (reg))
18061 reg_mode = V16QImode;
18062 else if (TARGET_E500_DOUBLE && mode == TFmode)
18065 reg_mode = word_mode;
18066 reg_mode_size = GET_MODE_SIZE (reg_mode);
18068 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
18070 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
18072 /* Move register range backwards, if we might have destructive
18075 for (i = nregs - 1; i >= 0; i--)
18076 emit_insn (gen_rtx_SET (VOIDmode,
18077 simplify_gen_subreg (reg_mode, dst, mode,
18078 i * reg_mode_size),
18079 simplify_gen_subreg (reg_mode, src, mode,
18080 i * reg_mode_size)));
18086 bool used_update = false;
18087 rtx restore_basereg = NULL_RTX;
18089 if (MEM_P (src) && INT_REGNO_P (reg))
18093 if (GET_CODE (XEXP (src, 0)) == PRE_INC
18094 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
18097 breg = XEXP (XEXP (src, 0), 0);
18098 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
18099 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
18100 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
18101 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
18102 src = replace_equiv_address (src, breg);
18104 else if (! rs6000_offsettable_memref_p (src))
18106 if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)
18108 rtx basereg = XEXP (XEXP (src, 0), 0);
18111 rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0);
18112 emit_insn (gen_rtx_SET (VOIDmode, ndst,
18113 gen_rtx_MEM (reg_mode, XEXP (src, 0))));
18114 used_update = true;
18117 emit_insn (gen_rtx_SET (VOIDmode, basereg,
18118 XEXP (XEXP (src, 0), 1)));
18119 src = replace_equiv_address (src, basereg);
18123 rtx basereg = gen_rtx_REG (Pmode, reg);
18124 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
18125 src = replace_equiv_address (src, basereg);
18129 breg = XEXP (src, 0);
18130 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
18131 breg = XEXP (breg, 0);
18133 /* If the base register we are using to address memory is
18134 also a destination reg, then change that register last. */
18136 && REGNO (breg) >= REGNO (dst)
18137 && REGNO (breg) < REGNO (dst) + nregs)
18138 j = REGNO (breg) - REGNO (dst);
18140 else if (MEM_P (dst) && INT_REGNO_P (reg))
18144 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
18145 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
18148 breg = XEXP (XEXP (dst, 0), 0);
18149 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
18150 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
18151 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
18153 /* We have to update the breg before doing the store.
18154 Use store with update, if available. */
18158 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
18159 emit_insn (TARGET_32BIT
18160 ? (TARGET_POWERPC64
18161 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
18162 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
18163 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
18164 used_update = true;
18167 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
18168 dst = replace_equiv_address (dst, breg);
18170 else if (!rs6000_offsettable_memref_p (dst)
18171 && GET_CODE (XEXP (dst, 0)) != LO_SUM)
18173 if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY)
18175 rtx basereg = XEXP (XEXP (dst, 0), 0);
18178 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
18179 emit_insn (gen_rtx_SET (VOIDmode,
18180 gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc));
18181 used_update = true;
18184 emit_insn (gen_rtx_SET (VOIDmode, basereg,
18185 XEXP (XEXP (dst, 0), 1)));
18186 dst = replace_equiv_address (dst, basereg);
18190 rtx basereg = XEXP (XEXP (dst, 0), 0);
18191 rtx offsetreg = XEXP (XEXP (dst, 0), 1);
18192 gcc_assert (GET_CODE (XEXP (dst, 0)) == PLUS
18194 && REG_P (offsetreg)
18195 && REGNO (basereg) != REGNO (offsetreg));
18196 if (REGNO (basereg) == 0)
18198 rtx tmp = offsetreg;
18199 offsetreg = basereg;
18202 emit_insn (gen_add3_insn (basereg, basereg, offsetreg));
18203 restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg);
18204 dst = replace_equiv_address (dst, basereg);
18207 else if (GET_CODE (XEXP (dst, 0)) != LO_SUM)
18208 gcc_assert (rs6000_offsettable_memref_p (dst));
18211 for (i = 0; i < nregs; i++)
18213 /* Calculate index to next subword. */
18218 /* If compiler already emitted move of first word by
18219 store with update, no need to do anything. */
18220 if (j == 0 && used_update)
18223 emit_insn (gen_rtx_SET (VOIDmode,
18224 simplify_gen_subreg (reg_mode, dst, mode,
18225 j * reg_mode_size),
18226 simplify_gen_subreg (reg_mode, src, mode,
18227 j * reg_mode_size)));
18229 if (restore_basereg != NULL_RTX)
18230 emit_insn (restore_basereg);
18235 /* This page contains routines that are used to determine what the
18236 function prologue and epilogue code will do and write them out. */
18238 /* Return the first fixed-point register that is required to be
18239 saved. 32 if none. */
18242 first_reg_to_save (void)
18246 /* Find lowest numbered live register. */
18247 for (first_reg = 13; first_reg <= 31; first_reg++)
18248 if (df_regs_ever_live_p (first_reg)
18249 && (! call_used_regs[first_reg]
18250 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18251 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
18252 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
18253 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
18258 && crtl->uses_pic_offset_table
18259 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
18260 return RS6000_PIC_OFFSET_TABLE_REGNUM;
18266 /* Similar, for FP regs. */
18269 first_fp_reg_to_save (void)
18273 /* Find lowest numbered live register. */
18274 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
18275 if (df_regs_ever_live_p (first_reg))
18281 /* Similar, for AltiVec regs. */
18284 first_altivec_reg_to_save (void)
18288 /* Stack frame remains as is unless we are in AltiVec ABI. */
18289 if (! TARGET_ALTIVEC_ABI)
18290 return LAST_ALTIVEC_REGNO + 1;
18292 /* On Darwin, the unwind routines are compiled without
18293 TARGET_ALTIVEC, and use save_world to save/restore the
18294 altivec registers when necessary. */
18295 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
18296 && ! TARGET_ALTIVEC)
18297 return FIRST_ALTIVEC_REGNO + 20;
18299 /* Find lowest numbered live register. */
18300 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
18301 if (df_regs_ever_live_p (i))
18307 /* Return a 32-bit mask of the AltiVec registers we need to set in
18308 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
18309 the 32-bit word is 0. */
18311 static unsigned int
18312 compute_vrsave_mask (void)
18314 unsigned int i, mask = 0;
18316 /* On Darwin, the unwind routines are compiled without
18317 TARGET_ALTIVEC, and use save_world to save/restore the
18318 call-saved altivec registers when necessary. */
18319 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
18320 && ! TARGET_ALTIVEC)
18323 /* First, find out if we use _any_ altivec registers. */
18324 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
18325 if (df_regs_ever_live_p (i))
18326 mask |= ALTIVEC_REG_BIT (i);
18331 /* Next, remove the argument registers from the set. These must
18332 be in the VRSAVE mask set by the caller, so we don't need to add
18333 them in again. More importantly, the mask we compute here is
18334 used to generate CLOBBERs in the set_vrsave insn, and we do not
18335 wish the argument registers to die. */
18336 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
18337 mask &= ~ALTIVEC_REG_BIT (i);
18339 /* Similarly, remove the return value from the set. */
18342 diddle_return_value (is_altivec_return_reg, &yes);
18344 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
18350 /* For a very restricted set of circumstances, we can cut down the
18351 size of prologues/epilogues by calling our own save/restore-the-world
18355 compute_save_world_info (rs6000_stack_t *info_ptr)
18357 info_ptr->world_save_p = 1;
18358 info_ptr->world_save_p
18359 = (WORLD_SAVE_P (info_ptr)
18360 && DEFAULT_ABI == ABI_DARWIN
18361 && ! (cfun->calls_setjmp && flag_exceptions)
18362 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
18363 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
18364 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
18365 && info_ptr->cr_save_p);
18367 /* This will not work in conjunction with sibcalls. Make sure there
18368 are none. (This check is expensive, but seldom executed.) */
18369 if (WORLD_SAVE_P (info_ptr))
18372 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
18373 if ( GET_CODE (insn) == CALL_INSN
18374 && SIBLING_CALL_P (insn))
18376 info_ptr->world_save_p = 0;
18381 if (WORLD_SAVE_P (info_ptr))
18383 /* Even if we're not touching VRsave, make sure there's room on the
18384 stack for it, if it looks like we're calling SAVE_WORLD, which
18385 will attempt to save it. */
18386 info_ptr->vrsave_size = 4;
18388 /* If we are going to save the world, we need to save the link register too. */
18389 info_ptr->lr_save_p = 1;
18391 /* "Save" the VRsave register too if we're saving the world. */
18392 if (info_ptr->vrsave_mask == 0)
18393 info_ptr->vrsave_mask = compute_vrsave_mask ();
18395 /* Because the Darwin register save/restore routines only handle
18396 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
18398 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
18399 && (info_ptr->first_altivec_reg_save
18400 >= FIRST_SAVED_ALTIVEC_REGNO));
18407 is_altivec_return_reg (rtx reg, void *xyes)
18409 bool *yes = (bool *) xyes;
18410 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
18415 /* Determine the strategy for savings/restoring registers. */
18418 SAVRES_MULTIPLE = 0x1,
18419 SAVE_INLINE_FPRS = 0x2,
18420 SAVE_INLINE_GPRS = 0x4,
18421 REST_INLINE_FPRS = 0x8,
18422 REST_INLINE_GPRS = 0x10,
18423 SAVE_NOINLINE_GPRS_SAVES_LR = 0x20,
18424 SAVE_NOINLINE_FPRS_SAVES_LR = 0x40,
18425 REST_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x80
18429 rs6000_savres_strategy (rs6000_stack_t *info,
18430 bool using_static_chain_p)
18434 if (TARGET_MULTIPLE
18435 && !TARGET_POWERPC64
18436 && !(TARGET_SPE_ABI && info->spe_64bit_regs_used)
18437 && info->first_gp_reg_save < 31
18438 && no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true))
18439 strategy |= SAVRES_MULTIPLE;
18441 if (crtl->calls_eh_return
18442 || cfun->machine->ra_need_lr
18443 || info->total_size > 32767)
18444 strategy |= (SAVE_INLINE_FPRS | REST_INLINE_FPRS
18445 | SAVE_INLINE_GPRS | REST_INLINE_GPRS);
18447 if (info->first_fp_reg_save == 64
18448 || FP_SAVE_INLINE (info->first_fp_reg_save)
18449 /* The out-of-line FP routines use double-precision stores;
18450 we can't use those routines if we don't have such stores. */
18451 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
18452 || !no_global_regs_above (info->first_fp_reg_save, /*gpr=*/false))
18453 strategy |= SAVE_INLINE_FPRS | REST_INLINE_FPRS;
18455 if (info->first_gp_reg_save == 32
18456 || GP_SAVE_INLINE (info->first_gp_reg_save)
18457 || !((strategy & SAVRES_MULTIPLE)
18458 || no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true)))
18459 strategy |= SAVE_INLINE_GPRS | REST_INLINE_GPRS;
18461 /* Don't bother to try to save things out-of-line if r11 is occupied
18462 by the static chain. It would require too much fiddling and the
18463 static chain is rarely used anyway. */
18464 if (using_static_chain_p)
18465 strategy |= SAVE_INLINE_FPRS | SAVE_INLINE_GPRS;
18467 /* If we are going to use store multiple, then don't even bother
18468 with the out-of-line routines, since the store-multiple
18469 instruction will always be smaller. */
18470 if ((strategy & SAVRES_MULTIPLE))
18471 strategy |= SAVE_INLINE_GPRS;
18473 /* The situation is more complicated with load multiple. We'd
18474 prefer to use the out-of-line routines for restores, since the
18475 "exit" out-of-line routines can handle the restore of LR and the
18476 frame teardown. However if doesn't make sense to use the
18477 out-of-line routine if that is the only reason we'd need to save
18478 LR, and we can't use the "exit" out-of-line gpr restore if we
18479 have saved some fprs; In those cases it is advantageous to use
18480 load multiple when available. */
18481 if ((strategy & SAVRES_MULTIPLE)
18482 && (!info->lr_save_p
18483 || info->first_fp_reg_save != 64))
18484 strategy |= REST_INLINE_GPRS;
18486 /* We can only use load multiple or the out-of-line routines to
18487 restore if we've used store multiple or out-of-line routines
18488 in the prologue, i.e. if we've saved all the registers from
18489 first_gp_reg_save. Otherwise, we risk loading garbage. */
18490 if ((strategy & (SAVE_INLINE_GPRS | SAVRES_MULTIPLE)) == SAVE_INLINE_GPRS)
18491 strategy |= REST_INLINE_GPRS;
18493 /* Saving CR interferes with the exit routines used on the SPE, so
18496 && info->spe_64bit_regs_used
18497 && info->cr_save_p)
18498 strategy |= REST_INLINE_GPRS;
18500 #ifdef POWERPC_LINUX
18503 if (!(strategy & SAVE_INLINE_FPRS))
18504 strategy |= SAVE_NOINLINE_FPRS_SAVES_LR;
18505 else if (!(strategy & SAVE_INLINE_GPRS)
18506 && info->first_fp_reg_save == 64)
18507 strategy |= SAVE_NOINLINE_GPRS_SAVES_LR;
18510 if (TARGET_AIX && !(strategy & REST_INLINE_FPRS))
18511 strategy |= REST_NOINLINE_FPRS_DOESNT_RESTORE_LR;
18516 /* Calculate the stack information for the current function. This is
18517 complicated by having two separate calling sequences, the AIX calling
18518 sequence and the V.4 calling sequence.
18520 AIX (and Darwin/Mac OS X) stack frames look like:
18522 SP----> +---------------------------------------+
18523 | back chain to caller | 0 0
18524 +---------------------------------------+
18525 | saved CR | 4 8 (8-11)
18526 +---------------------------------------+
18528 +---------------------------------------+
18529 | reserved for compilers | 12 24
18530 +---------------------------------------+
18531 | reserved for binders | 16 32
18532 +---------------------------------------+
18533 | saved TOC pointer | 20 40
18534 +---------------------------------------+
18535 | Parameter save area (P) | 24 48
18536 +---------------------------------------+
18537 | Alloca space (A) | 24+P etc.
18538 +---------------------------------------+
18539 | Local variable space (L) | 24+P+A
18540 +---------------------------------------+
18541 | Float/int conversion temporary (X) | 24+P+A+L
18542 +---------------------------------------+
18543 | Save area for AltiVec registers (W) | 24+P+A+L+X
18544 +---------------------------------------+
18545 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
18546 +---------------------------------------+
18547 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
18548 +---------------------------------------+
18549 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
18550 +---------------------------------------+
18551 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
18552 +---------------------------------------+
18553 old SP->| back chain to caller's caller |
18554 +---------------------------------------+
18556 The required alignment for AIX configurations is two words (i.e., 8
18560 V.4 stack frames look like:
18562 SP----> +---------------------------------------+
18563 | back chain to caller | 0
18564 +---------------------------------------+
18565 | caller's saved LR | 4
18566 +---------------------------------------+
18567 | Parameter save area (P) | 8
18568 +---------------------------------------+
18569 | Alloca space (A) | 8+P
18570 +---------------------------------------+
18571 | Varargs save area (V) | 8+P+A
18572 +---------------------------------------+
18573 | Local variable space (L) | 8+P+A+V
18574 +---------------------------------------+
18575 | Float/int conversion temporary (X) | 8+P+A+V+L
18576 +---------------------------------------+
18577 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
18578 +---------------------------------------+
18579 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
18580 +---------------------------------------+
18581 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
18582 +---------------------------------------+
18583 | SPE: area for 64-bit GP registers |
18584 +---------------------------------------+
18585 | SPE alignment padding |
18586 +---------------------------------------+
18587 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
18588 +---------------------------------------+
18589 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
18590 +---------------------------------------+
18591 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
18592 +---------------------------------------+
18593 old SP->| back chain to caller's caller |
18594 +---------------------------------------+
18596 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
18597 given. (But note below and in sysv4.h that we require only 8 and
18598 may round up the size of our stack frame anyways. The historical
18599 reason is early versions of powerpc-linux which didn't properly
18600 align the stack at program startup. A happy side-effect is that
18601 -mno-eabi libraries can be used with -meabi programs.)
18603 The EABI configuration defaults to the V.4 layout. However,
18604 the stack alignment requirements may differ. If -mno-eabi is not
18605 given, the required stack alignment is 8 bytes; if -mno-eabi is
18606 given, the required alignment is 16 bytes. (But see V.4 comment
18609 #ifndef ABI_STACK_BOUNDARY
18610 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
18613 static rs6000_stack_t *
18614 rs6000_stack_info (void)
18616 #ifdef ENABLE_CHECKING
18617 static rs6000_stack_t info_save;
18619 rs6000_stack_t *info_ptr = &stack_info;
18620 int reg_size = TARGET_32BIT ? 4 : 8;
18624 HOST_WIDE_INT non_fixed_size;
18625 bool using_static_chain_p;
18627 #ifdef ENABLE_CHECKING
18628 memcpy (&info_save, &stack_info, sizeof stack_info);
18630 if (reload_completed && info_ptr->reload_completed)
18634 memset (&stack_info, 0, sizeof (stack_info));
18635 info_ptr->reload_completed = reload_completed;
18639 /* Cache value so we don't rescan instruction chain over and over. */
18640 if (cfun->machine->insn_chain_scanned_p == 0)
18641 cfun->machine->insn_chain_scanned_p
18642 = spe_func_has_64bit_regs_p () + 1;
18643 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
18646 /* Select which calling sequence. */
18647 info_ptr->abi = DEFAULT_ABI;
18649 /* Calculate which registers need to be saved & save area size. */
18650 info_ptr->first_gp_reg_save = first_reg_to_save ();
18651 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
18652 even if it currently looks like we won't. Reload may need it to
18653 get at a constant; if so, it will have already created a constant
18654 pool entry for it. */
18655 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
18656 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
18657 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
18658 && crtl->uses_const_pool
18659 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
18660 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
18662 first_gp = info_ptr->first_gp_reg_save;
18664 info_ptr->gp_size = reg_size * (32 - first_gp);
18666 /* For the SPE, we have an additional upper 32-bits on each GPR.
18667 Ideally we should save the entire 64-bits only when the upper
18668 half is used in SIMD instructions. Since we only record
18669 registers live (not the size they are used in), this proves
18670 difficult because we'd have to traverse the instruction chain at
18671 the right time, taking reload into account. This is a real pain,
18672 so we opt to save the GPRs in 64-bits always if but one register
18673 gets used in 64-bits. Otherwise, all the registers in the frame
18674 get saved in 32-bits.
18676 So... since when we save all GPRs (except the SP) in 64-bits, the
18677 traditional GP save area will be empty. */
18678 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18679 info_ptr->gp_size = 0;
18681 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
18682 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
18684 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
18685 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
18686 - info_ptr->first_altivec_reg_save);
18688 /* Does this function call anything? */
18689 info_ptr->calls_p = (! current_function_is_leaf
18690 || cfun->machine->ra_needs_full_frame);
18692 /* Determine if we need to save the condition code registers. */
18693 if (df_regs_ever_live_p (CR2_REGNO)
18694 || df_regs_ever_live_p (CR3_REGNO)
18695 || df_regs_ever_live_p (CR4_REGNO))
18697 info_ptr->cr_save_p = 1;
18698 if (DEFAULT_ABI == ABI_V4)
18699 info_ptr->cr_size = reg_size;
18702 /* If the current function calls __builtin_eh_return, then we need
18703 to allocate stack space for registers that will hold data for
18704 the exception handler. */
18705 if (crtl->calls_eh_return)
18708 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
18711 /* SPE saves EH registers in 64-bits. */
18712 ehrd_size = i * (TARGET_SPE_ABI
18713 && info_ptr->spe_64bit_regs_used != 0
18714 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
18719 /* Determine various sizes. */
18720 info_ptr->reg_size = reg_size;
18721 info_ptr->fixed_size = RS6000_SAVE_AREA;
18722 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
18723 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
18724 TARGET_ALTIVEC ? 16 : 8);
18725 if (FRAME_GROWS_DOWNWARD)
18726 info_ptr->vars_size
18727 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
18728 + info_ptr->parm_size,
18729 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
18730 - (info_ptr->fixed_size + info_ptr->vars_size
18731 + info_ptr->parm_size);
18733 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18734 info_ptr->spe_gp_size = 8 * (32 - first_gp);
18736 info_ptr->spe_gp_size = 0;
18738 if (TARGET_ALTIVEC_ABI)
18739 info_ptr->vrsave_mask = compute_vrsave_mask ();
18741 info_ptr->vrsave_mask = 0;
18743 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
18744 info_ptr->vrsave_size = 4;
18746 info_ptr->vrsave_size = 0;
18748 compute_save_world_info (info_ptr);
18750 /* Calculate the offsets. */
18751 switch (DEFAULT_ABI)
18755 gcc_unreachable ();
18759 info_ptr->fp_save_offset = - info_ptr->fp_size;
18760 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18762 if (TARGET_ALTIVEC_ABI)
18764 info_ptr->vrsave_save_offset
18765 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
18767 /* Align stack so vector save area is on a quadword boundary.
18768 The padding goes above the vectors. */
18769 if (info_ptr->altivec_size != 0)
18770 info_ptr->altivec_padding_size
18771 = info_ptr->vrsave_save_offset & 0xF;
18773 info_ptr->altivec_padding_size = 0;
18775 info_ptr->altivec_save_offset
18776 = info_ptr->vrsave_save_offset
18777 - info_ptr->altivec_padding_size
18778 - info_ptr->altivec_size;
18779 gcc_assert (info_ptr->altivec_size == 0
18780 || info_ptr->altivec_save_offset % 16 == 0);
18782 /* Adjust for AltiVec case. */
18783 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
18786 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
18787 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
18788 info_ptr->lr_save_offset = 2*reg_size;
18792 info_ptr->fp_save_offset = - info_ptr->fp_size;
18793 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18794 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
18796 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18798 /* Align stack so SPE GPR save area is aligned on a
18799 double-word boundary. */
18800 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
18801 info_ptr->spe_padding_size
18802 = 8 - (-info_ptr->cr_save_offset % 8);
18804 info_ptr->spe_padding_size = 0;
18806 info_ptr->spe_gp_save_offset
18807 = info_ptr->cr_save_offset
18808 - info_ptr->spe_padding_size
18809 - info_ptr->spe_gp_size;
18811 /* Adjust for SPE case. */
18812 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
18814 else if (TARGET_ALTIVEC_ABI)
18816 info_ptr->vrsave_save_offset
18817 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
18819 /* Align stack so vector save area is on a quadword boundary. */
18820 if (info_ptr->altivec_size != 0)
18821 info_ptr->altivec_padding_size
18822 = 16 - (-info_ptr->vrsave_save_offset % 16);
18824 info_ptr->altivec_padding_size = 0;
18826 info_ptr->altivec_save_offset
18827 = info_ptr->vrsave_save_offset
18828 - info_ptr->altivec_padding_size
18829 - info_ptr->altivec_size;
18831 /* Adjust for AltiVec case. */
18832 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
18835 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
18836 info_ptr->ehrd_offset -= ehrd_size;
18837 info_ptr->lr_save_offset = reg_size;
18841 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
18842 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
18843 + info_ptr->gp_size
18844 + info_ptr->altivec_size
18845 + info_ptr->altivec_padding_size
18846 + info_ptr->spe_gp_size
18847 + info_ptr->spe_padding_size
18849 + info_ptr->cr_size
18850 + info_ptr->vrsave_size,
18853 non_fixed_size = (info_ptr->vars_size
18854 + info_ptr->parm_size
18855 + info_ptr->save_size);
18857 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
18858 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
18860 /* Determine if we need to save the link register. */
18861 if (info_ptr->calls_p
18862 || (DEFAULT_ABI == ABI_AIX
18864 && !TARGET_PROFILE_KERNEL)
18865 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
18866 #ifdef TARGET_RELOCATABLE
18867 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
18869 || rs6000_ra_ever_killed ())
18870 info_ptr->lr_save_p = 1;
18872 using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
18873 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
18874 && call_used_regs[STATIC_CHAIN_REGNUM]);
18875 info_ptr->savres_strategy = rs6000_savres_strategy (info_ptr,
18876 using_static_chain_p);
18878 if (!(info_ptr->savres_strategy & SAVE_INLINE_GPRS)
18879 || !(info_ptr->savres_strategy & SAVE_INLINE_FPRS)
18880 || !(info_ptr->savres_strategy & REST_INLINE_GPRS)
18881 || !(info_ptr->savres_strategy & REST_INLINE_FPRS))
18882 info_ptr->lr_save_p = 1;
18884 if (info_ptr->lr_save_p)
18885 df_set_regs_ever_live (LR_REGNO, true);
18887 /* Determine if we need to allocate any stack frame:
18889 For AIX we need to push the stack if a frame pointer is needed
18890 (because the stack might be dynamically adjusted), if we are
18891 debugging, if we make calls, or if the sum of fp_save, gp_save,
18892 and local variables are more than the space needed to save all
18893 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
18894 + 18*8 = 288 (GPR13 reserved).
18896 For V.4 we don't have the stack cushion that AIX uses, but assume
18897 that the debugger can handle stackless frames. */
18899 if (info_ptr->calls_p)
18900 info_ptr->push_p = 1;
18902 else if (DEFAULT_ABI == ABI_V4)
18903 info_ptr->push_p = non_fixed_size != 0;
18905 else if (frame_pointer_needed)
18906 info_ptr->push_p = 1;
18908 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
18909 info_ptr->push_p = 1;
18912 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
18914 /* Zero offsets if we're not saving those registers. */
18915 if (info_ptr->fp_size == 0)
18916 info_ptr->fp_save_offset = 0;
18918 if (info_ptr->gp_size == 0)
18919 info_ptr->gp_save_offset = 0;
18921 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
18922 info_ptr->altivec_save_offset = 0;
18924 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
18925 info_ptr->vrsave_save_offset = 0;
18927 if (! TARGET_SPE_ABI
18928 || info_ptr->spe_64bit_regs_used == 0
18929 || info_ptr->spe_gp_size == 0)
18930 info_ptr->spe_gp_save_offset = 0;
18932 if (! info_ptr->lr_save_p)
18933 info_ptr->lr_save_offset = 0;
18935 if (! info_ptr->cr_save_p)
18936 info_ptr->cr_save_offset = 0;
18938 #ifdef ENABLE_CHECKING
18939 gcc_assert (!(reload_completed && info_save.reload_completed)
18940 || memcmp (&info_save, &stack_info, sizeof stack_info) == 0);
18945 /* Return true if the current function uses any GPRs in 64-bit SIMD
18949 spe_func_has_64bit_regs_p (void)
18953 /* Functions that save and restore all the call-saved registers will
18954 need to save/restore the registers in 64-bits. */
18955 if (crtl->calls_eh_return
18956 || cfun->calls_setjmp
18957 || crtl->has_nonlocal_goto)
18960 insns = get_insns ();
18962 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
18968 /* FIXME: This should be implemented with attributes...
18970 (set_attr "spe64" "true")....then,
18971 if (get_spe64(insn)) return true;
18973 It's the only reliable way to do the stuff below. */
18975 i = PATTERN (insn);
18976 if (GET_CODE (i) == SET)
18978 enum machine_mode mode = GET_MODE (SET_SRC (i));
18980 if (SPE_VECTOR_MODE (mode))
18982 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
18992 debug_stack_info (rs6000_stack_t *info)
18994 const char *abi_string;
18997 info = rs6000_stack_info ();
18999 fprintf (stderr, "\nStack information for function %s:\n",
19000 ((current_function_decl && DECL_NAME (current_function_decl))
19001 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
19006 default: abi_string = "Unknown"; break;
19007 case ABI_NONE: abi_string = "NONE"; break;
19008 case ABI_AIX: abi_string = "AIX"; break;
19009 case ABI_DARWIN: abi_string = "Darwin"; break;
19010 case ABI_V4: abi_string = "V.4"; break;
19013 fprintf (stderr, "\tABI = %5s\n", abi_string);
19015 if (TARGET_ALTIVEC_ABI)
19016 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
19018 if (TARGET_SPE_ABI)
19019 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
19021 if (info->first_gp_reg_save != 32)
19022 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
19024 if (info->first_fp_reg_save != 64)
19025 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
19027 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
19028 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
19029 info->first_altivec_reg_save);
19031 if (info->lr_save_p)
19032 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
19034 if (info->cr_save_p)
19035 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
19037 if (info->vrsave_mask)
19038 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
19041 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
19044 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
19046 if (info->gp_save_offset)
19047 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
19049 if (info->fp_save_offset)
19050 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
19052 if (info->altivec_save_offset)
19053 fprintf (stderr, "\taltivec_save_offset = %5d\n",
19054 info->altivec_save_offset);
19056 if (info->spe_gp_save_offset)
19057 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
19058 info->spe_gp_save_offset);
19060 if (info->vrsave_save_offset)
19061 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
19062 info->vrsave_save_offset);
19064 if (info->lr_save_offset)
19065 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
19067 if (info->cr_save_offset)
19068 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
19070 if (info->varargs_save_offset)
19071 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
19073 if (info->total_size)
19074 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
19077 if (info->vars_size)
19078 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
19081 if (info->parm_size)
19082 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
19084 if (info->fixed_size)
19085 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
19088 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
19090 if (info->spe_gp_size)
19091 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
19094 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
19096 if (info->altivec_size)
19097 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
19099 if (info->vrsave_size)
19100 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
19102 if (info->altivec_padding_size)
19103 fprintf (stderr, "\taltivec_padding_size= %5d\n",
19104 info->altivec_padding_size);
19106 if (info->spe_padding_size)
19107 fprintf (stderr, "\tspe_padding_size = %5d\n",
19108 info->spe_padding_size);
19111 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
19113 if (info->save_size)
19114 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
19116 if (info->reg_size != 4)
19117 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
19119 fprintf (stderr, "\n");
19123 rs6000_return_addr (int count, rtx frame)
19125 /* Currently we don't optimize very well between prolog and body
19126 code and for PIC code the code can be actually quite bad, so
19127 don't try to be too clever here. */
19128 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
19130 cfun->machine->ra_needs_full_frame = 1;
19137 plus_constant (copy_to_reg
19138 (gen_rtx_MEM (Pmode,
19139 memory_address (Pmode, frame))),
19140 RETURN_ADDRESS_OFFSET)));
19143 cfun->machine->ra_need_lr = 1;
19144 return get_hard_reg_initial_val (Pmode, LR_REGNO);
19147 /* Say whether a function is a candidate for sibcall handling or not.
19148 We do not allow indirect calls to be optimized into sibling calls.
19149 Also, we can't do it if there are any vector parameters; there's
19150 nowhere to put the VRsave code so it works; note that functions with
19151 vector parameters are required to have a prototype, so the argument
19152 type info must be available here. (The tail recursion case can work
19153 with vector parameters, but there's no way to distinguish here.) */
19155 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
19160 if (TARGET_ALTIVEC_VRSAVE)
19162 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
19163 type; type = TREE_CHAIN (type))
19165 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
19169 if (DEFAULT_ABI == ABI_DARWIN
19170 || ((*targetm.binds_local_p) (decl)
19171 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
19173 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
19175 if (!lookup_attribute ("longcall", attr_list)
19176 || lookup_attribute ("shortcall", attr_list))
19183 /* NULL if INSN insn is valid within a low-overhead loop.
19184 Otherwise return why doloop cannot be applied.
19185 PowerPC uses the COUNT register for branch on table instructions. */
19187 static const char *
19188 rs6000_invalid_within_doloop (const_rtx insn)
19191 return "Function call in the loop.";
19194 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
19195 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
19196 return "Computed branch in the loop.";
19202 rs6000_ra_ever_killed (void)
19208 if (cfun->is_thunk)
19211 if (cfun->machine->lr_save_state)
19212 return cfun->machine->lr_save_state - 1;
19214 /* regs_ever_live has LR marked as used if any sibcalls are present,
19215 but this should not force saving and restoring in the
19216 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
19217 clobbers LR, so that is inappropriate. */
19219 /* Also, the prologue can generate a store into LR that
19220 doesn't really count, like this:
19223 bcl to set PIC register
19227 When we're called from the epilogue, we need to avoid counting
19228 this as a store. */
19230 push_topmost_sequence ();
19231 top = get_insns ();
19232 pop_topmost_sequence ();
19233 reg = gen_rtx_REG (Pmode, LR_REGNO);
19235 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
19241 if (!SIBLING_CALL_P (insn))
19244 else if (find_regno_note (insn, REG_INC, LR_REGNO))
19246 else if (set_of (reg, insn) != NULL_RTX
19247 && !prologue_epilogue_contains (insn))
19254 /* Emit instructions needed to load the TOC register.
19255 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
19256 a constant pool; or for SVR4 -fpic. */
19259 rs6000_emit_load_toc_table (int fromprolog)
19262 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
19264 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
19267 rtx lab, tmp1, tmp2, got;
19269 lab = gen_label_rtx ();
19270 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (lab));
19271 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19273 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
19275 got = rs6000_got_sym ();
19276 tmp1 = tmp2 = dest;
19279 tmp1 = gen_reg_rtx (Pmode);
19280 tmp2 = gen_reg_rtx (Pmode);
19282 emit_insn (gen_load_toc_v4_PIC_1 (lab));
19283 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
19284 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
19285 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
19287 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
19289 emit_insn (gen_load_toc_v4_pic_si ());
19290 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
19292 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
19295 rtx temp0 = (fromprolog
19296 ? gen_rtx_REG (Pmode, 0)
19297 : gen_reg_rtx (Pmode));
19303 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
19304 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19306 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
19307 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19309 emit_insn (gen_load_toc_v4_PIC_1 (symF));
19310 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
19311 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
19317 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
19318 lab = gen_label_rtx ();
19319 emit_insn (gen_load_toc_v4_PIC_1b (tocsym, lab));
19320 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
19321 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
19323 emit_insn (gen_addsi3 (dest, temp0, dest));
19325 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
19327 /* This is for AIX code running in non-PIC ELF32. */
19330 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
19331 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19333 emit_insn (gen_elf_high (dest, realsym));
19334 emit_insn (gen_elf_low (dest, dest, realsym));
19338 gcc_assert (DEFAULT_ABI == ABI_AIX);
19341 emit_insn (gen_load_toc_aix_si (dest));
19343 emit_insn (gen_load_toc_aix_di (dest));
19347 /* Emit instructions to restore the link register after determining where
19348 its value has been stored. */
19351 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
19353 rs6000_stack_t *info = rs6000_stack_info ();
19356 operands[0] = source;
19357 operands[1] = scratch;
19359 if (info->lr_save_p)
19361 rtx frame_rtx = stack_pointer_rtx;
19362 HOST_WIDE_INT sp_offset = 0;
19365 if (frame_pointer_needed
19366 || cfun->calls_alloca
19367 || info->total_size > 32767)
19369 tmp = gen_frame_mem (Pmode, frame_rtx);
19370 emit_move_insn (operands[1], tmp);
19371 frame_rtx = operands[1];
19373 else if (info->push_p)
19374 sp_offset = info->total_size;
19376 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
19377 tmp = gen_frame_mem (Pmode, tmp);
19378 emit_move_insn (tmp, operands[0]);
19381 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
19383 /* Freeze lr_save_p. We've just emitted rtl that depends on the
19384 state of lr_save_p so any change from here on would be a bug. In
19385 particular, stop rs6000_ra_ever_killed from considering the SET
19386 of lr we may have added just above. */
19387 cfun->machine->lr_save_state = info->lr_save_p + 1;
19390 static GTY(()) alias_set_type set = -1;
19393 get_TOC_alias_set (void)
19396 set = new_alias_set ();
19400 /* This returns nonzero if the current function uses the TOC. This is
19401 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
19402 is generated by the ABI_V4 load_toc_* patterns. */
19409 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
19412 rtx pat = PATTERN (insn);
19415 if (GET_CODE (pat) == PARALLEL)
19416 for (i = 0; i < XVECLEN (pat, 0); i++)
19418 rtx sub = XVECEXP (pat, 0, i);
19419 if (GET_CODE (sub) == USE)
19421 sub = XEXP (sub, 0);
19422 if (GET_CODE (sub) == UNSPEC
19423 && XINT (sub, 1) == UNSPEC_TOC)
19433 create_TOC_reference (rtx symbol, rtx largetoc_reg)
19435 rtx tocrel, tocreg;
19437 if (TARGET_DEBUG_ADDR)
19439 if (GET_CODE (symbol) == SYMBOL_REF)
19440 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
19444 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
19445 GET_RTX_NAME (GET_CODE (symbol)));
19446 debug_rtx (symbol);
19450 if (!can_create_pseudo_p ())
19451 df_set_regs_ever_live (TOC_REGISTER, true);
19453 tocrel = gen_rtx_CONST (Pmode,
19454 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol),
19456 tocreg = gen_rtx_REG (Pmode, TOC_REGISTER);
19457 if (TARGET_CMODEL != CMODEL_SMALL)
19459 rtx hi = gen_rtx_PLUS (Pmode, tocreg, gen_rtx_HIGH (Pmode, tocrel));
19460 if (largetoc_reg != NULL)
19462 emit_move_insn (largetoc_reg, hi);
19465 return gen_rtx_LO_SUM (Pmode, hi, copy_rtx (tocrel));
19468 return gen_rtx_PLUS (Pmode, tocreg, tocrel);
19471 /* Issue assembly directives that create a reference to the given DWARF
19472 FRAME_TABLE_LABEL from the current function section. */
19474 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
19476 fprintf (asm_out_file, "\t.ref %s\n",
19477 TARGET_STRIP_NAME_ENCODING (frame_table_label));
19480 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
19481 and the change to the stack pointer. */
19484 rs6000_emit_stack_tie (void)
19486 rtx mem = gen_frame_mem (BLKmode,
19487 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
19489 emit_insn (gen_stack_tie (mem));
19492 /* Emit the correct code for allocating stack space, as insns.
19493 If COPY_REG, make sure a copy of the old frame is left there.
19494 The generated code may use hard register 0 as a temporary. */
19497 rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg)
19500 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19501 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
19502 rtx todec = gen_int_mode (-size, Pmode);
19505 if (INTVAL (todec) != -size)
19507 warning (0, "stack frame too large");
19508 emit_insn (gen_trap ());
19512 if (crtl->limit_stack)
19514 if (REG_P (stack_limit_rtx)
19515 && REGNO (stack_limit_rtx) > 1
19516 && REGNO (stack_limit_rtx) <= 31)
19518 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
19519 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19522 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
19524 && DEFAULT_ABI == ABI_V4)
19526 rtx toload = gen_rtx_CONST (VOIDmode,
19527 gen_rtx_PLUS (Pmode,
19531 emit_insn (gen_elf_high (tmp_reg, toload));
19532 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
19533 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19537 warning (0, "stack limit expression is not supported");
19541 emit_move_insn (copy_reg, stack_reg);
19545 /* Need a note here so that try_split doesn't get confused. */
19546 if (get_last_insn () == NULL_RTX)
19547 emit_note (NOTE_INSN_DELETED);
19548 insn = emit_move_insn (tmp_reg, todec);
19549 try_split (PATTERN (insn), insn, 0);
19553 insn = emit_insn (TARGET_32BIT
19554 ? gen_movsi_update_stack (stack_reg, stack_reg,
19556 : gen_movdi_di_update_stack (stack_reg, stack_reg,
19557 todec, stack_reg));
19558 /* Since we didn't use gen_frame_mem to generate the MEM, grab
19559 it now and set the alias set/attributes. The above gen_*_update
19560 calls will generate a PARALLEL with the MEM set being the first
19562 par = PATTERN (insn);
19563 gcc_assert (GET_CODE (par) == PARALLEL);
19564 set = XVECEXP (par, 0, 0);
19565 gcc_assert (GET_CODE (set) == SET);
19566 mem = SET_DEST (set);
19567 gcc_assert (MEM_P (mem));
19568 MEM_NOTRAP_P (mem) = 1;
19569 set_mem_alias_set (mem, get_frame_alias_set ());
19571 RTX_FRAME_RELATED_P (insn) = 1;
19572 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
19573 gen_rtx_SET (VOIDmode, stack_reg,
19574 gen_rtx_PLUS (Pmode, stack_reg,
19575 GEN_INT (-size))));
19578 #define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
19580 #if PROBE_INTERVAL > 32768
19581 #error Cannot use indexed addressing mode for stack probing
19584 /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
19585 inclusive. These are offsets from the current stack pointer. */
19588 rs6000_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size)
19590 /* See if we have a constant small number of probes to generate. If so,
19591 that's the easy case. */
19592 if (first + size <= 32768)
19596 /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
19597 it exceeds SIZE. If only one probe is needed, this will not
19598 generate any code. Then probe at FIRST + SIZE. */
19599 for (i = PROBE_INTERVAL; i < size; i += PROBE_INTERVAL)
19600 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + i)));
19602 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + size)));
19605 /* Otherwise, do the same as above, but in a loop. Note that we must be
19606 extra careful with variables wrapping around because we might be at
19607 the very top (or the very bottom) of the address space and we have
19608 to be able to handle this case properly; in particular, we use an
19609 equality test for the loop condition. */
19612 HOST_WIDE_INT rounded_size;
19613 rtx r12 = gen_rtx_REG (Pmode, 12);
19614 rtx r0 = gen_rtx_REG (Pmode, 0);
19616 /* Sanity check for the addressing mode we're going to use. */
19617 gcc_assert (first <= 32768);
19619 /* Step 1: round SIZE to the previous multiple of the interval. */
19621 rounded_size = size & -PROBE_INTERVAL;
19624 /* Step 2: compute initial and final value of the loop counter. */
19626 /* TEST_ADDR = SP + FIRST. */
19627 emit_insn (gen_rtx_SET (VOIDmode, r12,
19628 plus_constant (stack_pointer_rtx, -first)));
19630 /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE. */
19631 if (rounded_size > 32768)
19633 emit_move_insn (r0, GEN_INT (-rounded_size));
19634 emit_insn (gen_rtx_SET (VOIDmode, r0,
19635 gen_rtx_PLUS (Pmode, r12, r0)));
19638 emit_insn (gen_rtx_SET (VOIDmode, r0,
19639 plus_constant (r12, -rounded_size)));
19642 /* Step 3: the loop
19644 while (TEST_ADDR != LAST_ADDR)
19646 TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
19650 probes at FIRST + N * PROBE_INTERVAL for values of N from 1
19651 until it is equal to ROUNDED_SIZE. */
19654 emit_insn (gen_probe_stack_rangedi (r12, r12, r0));
19656 emit_insn (gen_probe_stack_rangesi (r12, r12, r0));
19659 /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
19660 that SIZE is equal to ROUNDED_SIZE. */
19662 if (size != rounded_size)
19663 emit_stack_probe (plus_constant (r12, rounded_size - size));
19667 /* Probe a range of stack addresses from REG1 to REG2 inclusive. These are
19668 absolute addresses. */
19671 output_probe_stack_range (rtx reg1, rtx reg2)
19673 static int labelno = 0;
19674 char loop_lab[32], end_lab[32];
19677 ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno);
19678 ASM_GENERATE_INTERNAL_LABEL (end_lab, "LPSRE", labelno++);
19680 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
19682 /* Jump to END_LAB if TEST_ADDR == LAST_ADDR. */
19686 output_asm_insn ("{cmp|cmpd} 0,%0,%1", xops);
19688 output_asm_insn ("{cmp|cmpw} 0,%0,%1", xops);
19690 fputs ("\tbeq 0,", asm_out_file);
19691 assemble_name_raw (asm_out_file, end_lab);
19692 fputc ('\n', asm_out_file);
19694 /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */
19695 xops[1] = GEN_INT (-PROBE_INTERVAL);
19696 output_asm_insn ("{cal %0,%1(%0)|addi %0,%0,%1}", xops);
19698 /* Probe at TEST_ADDR and branch. */
19699 output_asm_insn ("{st|stw} 0,0(%0)", xops);
19700 fprintf (asm_out_file, "\tb ");
19701 assemble_name_raw (asm_out_file, loop_lab);
19702 fputc ('\n', asm_out_file);
19704 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, end_lab);
19709 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
19710 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
19711 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
19712 deduce these equivalences by itself so it wasn't necessary to hold
19713 its hand so much. */
19716 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
19717 rtx reg2, rtx rreg)
19721 /* copy_rtx will not make unique copies of registers, so we need to
19722 ensure we don't have unwanted sharing here. */
19724 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19727 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19729 real = copy_rtx (PATTERN (insn));
19731 if (reg2 != NULL_RTX)
19732 real = replace_rtx (real, reg2, rreg);
19734 real = replace_rtx (real, reg,
19735 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
19736 STACK_POINTER_REGNUM),
19739 /* We expect that 'real' is either a SET or a PARALLEL containing
19740 SETs (and possibly other stuff). In a PARALLEL, all the SETs
19741 are important so they all have to be marked RTX_FRAME_RELATED_P. */
19743 if (GET_CODE (real) == SET)
19747 temp = simplify_rtx (SET_SRC (set));
19749 SET_SRC (set) = temp;
19750 temp = simplify_rtx (SET_DEST (set));
19752 SET_DEST (set) = temp;
19753 if (GET_CODE (SET_DEST (set)) == MEM)
19755 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19757 XEXP (SET_DEST (set), 0) = temp;
19764 gcc_assert (GET_CODE (real) == PARALLEL);
19765 for (i = 0; i < XVECLEN (real, 0); i++)
19766 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
19768 rtx set = XVECEXP (real, 0, i);
19770 temp = simplify_rtx (SET_SRC (set));
19772 SET_SRC (set) = temp;
19773 temp = simplify_rtx (SET_DEST (set));
19775 SET_DEST (set) = temp;
19776 if (GET_CODE (SET_DEST (set)) == MEM)
19778 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19780 XEXP (SET_DEST (set), 0) = temp;
19782 RTX_FRAME_RELATED_P (set) = 1;
19786 RTX_FRAME_RELATED_P (insn) = 1;
19787 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
19790 /* Returns an insn that has a vrsave set operation with the
19791 appropriate CLOBBERs. */
19794 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
19797 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
19798 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19801 = gen_rtx_SET (VOIDmode,
19803 gen_rtx_UNSPEC_VOLATILE (SImode,
19804 gen_rtvec (2, reg, vrsave),
19805 UNSPECV_SET_VRSAVE));
19809 /* We need to clobber the registers in the mask so the scheduler
19810 does not move sets to VRSAVE before sets of AltiVec registers.
19812 However, if the function receives nonlocal gotos, reload will set
19813 all call saved registers live. We will end up with:
19815 (set (reg 999) (mem))
19816 (parallel [ (set (reg vrsave) (unspec blah))
19817 (clobber (reg 999))])
19819 The clobber will cause the store into reg 999 to be dead, and
19820 flow will attempt to delete an epilogue insn. In this case, we
19821 need an unspec use/set of the register. */
19823 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
19824 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19826 if (!epiloguep || call_used_regs [i])
19827 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
19828 gen_rtx_REG (V4SImode, i));
19831 rtx reg = gen_rtx_REG (V4SImode, i);
19834 = gen_rtx_SET (VOIDmode,
19836 gen_rtx_UNSPEC (V4SImode,
19837 gen_rtvec (1, reg), 27));
19841 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
19843 for (i = 0; i < nclobs; ++i)
19844 XVECEXP (insn, 0, i) = clobs[i];
19849 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
19850 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
19853 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
19854 unsigned int regno, int offset, HOST_WIDE_INT total_size)
19856 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
19857 rtx replacea, replaceb;
19859 int_rtx = GEN_INT (offset);
19861 /* Some cases that need register indexed addressing. */
19862 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
19863 || (TARGET_VSX && VSX_VECTOR_MODE (mode))
19864 || (TARGET_E500_DOUBLE && mode == DFmode)
19866 && SPE_VECTOR_MODE (mode)
19867 && !SPE_CONST_OFFSET_OK (offset)))
19869 /* Whomever calls us must make sure r11 is available in the
19870 flow path of instructions in the prologue. */
19871 offset_rtx = gen_rtx_REG (Pmode, 11);
19872 emit_move_insn (offset_rtx, int_rtx);
19874 replacea = offset_rtx;
19875 replaceb = int_rtx;
19879 offset_rtx = int_rtx;
19880 replacea = NULL_RTX;
19881 replaceb = NULL_RTX;
19884 reg = gen_rtx_REG (mode, regno);
19885 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
19886 mem = gen_frame_mem (mode, addr);
19888 insn = emit_move_insn (mem, reg);
19890 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
19893 /* Emit an offset memory reference suitable for a frame store, while
19894 converting to a valid addressing mode. */
19897 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
19899 rtx int_rtx, offset_rtx;
19901 int_rtx = GEN_INT (offset);
19903 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
19904 || (TARGET_E500_DOUBLE && mode == DFmode))
19906 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
19907 emit_move_insn (offset_rtx, int_rtx);
19910 offset_rtx = int_rtx;
19912 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
19915 /* Look for user-defined global regs. We should not save and restore these,
19916 and cannot use stmw/lmw if there are any in its range. */
19919 no_global_regs_above (int first, bool gpr)
19922 int last = gpr ? 32 : 64;
19923 for (i = first; i < last; i++)
19924 if (global_regs[i])
19929 #ifndef TARGET_FIX_AND_CONTINUE
19930 #define TARGET_FIX_AND_CONTINUE 0
19933 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
19934 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
19935 #define LAST_SAVRES_REGISTER 31
19936 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
19938 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
19940 /* Temporary holding space for an out-of-line register save/restore
19942 static char savres_routine_name[30];
19944 /* Return the name for an out-of-line register save/restore routine.
19945 We are saving/restoring GPRs if GPR is true. */
19948 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
19949 bool savep, bool gpr, bool lr)
19951 const char *prefix = "";
19952 const char *suffix = "";
19954 /* Different targets are supposed to define
19955 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
19956 routine name could be defined with:
19958 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
19960 This is a nice idea in practice, but in reality, things are
19961 complicated in several ways:
19963 - ELF targets have save/restore routines for GPRs.
19965 - SPE targets use different prefixes for 32/64-bit registers, and
19966 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
19968 - PPC64 ELF targets have routines for save/restore of GPRs that
19969 differ in what they do with the link register, so having a set
19970 prefix doesn't work. (We only use one of the save routines at
19971 the moment, though.)
19973 - PPC32 elf targets have "exit" versions of the restore routines
19974 that restore the link register and can save some extra space.
19975 These require an extra suffix. (There are also "tail" versions
19976 of the restore routines and "GOT" versions of the save routines,
19977 but we don't generate those at present. Same problems apply,
19980 We deal with all this by synthesizing our own prefix/suffix and
19981 using that for the simple sprintf call shown above. */
19984 /* No floating point saves on the SPE. */
19988 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
19990 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
19995 else if (DEFAULT_ABI == ABI_V4)
20001 prefix = savep ? "_savegpr_" : "_restgpr_";
20003 prefix = savep ? "_savefpr_" : "_restfpr_";
20008 else if (DEFAULT_ABI == ABI_AIX)
20010 #ifndef POWERPC_LINUX
20011 /* No out-of-line save/restore routines for GPRs on AIX. */
20012 gcc_assert (!TARGET_AIX || !gpr);
20018 ? (lr ? "_savegpr0_" : "_savegpr1_")
20019 : (lr ? "_restgpr0_" : "_restgpr1_"));
20020 #ifdef POWERPC_LINUX
20022 prefix = (savep ? "_savefpr_" : "_restfpr_");
20026 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
20027 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
20030 else if (DEFAULT_ABI == ABI_DARWIN)
20031 sorry ("out-of-line save/restore routines not supported on Darwin");
20033 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
20035 return savres_routine_name;
20038 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
20039 We are saving/restoring GPRs if GPR is true. */
20042 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
20045 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
20047 int select = ((savep ? 1 : 0) << 2
20049 /* On the SPE, we never have any FPRs, but we do have
20050 32/64-bit versions of the routines. */
20051 ? (info->spe_64bit_regs_used ? 1 : 0)
20052 : (gpr ? 1 : 0)) << 1)
20055 /* Don't generate bogus routine names. */
20056 gcc_assert (FIRST_SAVRES_REGISTER <= regno
20057 && regno <= LAST_SAVRES_REGISTER);
20059 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
20065 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
20067 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
20068 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
20069 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
20075 /* Emit a sequence of insns, including a stack tie if needed, for
20076 resetting the stack pointer. If SAVRES is true, then don't reset the
20077 stack pointer, but move the base of the frame into r11 for use by
20078 out-of-line register restore routines. */
20081 rs6000_emit_stack_reset (rs6000_stack_t *info,
20082 rtx sp_reg_rtx, rtx frame_reg_rtx,
20083 int sp_offset, bool savres)
20085 /* This blockage is needed so that sched doesn't decide to move
20086 the sp change before the register restores. */
20087 if (frame_reg_rtx != sp_reg_rtx
20089 && info->spe_64bit_regs_used != 0
20090 && info->first_gp_reg_save != 32))
20091 rs6000_emit_stack_tie ();
20093 if (frame_reg_rtx != sp_reg_rtx)
20095 if (sp_offset != 0)
20097 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
20098 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
20099 GEN_INT (sp_offset)));
20102 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
20104 else if (sp_offset != 0)
20106 /* If we are restoring registers out-of-line, we will be using the
20107 "exit" variants of the restore routines, which will reset the
20108 stack for us. But we do need to point r11 into the right place
20109 for those routines. */
20110 rtx dest_reg = (savres
20111 ? gen_rtx_REG (Pmode, 11)
20114 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
20115 GEN_INT (sp_offset)));
20122 /* Construct a parallel rtx describing the effect of a call to an
20123 out-of-line register save/restore routine. */
20126 rs6000_make_savres_rtx (rs6000_stack_t *info,
20127 rtx frame_reg_rtx, int save_area_offset,
20128 enum machine_mode reg_mode,
20129 bool savep, bool gpr, bool lr)
20132 int offset, start_reg, end_reg, n_regs;
20133 int reg_size = GET_MODE_SIZE (reg_mode);
20139 ? info->first_gp_reg_save
20140 : info->first_fp_reg_save);
20141 end_reg = gpr ? 32 : 64;
20142 n_regs = end_reg - start_reg;
20143 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
20146 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
20148 RTVEC_ELT (p, offset++)
20149 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
20151 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
20152 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
20153 RTVEC_ELT (p, offset++)
20154 = gen_rtx_USE (VOIDmode,
20155 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
20159 for (i = 0; i < end_reg - start_reg; i++)
20161 rtx addr, reg, mem;
20162 reg = gen_rtx_REG (reg_mode, start_reg + i);
20163 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20164 GEN_INT (save_area_offset + reg_size*i));
20165 mem = gen_frame_mem (reg_mode, addr);
20167 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
20169 savep ? reg : mem);
20174 rtx addr, reg, mem;
20175 reg = gen_rtx_REG (Pmode, 0);
20176 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20177 GEN_INT (info->lr_save_offset));
20178 mem = gen_frame_mem (Pmode, addr);
20179 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
20182 return gen_rtx_PARALLEL (VOIDmode, p);
20185 /* Determine whether the gp REG is really used. */
20188 rs6000_reg_live_or_pic_offset_p (int reg)
20190 /* If the function calls eh_return, claim used all the registers that would
20191 be checked for liveness otherwise. This is required for the PIC offset
20192 register with -mminimal-toc on AIX, as it is advertised as "fixed" for
20193 register allocation purposes in this case. */
20195 return (((crtl->calls_eh_return || df_regs_ever_live_p (reg))
20196 && (!call_used_regs[reg]
20197 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
20198 && !TARGET_SINGLE_PIC_BASE
20199 && TARGET_TOC && TARGET_MINIMAL_TOC)))
20200 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
20201 && !TARGET_SINGLE_PIC_BASE
20202 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
20203 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
20206 /* Emit function prologue as insns. */
20209 rs6000_emit_prologue (void)
20211 rs6000_stack_t *info = rs6000_stack_info ();
20212 enum machine_mode reg_mode = Pmode;
20213 int reg_size = TARGET_32BIT ? 4 : 8;
20214 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
20215 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
20216 rtx frame_reg_rtx = sp_reg_rtx;
20217 rtx cr_save_rtx = NULL_RTX;
20220 int saving_FPRs_inline;
20221 int saving_GPRs_inline;
20222 int using_store_multiple;
20223 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
20224 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
20225 && call_used_regs[STATIC_CHAIN_REGNUM]);
20226 HOST_WIDE_INT sp_offset = 0;
20228 if (flag_stack_usage)
20229 current_function_static_stack_size = info->total_size;
20231 if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK && info->total_size)
20232 rs6000_emit_probe_stack_range (STACK_CHECK_PROTECT, info->total_size);
20234 if (TARGET_FIX_AND_CONTINUE)
20236 /* gdb on darwin arranges to forward a function from the old
20237 address by modifying the first 5 instructions of the function
20238 to branch to the overriding function. This is necessary to
20239 permit function pointers that point to the old function to
20240 actually forward to the new function. */
20241 emit_insn (gen_nop ());
20242 emit_insn (gen_nop ());
20243 emit_insn (gen_nop ());
20244 emit_insn (gen_nop ());
20245 emit_insn (gen_nop ());
20248 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
20250 reg_mode = V2SImode;
20254 strategy = info->savres_strategy;
20255 using_store_multiple = strategy & SAVRES_MULTIPLE;
20256 saving_FPRs_inline = strategy & SAVE_INLINE_FPRS;
20257 saving_GPRs_inline = strategy & SAVE_INLINE_GPRS;
20259 /* For V.4, update stack before we do any saving and set back pointer. */
20260 if (! WORLD_SAVE_P (info)
20262 && (DEFAULT_ABI == ABI_V4
20263 || crtl->calls_eh_return))
20265 bool need_r11 = (TARGET_SPE
20266 ? (!saving_GPRs_inline
20267 && info->spe_64bit_regs_used == 0)
20268 : (!saving_FPRs_inline || !saving_GPRs_inline));
20269 rtx copy_reg = need_r11 ? gen_rtx_REG (Pmode, 11) : NULL;
20271 if (info->total_size < 32767)
20272 sp_offset = info->total_size;
20274 frame_reg_rtx = copy_reg;
20275 else if (info->cr_save_p
20277 || info->first_fp_reg_save < 64
20278 || info->first_gp_reg_save < 32
20279 || info->altivec_size != 0
20280 || info->vrsave_mask != 0
20281 || crtl->calls_eh_return)
20283 copy_reg = frame_ptr_rtx;
20284 frame_reg_rtx = copy_reg;
20288 /* The prologue won't be saving any regs so there is no need
20289 to set up a frame register to access any frame save area.
20290 We also won't be using sp_offset anywhere below, but set
20291 the correct value anyway to protect against future
20292 changes to this function. */
20293 sp_offset = info->total_size;
20295 rs6000_emit_allocate_stack (info->total_size, copy_reg);
20296 if (frame_reg_rtx != sp_reg_rtx)
20297 rs6000_emit_stack_tie ();
20300 /* Handle world saves specially here. */
20301 if (WORLD_SAVE_P (info))
20308 /* save_world expects lr in r0. */
20309 reg0 = gen_rtx_REG (Pmode, 0);
20310 if (info->lr_save_p)
20312 insn = emit_move_insn (reg0,
20313 gen_rtx_REG (Pmode, LR_REGNO));
20314 RTX_FRAME_RELATED_P (insn) = 1;
20317 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
20318 assumptions about the offsets of various bits of the stack
20320 gcc_assert (info->gp_save_offset == -220
20321 && info->fp_save_offset == -144
20322 && info->lr_save_offset == 8
20323 && info->cr_save_offset == 4
20326 && (!crtl->calls_eh_return
20327 || info->ehrd_offset == -432)
20328 && info->vrsave_save_offset == -224
20329 && info->altivec_save_offset == -416);
20331 treg = gen_rtx_REG (SImode, 11);
20332 emit_move_insn (treg, GEN_INT (-info->total_size));
20334 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
20335 in R11. It also clobbers R12, so beware! */
20337 /* Preserve CR2 for save_world prologues */
20339 sz += 32 - info->first_gp_reg_save;
20340 sz += 64 - info->first_fp_reg_save;
20341 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
20342 p = rtvec_alloc (sz);
20344 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
20345 gen_rtx_REG (SImode,
20347 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
20348 gen_rtx_SYMBOL_REF (Pmode,
20350 /* We do floats first so that the instruction pattern matches
20352 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20354 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20355 ? DFmode : SFmode),
20356 info->first_fp_reg_save + i);
20357 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20358 GEN_INT (info->fp_save_offset
20359 + sp_offset + 8 * i));
20360 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20361 ? DFmode : SFmode), addr);
20363 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20365 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
20367 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
20368 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20369 GEN_INT (info->altivec_save_offset
20370 + sp_offset + 16 * i));
20371 rtx mem = gen_frame_mem (V4SImode, addr);
20373 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20375 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20377 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20378 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20379 GEN_INT (info->gp_save_offset
20380 + sp_offset + reg_size * i));
20381 rtx mem = gen_frame_mem (reg_mode, addr);
20383 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20387 /* CR register traditionally saved as CR2. */
20388 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
20389 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20390 GEN_INT (info->cr_save_offset
20392 rtx mem = gen_frame_mem (reg_mode, addr);
20394 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20396 /* Explain about use of R0. */
20397 if (info->lr_save_p)
20399 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20400 GEN_INT (info->lr_save_offset
20402 rtx mem = gen_frame_mem (reg_mode, addr);
20404 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
20406 /* Explain what happens to the stack pointer. */
20408 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
20409 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
20412 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20413 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20414 treg, GEN_INT (-info->total_size));
20415 sp_offset = info->total_size;
20418 /* If we use the link register, get it into r0. */
20419 if (!WORLD_SAVE_P (info) && info->lr_save_p)
20421 rtx addr, reg, mem;
20423 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
20424 gen_rtx_REG (Pmode, LR_REGNO));
20425 RTX_FRAME_RELATED_P (insn) = 1;
20427 if (!(strategy & (SAVE_NOINLINE_GPRS_SAVES_LR
20428 | SAVE_NOINLINE_FPRS_SAVES_LR)))
20430 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20431 GEN_INT (info->lr_save_offset + sp_offset));
20432 reg = gen_rtx_REG (Pmode, 0);
20433 mem = gen_rtx_MEM (Pmode, addr);
20434 /* This should not be of rs6000_sr_alias_set, because of
20435 __builtin_return_address. */
20437 insn = emit_move_insn (mem, reg);
20438 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20439 NULL_RTX, NULL_RTX);
20443 /* If we need to save CR, put it into r12 or r11. */
20444 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
20449 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
20451 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20452 RTX_FRAME_RELATED_P (insn) = 1;
20453 /* Now, there's no way that dwarf2out_frame_debug_expr is going
20454 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
20455 But that's OK. All we have to do is specify that _one_ condition
20456 code register is saved in this stack slot. The thrower's epilogue
20457 will then restore all the call-saved registers.
20458 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
20459 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
20460 gen_rtx_REG (SImode, CR2_REGNO));
20461 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20464 /* Do any required saving of fpr's. If only one or two to save, do
20465 it ourselves. Otherwise, call function. */
20466 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
20469 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20470 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
20471 && ! call_used_regs[info->first_fp_reg_save+i]))
20472 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
20473 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20475 info->first_fp_reg_save + i,
20476 info->fp_save_offset + sp_offset + 8 * i,
20479 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
20483 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20484 info->fp_save_offset + sp_offset,
20486 /*savep=*/true, /*gpr=*/false,
20488 & SAVE_NOINLINE_FPRS_SAVES_LR)
20490 insn = emit_insn (par);
20491 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20492 NULL_RTX, NULL_RTX);
20495 /* Save GPRs. This is done as a PARALLEL if we are using
20496 the store-multiple instructions. */
20497 if (!WORLD_SAVE_P (info)
20499 && info->spe_64bit_regs_used != 0
20500 && info->first_gp_reg_save != 32)
20503 rtx spe_save_area_ptr;
20505 /* Determine whether we can address all of the registers that need
20506 to be saved with an offset from the stack pointer that fits in
20507 the small const field for SPE memory instructions. */
20508 int spe_regs_addressable_via_sp
20509 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
20510 + (32 - info->first_gp_reg_save - 1) * reg_size)
20511 && saving_GPRs_inline);
20514 if (spe_regs_addressable_via_sp)
20516 spe_save_area_ptr = frame_reg_rtx;
20517 spe_offset = info->spe_gp_save_offset + sp_offset;
20521 /* Make r11 point to the start of the SPE save area. We need
20522 to be careful here if r11 is holding the static chain. If
20523 it is, then temporarily save it in r0. We would use r0 as
20524 our base register here, but using r0 as a base register in
20525 loads and stores means something different from what we
20527 int ool_adjust = (saving_GPRs_inline
20529 : (info->first_gp_reg_save
20530 - (FIRST_SAVRES_REGISTER+1))*8);
20531 HOST_WIDE_INT offset = (info->spe_gp_save_offset
20532 + sp_offset - ool_adjust);
20534 if (using_static_chain_p)
20536 rtx r0 = gen_rtx_REG (Pmode, 0);
20537 gcc_assert (info->first_gp_reg_save > 11);
20539 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
20542 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
20543 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
20545 GEN_INT (offset)));
20546 /* We need to make sure the move to r11 gets noted for
20547 properly outputting unwind information. */
20548 if (!saving_GPRs_inline)
20549 rs6000_frame_related (insn, frame_reg_rtx, offset,
20550 NULL_RTX, NULL_RTX);
20554 if (saving_GPRs_inline)
20556 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20557 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20559 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20560 rtx offset, addr, mem;
20562 /* We're doing all this to ensure that the offset fits into
20563 the immediate offset of 'evstdd'. */
20564 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
20566 offset = GEN_INT (reg_size * i + spe_offset);
20567 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
20568 mem = gen_rtx_MEM (V2SImode, addr);
20570 insn = emit_move_insn (mem, reg);
20572 rs6000_frame_related (insn, spe_save_area_ptr,
20573 info->spe_gp_save_offset
20574 + sp_offset + reg_size * i,
20575 offset, const0_rtx);
20582 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
20584 /*savep=*/true, /*gpr=*/true,
20586 insn = emit_insn (par);
20587 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20588 NULL_RTX, NULL_RTX);
20592 /* Move the static chain pointer back. */
20593 if (using_static_chain_p && !spe_regs_addressable_via_sp)
20594 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
20596 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
20600 /* Need to adjust r11 (r12) if we saved any FPRs. */
20601 if (info->first_fp_reg_save != 64)
20603 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
20605 rtx offset = GEN_INT (sp_offset
20606 + (-8 * (64-info->first_fp_reg_save)));
20607 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
20610 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20611 info->gp_save_offset + sp_offset,
20613 /*savep=*/true, /*gpr=*/true,
20615 & SAVE_NOINLINE_GPRS_SAVES_LR)
20617 insn = emit_insn (par);
20618 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20619 NULL_RTX, NULL_RTX);
20621 else if (!WORLD_SAVE_P (info) && using_store_multiple)
20625 p = rtvec_alloc (32 - info->first_gp_reg_save);
20626 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20628 rtx addr, reg, mem;
20629 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20630 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20631 GEN_INT (info->gp_save_offset
20634 mem = gen_frame_mem (reg_mode, addr);
20636 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
20638 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20639 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20640 NULL_RTX, NULL_RTX);
20642 else if (!WORLD_SAVE_P (info))
20645 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20646 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20648 rtx addr, reg, mem;
20649 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20651 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20652 GEN_INT (info->gp_save_offset
20655 mem = gen_frame_mem (reg_mode, addr);
20657 insn = emit_move_insn (mem, reg);
20658 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20659 NULL_RTX, NULL_RTX);
20663 /* ??? There's no need to emit actual instructions here, but it's the
20664 easiest way to get the frame unwind information emitted. */
20665 if (crtl->calls_eh_return)
20667 unsigned int i, regno;
20671 regno = EH_RETURN_DATA_REGNO (i);
20672 if (regno == INVALID_REGNUM)
20675 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
20676 info->ehrd_offset + sp_offset
20677 + reg_size * (int) i,
20682 /* In AIX ABI we need to make sure r2 is really saved. */
20683 if (TARGET_AIX && crtl->calls_eh_return)
20685 rtx tmp_reg, tmp_reg_si, hi, lo, compare_result, toc_save_done, jump;
20686 long toc_restore_insn;
20688 gcc_assert (frame_reg_rtx == frame_ptr_rtx
20689 || frame_reg_rtx == sp_reg_rtx);
20690 tmp_reg = gen_rtx_REG (Pmode, 11);
20691 tmp_reg_si = gen_rtx_REG (SImode, 11);
20692 if (using_static_chain_p)
20693 emit_move_insn (gen_rtx_REG (Pmode, 0), tmp_reg);
20694 gcc_assert (saving_GPRs_inline && saving_FPRs_inline);
20695 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, LR_REGNO));
20696 /* Peek at instruction to which this function returns. If it's
20697 restoring r2, then we know we've already saved r2. We can't
20698 unconditionally save r2 because the value we have will already
20699 be updated if we arrived at this function via a plt call or
20700 toc adjusting stub. */
20701 emit_move_insn (tmp_reg_si, gen_rtx_MEM (SImode, tmp_reg));
20702 toc_restore_insn = TARGET_32BIT ? 0x80410014 : 0xE8410028;
20703 hi = gen_int_mode (toc_restore_insn & ~0xffff, SImode);
20704 emit_insn (gen_xorsi3 (tmp_reg_si, tmp_reg_si, hi));
20705 compare_result = gen_rtx_REG (CCUNSmode, CR0_REGNO);
20706 validate_condition_mode (EQ, CCUNSmode);
20707 lo = gen_int_mode (toc_restore_insn & 0xffff, SImode);
20708 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
20709 gen_rtx_COMPARE (CCUNSmode, tmp_reg_si, lo)));
20710 toc_save_done = gen_label_rtx ();
20711 jump = gen_rtx_IF_THEN_ELSE (VOIDmode,
20712 gen_rtx_EQ (VOIDmode, compare_result,
20714 gen_rtx_LABEL_REF (VOIDmode, toc_save_done),
20716 jump = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, jump));
20717 JUMP_LABEL (jump) = toc_save_done;
20718 LABEL_NUSES (toc_save_done) += 1;
20720 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, 2,
20721 sp_offset + 5 * reg_size, info->total_size);
20722 emit_label (toc_save_done);
20723 if (using_static_chain_p)
20724 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, 0));
20727 /* Save CR if we use any that must be preserved. */
20728 if (!WORLD_SAVE_P (info) && info->cr_save_p)
20730 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20731 GEN_INT (info->cr_save_offset + sp_offset));
20732 rtx mem = gen_frame_mem (SImode, addr);
20733 /* See the large comment above about why CR2_REGNO is used. */
20734 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
20736 /* If r12 was used to hold the original sp, copy cr into r0 now
20738 if (REGNO (frame_reg_rtx) == 12)
20742 cr_save_rtx = gen_rtx_REG (SImode, 0);
20743 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20744 RTX_FRAME_RELATED_P (insn) = 1;
20745 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
20746 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20748 insn = emit_move_insn (mem, cr_save_rtx);
20750 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20751 NULL_RTX, NULL_RTX);
20754 /* Update stack and set back pointer unless this is V.4,
20755 for which it was done previously. */
20756 if (!WORLD_SAVE_P (info) && info->push_p
20757 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
20759 rtx copy_reg = NULL;
20761 if (info->total_size < 32767)
20762 sp_offset = info->total_size;
20763 else if (info->altivec_size != 0
20764 || info->vrsave_mask != 0)
20766 copy_reg = frame_ptr_rtx;
20767 frame_reg_rtx = copy_reg;
20770 sp_offset = info->total_size;
20771 rs6000_emit_allocate_stack (info->total_size, copy_reg);
20772 if (frame_reg_rtx != sp_reg_rtx)
20773 rs6000_emit_stack_tie ();
20776 /* Set frame pointer, if needed. */
20777 if (frame_pointer_needed)
20779 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
20781 RTX_FRAME_RELATED_P (insn) = 1;
20784 /* Save AltiVec registers if needed. Save here because the red zone does
20785 not include AltiVec registers. */
20786 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
20790 /* There should be a non inline version of this, for when we
20791 are saving lots of vector registers. */
20792 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20793 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20795 rtx areg, savereg, mem;
20798 offset = info->altivec_save_offset + sp_offset
20799 + 16 * (i - info->first_altivec_reg_save);
20801 savereg = gen_rtx_REG (V4SImode, i);
20803 areg = gen_rtx_REG (Pmode, 0);
20804 emit_move_insn (areg, GEN_INT (offset));
20806 /* AltiVec addressing mode is [reg+reg]. */
20807 mem = gen_frame_mem (V4SImode,
20808 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
20810 insn = emit_move_insn (mem, savereg);
20812 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20813 areg, GEN_INT (offset));
20817 /* VRSAVE is a bit vector representing which AltiVec registers
20818 are used. The OS uses this to determine which vector
20819 registers to save on a context switch. We need to save
20820 VRSAVE on the stack frame, add whatever AltiVec registers we
20821 used in this function, and do the corresponding magic in the
20824 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
20825 && info->vrsave_mask != 0)
20827 rtx reg, mem, vrsave;
20830 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
20831 as frame_reg_rtx and r11 as the static chain pointer for
20832 nested functions. */
20833 reg = gen_rtx_REG (SImode, 0);
20834 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
20836 emit_insn (gen_get_vrsave_internal (reg));
20838 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
20840 if (!WORLD_SAVE_P (info))
20843 offset = info->vrsave_save_offset + sp_offset;
20844 mem = gen_frame_mem (SImode,
20845 gen_rtx_PLUS (Pmode, frame_reg_rtx,
20846 GEN_INT (offset)));
20847 insn = emit_move_insn (mem, reg);
20850 /* Include the registers in the mask. */
20851 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
20853 insn = emit_insn (generate_set_vrsave (reg, info, 0));
20856 if (TARGET_SINGLE_PIC_BASE)
20857 return; /* Do not set PIC register */
20859 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
20860 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
20861 || (DEFAULT_ABI == ABI_V4
20862 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
20863 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
20865 /* If emit_load_toc_table will use the link register, we need to save
20866 it. We use R12 for this purpose because emit_load_toc_table
20867 can use register 0. This allows us to use a plain 'blr' to return
20868 from the procedure more often. */
20869 int save_LR_around_toc_setup = (TARGET_ELF
20870 && DEFAULT_ABI != ABI_AIX
20872 && ! info->lr_save_p
20873 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
20874 if (save_LR_around_toc_setup)
20876 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
20878 insn = emit_move_insn (frame_ptr_rtx, lr);
20879 RTX_FRAME_RELATED_P (insn) = 1;
20881 rs6000_emit_load_toc_table (TRUE);
20883 insn = emit_move_insn (lr, frame_ptr_rtx);
20884 RTX_FRAME_RELATED_P (insn) = 1;
20887 rs6000_emit_load_toc_table (TRUE);
20891 if (DEFAULT_ABI == ABI_DARWIN
20892 && flag_pic && crtl->uses_pic_offset_table)
20894 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
20895 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
20897 /* Save and restore LR locally around this call (in R0). */
20898 if (!info->lr_save_p)
20899 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
20901 emit_insn (gen_load_macho_picbase (src));
20903 emit_move_insn (gen_rtx_REG (Pmode,
20904 RS6000_PIC_OFFSET_TABLE_REGNUM),
20907 if (!info->lr_save_p)
20908 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
20913 /* Write function prologue. */
20916 rs6000_output_function_prologue (FILE *file,
20917 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
20919 rs6000_stack_t *info = rs6000_stack_info ();
20921 if (TARGET_DEBUG_STACK)
20922 debug_stack_info (info);
20924 /* Write .extern for any function we will call to save and restore
20926 if (info->first_fp_reg_save < 64)
20929 int regno = info->first_fp_reg_save - 32;
20931 if ((info->savres_strategy & SAVE_INLINE_FPRS) == 0)
20933 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
20934 /*gpr=*/false, /*lr=*/false);
20935 fprintf (file, "\t.extern %s\n", name);
20937 if ((info->savres_strategy & REST_INLINE_FPRS) == 0)
20939 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
20940 /*gpr=*/false, /*lr=*/true);
20941 fprintf (file, "\t.extern %s\n", name);
20945 /* Write .extern for AIX common mode routines, if needed. */
20946 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
20948 fputs ("\t.extern __mulh\n", file);
20949 fputs ("\t.extern __mull\n", file);
20950 fputs ("\t.extern __divss\n", file);
20951 fputs ("\t.extern __divus\n", file);
20952 fputs ("\t.extern __quoss\n", file);
20953 fputs ("\t.extern __quous\n", file);
20954 common_mode_defined = 1;
20957 if (! HAVE_prologue)
20963 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
20964 the "toplevel" insn chain. */
20965 emit_note (NOTE_INSN_DELETED);
20966 rs6000_emit_prologue ();
20967 emit_note (NOTE_INSN_DELETED);
20969 /* Expand INSN_ADDRESSES so final() doesn't crash. */
20973 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
20975 INSN_ADDRESSES_NEW (insn, addr);
20980 prologue = get_insns ();
20983 if (TARGET_DEBUG_STACK)
20984 debug_rtx_list (prologue, 100);
20986 emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb),
20990 rs6000_pic_labelno++;
20993 /* Non-zero if vmx regs are restored before the frame pop, zero if
20994 we restore after the pop when possible. */
20995 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
20997 /* Reload CR from REG. */
21000 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
21005 if (using_mfcr_multiple)
21007 for (i = 0; i < 8; i++)
21008 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
21010 gcc_assert (count);
21013 if (using_mfcr_multiple && count > 1)
21018 p = rtvec_alloc (count);
21021 for (i = 0; i < 8; i++)
21022 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
21024 rtvec r = rtvec_alloc (2);
21025 RTVEC_ELT (r, 0) = reg;
21026 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
21027 RTVEC_ELT (p, ndx) =
21028 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
21029 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
21032 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
21033 gcc_assert (ndx == count);
21036 for (i = 0; i < 8; i++)
21037 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
21039 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
21045 /* Return true if OFFSET from stack pointer can be clobbered by signals.
21046 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
21047 below stack pointer not cloberred by signals. */
21050 offset_below_red_zone_p (HOST_WIDE_INT offset)
21052 return offset < (DEFAULT_ABI == ABI_V4
21054 : TARGET_32BIT ? -220 : -288);
21057 /* Emit function epilogue as insns. */
21060 rs6000_emit_epilogue (int sibcall)
21062 rs6000_stack_t *info;
21063 int restoring_GPRs_inline;
21064 int restoring_FPRs_inline;
21065 int using_load_multiple;
21066 int using_mtcr_multiple;
21067 int use_backchain_to_restore_sp;
21071 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
21072 rtx frame_reg_rtx = sp_reg_rtx;
21073 rtx cfa_restores = NULL_RTX;
21075 rtx cr_save_reg = NULL_RTX;
21076 enum machine_mode reg_mode = Pmode;
21077 int reg_size = TARGET_32BIT ? 4 : 8;
21080 info = rs6000_stack_info ();
21082 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
21084 reg_mode = V2SImode;
21088 strategy = info->savres_strategy;
21089 using_load_multiple = strategy & SAVRES_MULTIPLE;
21090 restoring_FPRs_inline = sibcall || (strategy & REST_INLINE_FPRS);
21091 restoring_GPRs_inline = sibcall || (strategy & REST_INLINE_GPRS);
21092 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
21093 || rs6000_cpu == PROCESSOR_PPC603
21094 || rs6000_cpu == PROCESSOR_PPC750
21096 /* Restore via the backchain when we have a large frame, since this
21097 is more efficient than an addis, addi pair. The second condition
21098 here will not trigger at the moment; We don't actually need a
21099 frame pointer for alloca, but the generic parts of the compiler
21100 give us one anyway. */
21101 use_backchain_to_restore_sp = (info->total_size > 32767
21102 || info->total_size
21103 + (info->lr_save_p ? info->lr_save_offset : 0)
21105 || (cfun->calls_alloca
21106 && !frame_pointer_needed));
21107 restore_lr = (info->lr_save_p
21108 && (restoring_FPRs_inline
21109 || (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR))
21110 && (restoring_GPRs_inline
21111 || info->first_fp_reg_save < 64));
21113 if (WORLD_SAVE_P (info))
21117 const char *alloc_rname;
21120 /* eh_rest_world_r10 will return to the location saved in the LR
21121 stack slot (which is not likely to be our caller.)
21122 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
21123 rest_world is similar, except any R10 parameter is ignored.
21124 The exception-handling stuff that was here in 2.95 is no
21125 longer necessary. */
21129 + 32 - info->first_gp_reg_save
21130 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
21131 + 63 + 1 - info->first_fp_reg_save);
21133 strcpy (rname, ((crtl->calls_eh_return) ?
21134 "*eh_rest_world_r10" : "*rest_world"));
21135 alloc_rname = ggc_strdup (rname);
21138 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
21139 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
21140 gen_rtx_REG (Pmode,
21143 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
21144 /* The instruction pattern requires a clobber here;
21145 it is shared with the restVEC helper. */
21147 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
21150 /* CR register traditionally saved as CR2. */
21151 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
21152 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21153 GEN_INT (info->cr_save_offset));
21154 rtx mem = gen_frame_mem (reg_mode, addr);
21156 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21159 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21161 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21162 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21163 GEN_INT (info->gp_save_offset
21165 rtx mem = gen_frame_mem (reg_mode, addr);
21167 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21169 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
21171 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
21172 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21173 GEN_INT (info->altivec_save_offset
21175 rtx mem = gen_frame_mem (V4SImode, addr);
21177 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21179 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
21181 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21182 ? DFmode : SFmode),
21183 info->first_fp_reg_save + i);
21184 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21185 GEN_INT (info->fp_save_offset
21187 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21188 ? DFmode : SFmode), addr);
21190 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21193 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
21195 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
21197 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
21199 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
21201 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
21202 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
21207 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
21209 sp_offset = info->total_size;
21211 /* Restore AltiVec registers if we must do so before adjusting the
21213 if (TARGET_ALTIVEC_ABI
21214 && info->altivec_size != 0
21215 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21216 || (DEFAULT_ABI != ABI_V4
21217 && offset_below_red_zone_p (info->altivec_save_offset))))
21221 if (use_backchain_to_restore_sp)
21223 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21224 emit_move_insn (frame_reg_rtx,
21225 gen_rtx_MEM (Pmode, sp_reg_rtx));
21228 else if (frame_pointer_needed)
21229 frame_reg_rtx = hard_frame_pointer_rtx;
21231 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
21232 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
21234 rtx addr, areg, mem, reg;
21236 areg = gen_rtx_REG (Pmode, 0);
21238 (areg, GEN_INT (info->altivec_save_offset
21240 + 16 * (i - info->first_altivec_reg_save)));
21242 /* AltiVec addressing mode is [reg+reg]. */
21243 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
21244 mem = gen_frame_mem (V4SImode, addr);
21246 reg = gen_rtx_REG (V4SImode, i);
21247 emit_move_insn (reg, mem);
21248 if (offset_below_red_zone_p (info->altivec_save_offset
21249 + (i - info->first_altivec_reg_save)
21251 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21256 /* Restore VRSAVE if we must do so before adjusting the stack. */
21258 && TARGET_ALTIVEC_VRSAVE
21259 && info->vrsave_mask != 0
21260 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21261 || (DEFAULT_ABI != ABI_V4
21262 && offset_below_red_zone_p (info->vrsave_save_offset))))
21264 rtx addr, mem, reg;
21266 if (frame_reg_rtx == sp_reg_rtx)
21268 if (use_backchain_to_restore_sp)
21270 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21271 emit_move_insn (frame_reg_rtx,
21272 gen_rtx_MEM (Pmode, sp_reg_rtx));
21275 else if (frame_pointer_needed)
21276 frame_reg_rtx = hard_frame_pointer_rtx;
21279 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21280 GEN_INT (info->vrsave_save_offset + sp_offset));
21281 mem = gen_frame_mem (SImode, addr);
21282 reg = gen_rtx_REG (SImode, 12);
21283 emit_move_insn (reg, mem);
21285 emit_insn (generate_set_vrsave (reg, info, 1));
21289 /* If we have a large stack frame, restore the old stack pointer
21290 using the backchain. */
21291 if (use_backchain_to_restore_sp)
21293 if (frame_reg_rtx == sp_reg_rtx)
21295 /* Under V.4, don't reset the stack pointer until after we're done
21296 loading the saved registers. */
21297 if (DEFAULT_ABI == ABI_V4)
21298 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21300 insn = emit_move_insn (frame_reg_rtx,
21301 gen_rtx_MEM (Pmode, sp_reg_rtx));
21304 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21305 && DEFAULT_ABI == ABI_V4)
21306 /* frame_reg_rtx has been set up by the altivec restore. */
21310 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
21311 frame_reg_rtx = sp_reg_rtx;
21314 /* If we have a frame pointer, we can restore the old stack pointer
21316 else if (frame_pointer_needed)
21318 frame_reg_rtx = sp_reg_rtx;
21319 if (DEFAULT_ABI == ABI_V4)
21320 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21321 /* Prevent reordering memory accesses against stack pointer restore. */
21322 else if (cfun->calls_alloca
21323 || offset_below_red_zone_p (-info->total_size))
21325 rtx mem1 = gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx);
21326 rtx mem2 = gen_rtx_MEM (BLKmode, sp_reg_rtx);
21327 MEM_NOTRAP_P (mem1) = 1;
21328 MEM_NOTRAP_P (mem2) = 1;
21329 emit_insn (gen_frame_tie (mem1, mem2));
21332 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
21333 GEN_INT (info->total_size)));
21336 else if (info->push_p
21337 && DEFAULT_ABI != ABI_V4
21338 && !crtl->calls_eh_return)
21340 /* Prevent reordering memory accesses against stack pointer restore. */
21341 if (cfun->calls_alloca
21342 || offset_below_red_zone_p (-info->total_size))
21344 rtx mem = gen_rtx_MEM (BLKmode, sp_reg_rtx);
21345 MEM_NOTRAP_P (mem) = 1;
21346 emit_insn (gen_stack_tie (mem));
21348 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
21349 GEN_INT (info->total_size)));
21352 if (insn && frame_reg_rtx == sp_reg_rtx)
21356 REG_NOTES (insn) = cfa_restores;
21357 cfa_restores = NULL_RTX;
21359 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
21360 RTX_FRAME_RELATED_P (insn) = 1;
21363 /* Restore AltiVec registers if we have not done so already. */
21364 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21365 && TARGET_ALTIVEC_ABI
21366 && info->altivec_size != 0
21367 && (DEFAULT_ABI == ABI_V4
21368 || !offset_below_red_zone_p (info->altivec_save_offset)))
21372 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
21373 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
21375 rtx addr, areg, mem, reg;
21377 areg = gen_rtx_REG (Pmode, 0);
21379 (areg, GEN_INT (info->altivec_save_offset
21381 + 16 * (i - info->first_altivec_reg_save)));
21383 /* AltiVec addressing mode is [reg+reg]. */
21384 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
21385 mem = gen_frame_mem (V4SImode, addr);
21387 reg = gen_rtx_REG (V4SImode, i);
21388 emit_move_insn (reg, mem);
21389 if (DEFAULT_ABI == ABI_V4)
21390 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21395 /* Restore VRSAVE if we have not done so already. */
21396 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21398 && TARGET_ALTIVEC_VRSAVE
21399 && info->vrsave_mask != 0
21400 && (DEFAULT_ABI == ABI_V4
21401 || !offset_below_red_zone_p (info->vrsave_save_offset)))
21403 rtx addr, mem, reg;
21405 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21406 GEN_INT (info->vrsave_save_offset + sp_offset));
21407 mem = gen_frame_mem (SImode, addr);
21408 reg = gen_rtx_REG (SImode, 12);
21409 emit_move_insn (reg, mem);
21411 emit_insn (generate_set_vrsave (reg, info, 1));
21414 /* Get the old lr if we saved it. If we are restoring registers
21415 out-of-line, then the out-of-line routines can do this for us. */
21416 if (restore_lr && restoring_GPRs_inline)
21418 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21419 info->lr_save_offset + sp_offset);
21421 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21424 /* Get the old cr if we saved it. */
21425 if (info->cr_save_p)
21427 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21428 GEN_INT (info->cr_save_offset + sp_offset));
21429 rtx mem = gen_frame_mem (SImode, addr);
21431 cr_save_reg = gen_rtx_REG (SImode,
21432 DEFAULT_ABI == ABI_AIX
21433 && !restoring_GPRs_inline
21434 && info->first_fp_reg_save < 64
21436 emit_move_insn (cr_save_reg, mem);
21439 /* Set LR here to try to overlap restores below. LR is always saved
21440 above incoming stack, so it never needs REG_CFA_RESTORE. */
21441 if (restore_lr && restoring_GPRs_inline)
21442 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21443 gen_rtx_REG (Pmode, 0));
21445 /* Load exception handler data registers, if needed. */
21446 if (crtl->calls_eh_return)
21448 unsigned int i, regno;
21452 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21453 GEN_INT (sp_offset + 5 * reg_size));
21454 rtx mem = gen_frame_mem (reg_mode, addr);
21456 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
21463 regno = EH_RETURN_DATA_REGNO (i);
21464 if (regno == INVALID_REGNUM)
21467 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
21468 info->ehrd_offset + sp_offset
21469 + reg_size * (int) i);
21471 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
21475 /* Restore GPRs. This is done as a PARALLEL if we are using
21476 the load-multiple instructions. */
21478 && info->spe_64bit_regs_used != 0
21479 && info->first_gp_reg_save != 32)
21481 /* Determine whether we can address all of the registers that need
21482 to be saved with an offset from the stack pointer that fits in
21483 the small const field for SPE memory instructions. */
21484 int spe_regs_addressable_via_sp
21485 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
21486 + (32 - info->first_gp_reg_save - 1) * reg_size)
21487 && restoring_GPRs_inline);
21490 if (spe_regs_addressable_via_sp)
21491 spe_offset = info->spe_gp_save_offset + sp_offset;
21494 rtx old_frame_reg_rtx = frame_reg_rtx;
21495 /* Make r11 point to the start of the SPE save area. We worried about
21496 not clobbering it when we were saving registers in the prologue.
21497 There's no need to worry here because the static chain is passed
21498 anew to every function. */
21499 int ool_adjust = (restoring_GPRs_inline
21501 : (info->first_gp_reg_save
21502 - (FIRST_SAVRES_REGISTER+1))*8);
21504 if (frame_reg_rtx == sp_reg_rtx)
21505 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21506 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
21507 GEN_INT (info->spe_gp_save_offset
21510 /* Keep the invariant that frame_reg_rtx + sp_offset points
21511 at the top of the stack frame. */
21512 sp_offset = -info->spe_gp_save_offset;
21517 if (restoring_GPRs_inline)
21519 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21520 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21522 rtx offset, addr, mem, reg;
21524 /* We're doing all this to ensure that the immediate offset
21525 fits into the immediate field of 'evldd'. */
21526 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
21528 offset = GEN_INT (spe_offset + reg_size * i);
21529 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
21530 mem = gen_rtx_MEM (V2SImode, addr);
21531 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21533 insn = emit_move_insn (reg, mem);
21534 if (DEFAULT_ABI == ABI_V4)
21536 if (frame_pointer_needed
21537 && info->first_gp_reg_save + i
21538 == HARD_FRAME_POINTER_REGNUM)
21540 add_reg_note (insn, REG_CFA_DEF_CFA,
21541 plus_constant (frame_reg_rtx,
21543 RTX_FRAME_RELATED_P (insn) = 1;
21546 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21555 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
21557 /*savep=*/false, /*gpr=*/true,
21559 emit_jump_insn (par);
21560 /* We don't want anybody else emitting things after we jumped
21565 else if (!restoring_GPRs_inline)
21567 /* We are jumping to an out-of-line function. */
21568 bool can_use_exit = info->first_fp_reg_save == 64;
21571 /* Emit stack reset code if we need it. */
21573 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21574 sp_offset, can_use_exit);
21577 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
21580 GEN_INT (sp_offset - info->fp_size)));
21581 if (REGNO (frame_reg_rtx) == 11)
21582 sp_offset += info->fp_size;
21585 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
21586 info->gp_save_offset, reg_mode,
21587 /*savep=*/false, /*gpr=*/true,
21588 /*lr=*/can_use_exit);
21592 if (info->cr_save_p)
21594 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21595 if (DEFAULT_ABI == ABI_V4)
21597 = alloc_reg_note (REG_CFA_RESTORE,
21598 gen_rtx_REG (SImode, CR2_REGNO),
21602 emit_jump_insn (par);
21604 /* We don't want anybody else emitting things after we jumped
21609 insn = emit_insn (par);
21610 if (DEFAULT_ABI == ABI_V4)
21612 if (frame_pointer_needed)
21614 add_reg_note (insn, REG_CFA_DEF_CFA,
21615 plus_constant (frame_reg_rtx, sp_offset));
21616 RTX_FRAME_RELATED_P (insn) = 1;
21619 for (i = info->first_gp_reg_save; i < 32; i++)
21621 = alloc_reg_note (REG_CFA_RESTORE,
21622 gen_rtx_REG (reg_mode, i), cfa_restores);
21625 else if (using_load_multiple)
21628 p = rtvec_alloc (32 - info->first_gp_reg_save);
21629 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21631 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21632 GEN_INT (info->gp_save_offset
21635 rtx mem = gen_frame_mem (reg_mode, addr);
21636 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21638 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
21639 if (DEFAULT_ABI == ABI_V4)
21640 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21643 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
21644 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
21646 add_reg_note (insn, REG_CFA_DEF_CFA,
21647 plus_constant (frame_reg_rtx, sp_offset));
21648 RTX_FRAME_RELATED_P (insn) = 1;
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 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21657 GEN_INT (info->gp_save_offset
21660 rtx mem = gen_frame_mem (reg_mode, addr);
21661 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21663 insn = emit_move_insn (reg, mem);
21664 if (DEFAULT_ABI == ABI_V4)
21666 if (frame_pointer_needed
21667 && info->first_gp_reg_save + i
21668 == HARD_FRAME_POINTER_REGNUM)
21670 add_reg_note (insn, REG_CFA_DEF_CFA,
21671 plus_constant (frame_reg_rtx, sp_offset));
21672 RTX_FRAME_RELATED_P (insn) = 1;
21675 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21681 if (restore_lr && !restoring_GPRs_inline)
21683 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21684 info->lr_save_offset + sp_offset);
21686 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21687 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21688 gen_rtx_REG (Pmode, 0));
21691 /* Restore fpr's if we need to do it without calling a function. */
21692 if (restoring_FPRs_inline)
21693 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21694 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
21695 && ! call_used_regs[info->first_fp_reg_save+i]))
21697 rtx addr, mem, reg;
21698 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21699 GEN_INT (info->fp_save_offset
21702 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21703 ? DFmode : SFmode), addr);
21704 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21705 ? DFmode : SFmode),
21706 info->first_fp_reg_save + i);
21708 emit_move_insn (reg, mem);
21709 if (DEFAULT_ABI == ABI_V4)
21710 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21714 /* If we saved cr, restore it here. Just those that were used. */
21715 if (info->cr_save_p)
21717 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21718 if (DEFAULT_ABI == ABI_V4)
21720 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
21724 /* If this is V.4, unwind the stack pointer after all of the loads
21726 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21727 sp_offset, !restoring_FPRs_inline);
21732 REG_NOTES (insn) = cfa_restores;
21733 cfa_restores = NULL_RTX;
21735 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
21736 RTX_FRAME_RELATED_P (insn) = 1;
21739 if (crtl->calls_eh_return)
21741 rtx sa = EH_RETURN_STACKADJ_RTX;
21742 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
21748 bool lr = (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
21749 if (! restoring_FPRs_inline)
21750 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
21752 p = rtvec_alloc (2);
21754 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
21755 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
21756 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
21757 : gen_rtx_CLOBBER (VOIDmode,
21758 gen_rtx_REG (Pmode, 65)));
21760 /* If we have to restore more than two FP registers, branch to the
21761 restore function. It will return to our caller. */
21762 if (! restoring_FPRs_inline)
21767 sym = rs6000_savres_routine_sym (info,
21771 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
21772 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
21773 gen_rtx_REG (Pmode,
21774 DEFAULT_ABI == ABI_AIX
21776 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21779 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
21780 GEN_INT (info->fp_save_offset + 8*i));
21781 mem = gen_frame_mem (DFmode, addr);
21783 RTVEC_ELT (p, i+4) =
21784 gen_rtx_SET (VOIDmode,
21785 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
21790 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
21794 /* Write function epilogue. */
21797 rs6000_output_function_epilogue (FILE *file,
21798 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
21800 if (! HAVE_epilogue)
21802 rtx insn = get_last_insn ();
21803 /* If the last insn was a BARRIER, we don't have to write anything except
21804 the trace table. */
21805 if (GET_CODE (insn) == NOTE)
21806 insn = prev_nonnote_insn (insn);
21807 if (insn == 0 || GET_CODE (insn) != BARRIER)
21809 /* This is slightly ugly, but at least we don't have two
21810 copies of the epilogue-emitting code. */
21813 /* A NOTE_INSN_DELETED is supposed to be at the start
21814 and end of the "toplevel" insn chain. */
21815 emit_note (NOTE_INSN_DELETED);
21816 rs6000_emit_epilogue (FALSE);
21817 emit_note (NOTE_INSN_DELETED);
21819 /* Expand INSN_ADDRESSES so final() doesn't crash. */
21823 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
21825 INSN_ADDRESSES_NEW (insn, addr);
21830 if (TARGET_DEBUG_STACK)
21831 debug_rtx_list (get_insns (), 100);
21832 final (get_insns (), file, FALSE);
21838 macho_branch_islands ();
21839 /* Mach-O doesn't support labels at the end of objects, so if
21840 it looks like we might want one, insert a NOP. */
21842 rtx insn = get_last_insn ();
21845 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
21846 insn = PREV_INSN (insn);
21850 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
21851 fputs ("\tnop\n", file);
21855 /* Output a traceback table here. See /usr/include/sys/debug.h for info
21858 We don't output a traceback table if -finhibit-size-directive was
21859 used. The documentation for -finhibit-size-directive reads
21860 ``don't output a @code{.size} assembler directive, or anything
21861 else that would cause trouble if the function is split in the
21862 middle, and the two halves are placed at locations far apart in
21863 memory.'' The traceback table has this property, since it
21864 includes the offset from the start of the function to the
21865 traceback table itself.
21867 System V.4 Powerpc's (and the embedded ABI derived from it) use a
21868 different traceback table. */
21869 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
21870 && rs6000_traceback != traceback_none && !cfun->is_thunk)
21872 const char *fname = NULL;
21873 const char *language_string = lang_hooks.name;
21874 int fixed_parms = 0, float_parms = 0, parm_info = 0;
21876 int optional_tbtab;
21877 rs6000_stack_t *info = rs6000_stack_info ();
21879 if (rs6000_traceback == traceback_full)
21880 optional_tbtab = 1;
21881 else if (rs6000_traceback == traceback_part)
21882 optional_tbtab = 0;
21884 optional_tbtab = !optimize_size && !TARGET_ELF;
21886 if (optional_tbtab)
21888 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
21889 while (*fname == '.') /* V.4 encodes . in the name */
21892 /* Need label immediately before tbtab, so we can compute
21893 its offset from the function start. */
21894 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
21895 ASM_OUTPUT_LABEL (file, fname);
21898 /* The .tbtab pseudo-op can only be used for the first eight
21899 expressions, since it can't handle the possibly variable
21900 length fields that follow. However, if you omit the optional
21901 fields, the assembler outputs zeros for all optional fields
21902 anyways, giving each variable length field is minimum length
21903 (as defined in sys/debug.h). Thus we can not use the .tbtab
21904 pseudo-op at all. */
21906 /* An all-zero word flags the start of the tbtab, for debuggers
21907 that have to find it by searching forward from the entry
21908 point or from the current pc. */
21909 fputs ("\t.long 0\n", file);
21911 /* Tbtab format type. Use format type 0. */
21912 fputs ("\t.byte 0,", file);
21914 /* Language type. Unfortunately, there does not seem to be any
21915 official way to discover the language being compiled, so we
21916 use language_string.
21917 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
21918 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
21919 a number, so for now use 9. LTO isn't assigned a number either,
21920 so for now use 0. */
21921 if (! strcmp (language_string, "GNU C")
21922 || ! strcmp (language_string, "GNU GIMPLE"))
21924 else if (! strcmp (language_string, "GNU F77")
21925 || ! strcmp (language_string, "GNU Fortran"))
21927 else if (! strcmp (language_string, "GNU Pascal"))
21929 else if (! strcmp (language_string, "GNU Ada"))
21931 else if (! strcmp (language_string, "GNU C++")
21932 || ! strcmp (language_string, "GNU Objective-C++"))
21934 else if (! strcmp (language_string, "GNU Java"))
21936 else if (! strcmp (language_string, "GNU Objective-C"))
21939 gcc_unreachable ();
21940 fprintf (file, "%d,", i);
21942 /* 8 single bit fields: global linkage (not set for C extern linkage,
21943 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
21944 from start of procedure stored in tbtab, internal function, function
21945 has controlled storage, function has no toc, function uses fp,
21946 function logs/aborts fp operations. */
21947 /* Assume that fp operations are used if any fp reg must be saved. */
21948 fprintf (file, "%d,",
21949 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
21951 /* 6 bitfields: function is interrupt handler, name present in
21952 proc table, function calls alloca, on condition directives
21953 (controls stack walks, 3 bits), saves condition reg, saves
21955 /* The `function calls alloca' bit seems to be set whenever reg 31 is
21956 set up as a frame pointer, even when there is no alloca call. */
21957 fprintf (file, "%d,",
21958 ((optional_tbtab << 6)
21959 | ((optional_tbtab & frame_pointer_needed) << 5)
21960 | (info->cr_save_p << 1)
21961 | (info->lr_save_p)));
21963 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
21965 fprintf (file, "%d,",
21966 (info->push_p << 7) | (64 - info->first_fp_reg_save));
21968 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
21969 fprintf (file, "%d,", (32 - first_reg_to_save ()));
21971 if (optional_tbtab)
21973 /* Compute the parameter info from the function decl argument
21976 int next_parm_info_bit = 31;
21978 for (decl = DECL_ARGUMENTS (current_function_decl);
21979 decl; decl = DECL_CHAIN (decl))
21981 rtx parameter = DECL_INCOMING_RTL (decl);
21982 enum machine_mode mode = GET_MODE (parameter);
21984 if (GET_CODE (parameter) == REG)
21986 if (SCALAR_FLOAT_MODE_P (mode))
22007 gcc_unreachable ();
22010 /* If only one bit will fit, don't or in this entry. */
22011 if (next_parm_info_bit > 0)
22012 parm_info |= (bits << (next_parm_info_bit - 1));
22013 next_parm_info_bit -= 2;
22017 fixed_parms += ((GET_MODE_SIZE (mode)
22018 + (UNITS_PER_WORD - 1))
22020 next_parm_info_bit -= 1;
22026 /* Number of fixed point parameters. */
22027 /* This is actually the number of words of fixed point parameters; thus
22028 an 8 byte struct counts as 2; and thus the maximum value is 8. */
22029 fprintf (file, "%d,", fixed_parms);
22031 /* 2 bitfields: number of floating point parameters (7 bits), parameters
22033 /* This is actually the number of fp registers that hold parameters;
22034 and thus the maximum value is 13. */
22035 /* Set parameters on stack bit if parameters are not in their original
22036 registers, regardless of whether they are on the stack? Xlc
22037 seems to set the bit when not optimizing. */
22038 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
22040 if (! optional_tbtab)
22043 /* Optional fields follow. Some are variable length. */
22045 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
22046 11 double float. */
22047 /* There is an entry for each parameter in a register, in the order that
22048 they occur in the parameter list. Any intervening arguments on the
22049 stack are ignored. If the list overflows a long (max possible length
22050 34 bits) then completely leave off all elements that don't fit. */
22051 /* Only emit this long if there was at least one parameter. */
22052 if (fixed_parms || float_parms)
22053 fprintf (file, "\t.long %d\n", parm_info);
22055 /* Offset from start of code to tb table. */
22056 fputs ("\t.long ", file);
22057 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
22058 RS6000_OUTPUT_BASENAME (file, fname);
22060 rs6000_output_function_entry (file, fname);
22063 /* Interrupt handler mask. */
22064 /* Omit this long, since we never set the interrupt handler bit
22067 /* Number of CTL (controlled storage) anchors. */
22068 /* Omit this long, since the has_ctl bit is never set above. */
22070 /* Displacement into stack of each CTL anchor. */
22071 /* Omit this list of longs, because there are no CTL anchors. */
22073 /* Length of function name. */
22076 fprintf (file, "\t.short %d\n", (int) strlen (fname));
22078 /* Function name. */
22079 assemble_string (fname, strlen (fname));
22081 /* Register for alloca automatic storage; this is always reg 31.
22082 Only emit this if the alloca bit was set above. */
22083 if (frame_pointer_needed)
22084 fputs ("\t.byte 31\n", file);
22086 fputs ("\t.align 2\n", file);
22090 /* A C compound statement that outputs the assembler code for a thunk
22091 function, used to implement C++ virtual function calls with
22092 multiple inheritance. The thunk acts as a wrapper around a virtual
22093 function, adjusting the implicit object parameter before handing
22094 control off to the real function.
22096 First, emit code to add the integer DELTA to the location that
22097 contains the incoming first argument. Assume that this argument
22098 contains a pointer, and is the one used to pass the `this' pointer
22099 in C++. This is the incoming argument *before* the function
22100 prologue, e.g. `%o0' on a sparc. The addition must preserve the
22101 values of all other incoming arguments.
22103 After the addition, emit code to jump to FUNCTION, which is a
22104 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
22105 not touch the return address. Hence returning from FUNCTION will
22106 return to whoever called the current `thunk'.
22108 The effect must be as if FUNCTION had been called directly with the
22109 adjusted first argument. This macro is responsible for emitting
22110 all of the code for a thunk function; output_function_prologue()
22111 and output_function_epilogue() are not invoked.
22113 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
22114 been extracted from it.) It might possibly be useful on some
22115 targets, but probably not.
22117 If you do not define this macro, the target-independent code in the
22118 C++ frontend will generate a less efficient heavyweight thunk that
22119 calls FUNCTION instead of jumping to it. The generic approach does
22120 not support varargs. */
22123 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
22124 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
22127 rtx this_rtx, insn, funexp;
22129 reload_completed = 1;
22130 epilogue_completed = 1;
22132 /* Mark the end of the (empty) prologue. */
22133 emit_note (NOTE_INSN_PROLOGUE_END);
22135 /* Find the "this" pointer. If the function returns a structure,
22136 the structure return pointer is in r3. */
22137 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
22138 this_rtx = gen_rtx_REG (Pmode, 4);
22140 this_rtx = gen_rtx_REG (Pmode, 3);
22142 /* Apply the constant offset, if required. */
22144 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
22146 /* Apply the offset from the vtable, if required. */
22149 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
22150 rtx tmp = gen_rtx_REG (Pmode, 12);
22152 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
22153 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
22155 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
22156 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
22160 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
22162 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
22164 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
22167 /* Generate a tail call to the target function. */
22168 if (!TREE_USED (function))
22170 assemble_external (function);
22171 TREE_USED (function) = 1;
22173 funexp = XEXP (DECL_RTL (function), 0);
22174 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
22177 if (MACHOPIC_INDIRECT)
22178 funexp = machopic_indirect_call_target (funexp);
22181 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
22182 generate sibcall RTL explicitly. */
22183 insn = emit_call_insn (
22184 gen_rtx_PARALLEL (VOIDmode,
22186 gen_rtx_CALL (VOIDmode,
22187 funexp, const0_rtx),
22188 gen_rtx_USE (VOIDmode, const0_rtx),
22189 gen_rtx_USE (VOIDmode,
22190 gen_rtx_REG (SImode,
22192 gen_rtx_RETURN (VOIDmode))));
22193 SIBLING_CALL_P (insn) = 1;
22196 /* Run just enough of rest_of_compilation to get the insns emitted.
22197 There's not really enough bulk here to make other passes such as
22198 instruction scheduling worth while. Note that use_thunk calls
22199 assemble_start_function and assemble_end_function. */
22200 insn = get_insns ();
22201 insn_locators_alloc ();
22202 shorten_branches (insn);
22203 final_start_function (insn, file, 1);
22204 final (insn, file, 1);
22205 final_end_function ();
22207 reload_completed = 0;
22208 epilogue_completed = 0;
22211 /* A quick summary of the various types of 'constant-pool tables'
22214 Target Flags Name One table per
22215 AIX (none) AIX TOC object file
22216 AIX -mfull-toc AIX TOC object file
22217 AIX -mminimal-toc AIX minimal TOC translation unit
22218 SVR4/EABI (none) SVR4 SDATA object file
22219 SVR4/EABI -fpic SVR4 pic object file
22220 SVR4/EABI -fPIC SVR4 PIC translation unit
22221 SVR4/EABI -mrelocatable EABI TOC function
22222 SVR4/EABI -maix AIX TOC object file
22223 SVR4/EABI -maix -mminimal-toc
22224 AIX minimal TOC translation unit
22226 Name Reg. Set by entries contains:
22227 made by addrs? fp? sum?
22229 AIX TOC 2 crt0 as Y option option
22230 AIX minimal TOC 30 prolog gcc Y Y option
22231 SVR4 SDATA 13 crt0 gcc N Y N
22232 SVR4 pic 30 prolog ld Y not yet N
22233 SVR4 PIC 30 prolog gcc Y option option
22234 EABI TOC 30 prolog gcc Y option option
22238 /* Hash functions for the hash table. */
22241 rs6000_hash_constant (rtx k)
22243 enum rtx_code code = GET_CODE (k);
22244 enum machine_mode mode = GET_MODE (k);
22245 unsigned result = (code << 3) ^ mode;
22246 const char *format;
22249 format = GET_RTX_FORMAT (code);
22250 flen = strlen (format);
22256 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
22259 if (mode != VOIDmode)
22260 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
22272 for (; fidx < flen; fidx++)
22273 switch (format[fidx])
22278 const char *str = XSTR (k, fidx);
22279 len = strlen (str);
22280 result = result * 613 + len;
22281 for (i = 0; i < len; i++)
22282 result = result * 613 + (unsigned) str[i];
22287 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
22291 result = result * 613 + (unsigned) XINT (k, fidx);
22294 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
22295 result = result * 613 + (unsigned) XWINT (k, fidx);
22299 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
22300 result = result * 613 + (unsigned) (XWINT (k, fidx)
22307 gcc_unreachable ();
22314 toc_hash_function (const void *hash_entry)
22316 const struct toc_hash_struct *thc =
22317 (const struct toc_hash_struct *) hash_entry;
22318 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
22321 /* Compare H1 and H2 for equivalence. */
22324 toc_hash_eq (const void *h1, const void *h2)
22326 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
22327 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
22329 if (((const struct toc_hash_struct *) h1)->key_mode
22330 != ((const struct toc_hash_struct *) h2)->key_mode)
22333 return rtx_equal_p (r1, r2);
22336 /* These are the names given by the C++ front-end to vtables, and
22337 vtable-like objects. Ideally, this logic should not be here;
22338 instead, there should be some programmatic way of inquiring as
22339 to whether or not an object is a vtable. */
22341 #define VTABLE_NAME_P(NAME) \
22342 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
22343 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
22344 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
22345 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
22346 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
22348 #ifdef NO_DOLLAR_IN_LABEL
22349 /* Return a GGC-allocated character string translating dollar signs in
22350 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
22353 rs6000_xcoff_strip_dollar (const char *name)
22358 p = strchr (name, '$');
22360 if (p == 0 || p == name)
22363 len = strlen (name);
22364 strip = (char *) alloca (len + 1);
22365 strcpy (strip, name);
22366 p = strchr (strip, '$');
22370 p = strchr (p + 1, '$');
22373 return ggc_alloc_string (strip, len);
22378 rs6000_output_symbol_ref (FILE *file, rtx x)
22380 /* Currently C++ toc references to vtables can be emitted before it
22381 is decided whether the vtable is public or private. If this is
22382 the case, then the linker will eventually complain that there is
22383 a reference to an unknown section. Thus, for vtables only,
22384 we emit the TOC reference to reference the symbol and not the
22386 const char *name = XSTR (x, 0);
22388 if (VTABLE_NAME_P (name))
22390 RS6000_OUTPUT_BASENAME (file, name);
22393 assemble_name (file, name);
22396 /* Output a TOC entry. We derive the entry name from what is being
22400 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
22403 const char *name = buf;
22405 HOST_WIDE_INT offset = 0;
22407 gcc_assert (!TARGET_NO_TOC);
22409 /* When the linker won't eliminate them, don't output duplicate
22410 TOC entries (this happens on AIX if there is any kind of TOC,
22411 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
22413 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
22415 struct toc_hash_struct *h;
22418 /* Create toc_hash_table. This can't be done at TARGET_OPTION_OVERRIDE
22419 time because GGC is not initialized at that point. */
22420 if (toc_hash_table == NULL)
22421 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
22422 toc_hash_eq, NULL);
22424 h = ggc_alloc_toc_hash_struct ();
22426 h->key_mode = mode;
22427 h->labelno = labelno;
22429 found = htab_find_slot (toc_hash_table, h, INSERT);
22430 if (*found == NULL)
22432 else /* This is indeed a duplicate.
22433 Set this label equal to that label. */
22435 fputs ("\t.set ", file);
22436 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22437 fprintf (file, "%d,", labelno);
22438 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22439 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
22445 /* If we're going to put a double constant in the TOC, make sure it's
22446 aligned properly when strict alignment is on. */
22447 if (GET_CODE (x) == CONST_DOUBLE
22448 && STRICT_ALIGNMENT
22449 && GET_MODE_BITSIZE (mode) >= 64
22450 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
22451 ASM_OUTPUT_ALIGN (file, 3);
22454 (*targetm.asm_out.internal_label) (file, "LC", labelno);
22456 /* Handle FP constants specially. Note that if we have a minimal
22457 TOC, things we put here aren't actually in the TOC, so we can allow
22459 if (GET_CODE (x) == CONST_DOUBLE &&
22460 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
22462 REAL_VALUE_TYPE rv;
22465 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22466 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22467 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
22469 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
22473 if (TARGET_MINIMAL_TOC)
22474 fputs (DOUBLE_INT_ASM_OP, file);
22476 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22477 k[0] & 0xffffffff, k[1] & 0xffffffff,
22478 k[2] & 0xffffffff, k[3] & 0xffffffff);
22479 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
22480 k[0] & 0xffffffff, k[1] & 0xffffffff,
22481 k[2] & 0xffffffff, k[3] & 0xffffffff);
22486 if (TARGET_MINIMAL_TOC)
22487 fputs ("\t.long ", file);
22489 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22490 k[0] & 0xffffffff, k[1] & 0xffffffff,
22491 k[2] & 0xffffffff, k[3] & 0xffffffff);
22492 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
22493 k[0] & 0xffffffff, k[1] & 0xffffffff,
22494 k[2] & 0xffffffff, k[3] & 0xffffffff);
22498 else if (GET_CODE (x) == CONST_DOUBLE &&
22499 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
22501 REAL_VALUE_TYPE rv;
22504 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22506 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22507 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
22509 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
22513 if (TARGET_MINIMAL_TOC)
22514 fputs (DOUBLE_INT_ASM_OP, file);
22516 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22517 k[0] & 0xffffffff, k[1] & 0xffffffff);
22518 fprintf (file, "0x%lx%08lx\n",
22519 k[0] & 0xffffffff, k[1] & 0xffffffff);
22524 if (TARGET_MINIMAL_TOC)
22525 fputs ("\t.long ", file);
22527 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22528 k[0] & 0xffffffff, k[1] & 0xffffffff);
22529 fprintf (file, "0x%lx,0x%lx\n",
22530 k[0] & 0xffffffff, k[1] & 0xffffffff);
22534 else if (GET_CODE (x) == CONST_DOUBLE &&
22535 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
22537 REAL_VALUE_TYPE rv;
22540 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22541 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22542 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
22544 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
22548 if (TARGET_MINIMAL_TOC)
22549 fputs (DOUBLE_INT_ASM_OP, file);
22551 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22552 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
22557 if (TARGET_MINIMAL_TOC)
22558 fputs ("\t.long ", file);
22560 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22561 fprintf (file, "0x%lx\n", l & 0xffffffff);
22565 else if (GET_MODE (x) == VOIDmode
22566 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
22568 unsigned HOST_WIDE_INT low;
22569 HOST_WIDE_INT high;
22571 if (GET_CODE (x) == CONST_DOUBLE)
22573 low = CONST_DOUBLE_LOW (x);
22574 high = CONST_DOUBLE_HIGH (x);
22577 #if HOST_BITS_PER_WIDE_INT == 32
22580 high = (low & 0x80000000) ? ~0 : 0;
22584 low = INTVAL (x) & 0xffffffff;
22585 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
22589 /* TOC entries are always Pmode-sized, but since this
22590 is a bigendian machine then if we're putting smaller
22591 integer constants in the TOC we have to pad them.
22592 (This is still a win over putting the constants in
22593 a separate constant pool, because then we'd have
22594 to have both a TOC entry _and_ the actual constant.)
22596 For a 32-bit target, CONST_INT values are loaded and shifted
22597 entirely within `low' and can be stored in one TOC entry. */
22599 /* It would be easy to make this work, but it doesn't now. */
22600 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
22602 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
22604 #if HOST_BITS_PER_WIDE_INT == 32
22605 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
22606 POINTER_SIZE, &low, &high, 0);
22609 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
22610 high = (HOST_WIDE_INT) low >> 32;
22617 if (TARGET_MINIMAL_TOC)
22618 fputs (DOUBLE_INT_ASM_OP, file);
22620 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22621 (long) high & 0xffffffff, (long) low & 0xffffffff);
22622 fprintf (file, "0x%lx%08lx\n",
22623 (long) high & 0xffffffff, (long) low & 0xffffffff);
22628 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
22630 if (TARGET_MINIMAL_TOC)
22631 fputs ("\t.long ", file);
22633 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22634 (long) high & 0xffffffff, (long) low & 0xffffffff);
22635 fprintf (file, "0x%lx,0x%lx\n",
22636 (long) high & 0xffffffff, (long) low & 0xffffffff);
22640 if (TARGET_MINIMAL_TOC)
22641 fputs ("\t.long ", file);
22643 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
22644 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
22650 if (GET_CODE (x) == CONST)
22652 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
22653 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
22655 base = XEXP (XEXP (x, 0), 0);
22656 offset = INTVAL (XEXP (XEXP (x, 0), 1));
22659 switch (GET_CODE (base))
22662 name = XSTR (base, 0);
22666 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
22667 CODE_LABEL_NUMBER (XEXP (base, 0)));
22671 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
22675 gcc_unreachable ();
22678 if (TARGET_MINIMAL_TOC)
22679 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
22682 fputs ("\t.tc ", file);
22683 RS6000_OUTPUT_BASENAME (file, name);
22686 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
22688 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
22690 fputs ("[TC],", file);
22693 /* Currently C++ toc references to vtables can be emitted before it
22694 is decided whether the vtable is public or private. If this is
22695 the case, then the linker will eventually complain that there is
22696 a TOC reference to an unknown section. Thus, for vtables only,
22697 we emit the TOC reference to reference the symbol and not the
22699 if (VTABLE_NAME_P (name))
22701 RS6000_OUTPUT_BASENAME (file, name);
22703 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
22704 else if (offset > 0)
22705 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
22708 output_addr_const (file, x);
22712 /* Output an assembler pseudo-op to write an ASCII string of N characters
22713 starting at P to FILE.
22715 On the RS/6000, we have to do this using the .byte operation and
22716 write out special characters outside the quoted string.
22717 Also, the assembler is broken; very long strings are truncated,
22718 so we must artificially break them up early. */
22721 output_ascii (FILE *file, const char *p, int n)
22724 int i, count_string;
22725 const char *for_string = "\t.byte \"";
22726 const char *for_decimal = "\t.byte ";
22727 const char *to_close = NULL;
22730 for (i = 0; i < n; i++)
22733 if (c >= ' ' && c < 0177)
22736 fputs (for_string, file);
22739 /* Write two quotes to get one. */
22747 for_decimal = "\"\n\t.byte ";
22751 if (count_string >= 512)
22753 fputs (to_close, file);
22755 for_string = "\t.byte \"";
22756 for_decimal = "\t.byte ";
22764 fputs (for_decimal, file);
22765 fprintf (file, "%d", c);
22767 for_string = "\n\t.byte \"";
22768 for_decimal = ", ";
22774 /* Now close the string if we have written one. Then end the line. */
22776 fputs (to_close, file);
22779 /* Generate a unique section name for FILENAME for a section type
22780 represented by SECTION_DESC. Output goes into BUF.
22782 SECTION_DESC can be any string, as long as it is different for each
22783 possible section type.
22785 We name the section in the same manner as xlc. The name begins with an
22786 underscore followed by the filename (after stripping any leading directory
22787 names) with the last period replaced by the string SECTION_DESC. If
22788 FILENAME does not contain a period, SECTION_DESC is appended to the end of
22792 rs6000_gen_section_name (char **buf, const char *filename,
22793 const char *section_desc)
22795 const char *q, *after_last_slash, *last_period = 0;
22799 after_last_slash = filename;
22800 for (q = filename; *q; q++)
22803 after_last_slash = q + 1;
22804 else if (*q == '.')
22808 len = strlen (after_last_slash) + strlen (section_desc) + 2;
22809 *buf = (char *) xmalloc (len);
22814 for (q = after_last_slash; *q; q++)
22816 if (q == last_period)
22818 strcpy (p, section_desc);
22819 p += strlen (section_desc);
22823 else if (ISALNUM (*q))
22827 if (last_period == 0)
22828 strcpy (p, section_desc);
22833 /* Emit profile function. */
22836 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
22838 /* Non-standard profiling for kernels, which just saves LR then calls
22839 _mcount without worrying about arg saves. The idea is to change
22840 the function prologue as little as possible as it isn't easy to
22841 account for arg save/restore code added just for _mcount. */
22842 if (TARGET_PROFILE_KERNEL)
22845 if (DEFAULT_ABI == ABI_AIX)
22847 #ifndef NO_PROFILE_COUNTERS
22848 # define NO_PROFILE_COUNTERS 0
22850 if (NO_PROFILE_COUNTERS)
22851 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22852 LCT_NORMAL, VOIDmode, 0);
22856 const char *label_name;
22859 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
22860 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
22861 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
22863 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22864 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
22867 else if (DEFAULT_ABI == ABI_DARWIN)
22869 const char *mcount_name = RS6000_MCOUNT;
22870 int caller_addr_regno = LR_REGNO;
22872 /* Be conservative and always set this, at least for now. */
22873 crtl->uses_pic_offset_table = 1;
22876 /* For PIC code, set up a stub and collect the caller's address
22877 from r0, which is where the prologue puts it. */
22878 if (MACHOPIC_INDIRECT
22879 && crtl->uses_pic_offset_table)
22880 caller_addr_regno = 0;
22882 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
22883 LCT_NORMAL, VOIDmode, 1,
22884 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
22888 /* Write function profiler code. */
22891 output_function_profiler (FILE *file, int labelno)
22895 switch (DEFAULT_ABI)
22898 gcc_unreachable ();
22903 warning (0, "no profiling of 64-bit code for this ABI");
22906 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
22907 fprintf (file, "\tmflr %s\n", reg_names[0]);
22908 if (NO_PROFILE_COUNTERS)
22910 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22911 reg_names[0], reg_names[1]);
22913 else if (TARGET_SECURE_PLT && flag_pic)
22915 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
22916 reg_names[0], reg_names[1]);
22917 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
22918 asm_fprintf (file, "\t{cau|addis} %s,%s,",
22919 reg_names[12], reg_names[12]);
22920 assemble_name (file, buf);
22921 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
22922 assemble_name (file, buf);
22923 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
22925 else if (flag_pic == 1)
22927 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
22928 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22929 reg_names[0], reg_names[1]);
22930 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
22931 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
22932 assemble_name (file, buf);
22933 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
22935 else if (flag_pic > 1)
22937 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22938 reg_names[0], reg_names[1]);
22939 /* Now, we need to get the address of the label. */
22940 fputs ("\tbcl 20,31,1f\n\t.long ", file);
22941 assemble_name (file, buf);
22942 fputs ("-.\n1:", file);
22943 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
22944 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
22945 reg_names[0], reg_names[11]);
22946 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
22947 reg_names[0], reg_names[0], reg_names[11]);
22951 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
22952 assemble_name (file, buf);
22953 fputs ("@ha\n", file);
22954 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22955 reg_names[0], reg_names[1]);
22956 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
22957 assemble_name (file, buf);
22958 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
22961 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
22962 fprintf (file, "\tbl %s%s\n",
22963 RS6000_MCOUNT, flag_pic ? "@plt" : "");
22968 if (!TARGET_PROFILE_KERNEL)
22970 /* Don't do anything, done in output_profile_hook (). */
22974 gcc_assert (!TARGET_32BIT);
22976 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
22977 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
22979 if (cfun->static_chain_decl != NULL)
22981 asm_fprintf (file, "\tstd %s,24(%s)\n",
22982 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
22983 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
22984 asm_fprintf (file, "\tld %s,24(%s)\n",
22985 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
22988 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
22996 /* The following variable value is the last issued insn. */
22998 static rtx last_scheduled_insn;
23000 /* The following variable helps to balance issuing of load and
23001 store instructions */
23003 static int load_store_pendulum;
23005 /* Power4 load update and store update instructions are cracked into a
23006 load or store and an integer insn which are executed in the same cycle.
23007 Branches have their own dispatch slot which does not count against the
23008 GCC issue rate, but it changes the program flow so there are no other
23009 instructions to issue in this cycle. */
23012 rs6000_variable_issue_1 (rtx insn, int more)
23014 last_scheduled_insn = insn;
23015 if (GET_CODE (PATTERN (insn)) == USE
23016 || GET_CODE (PATTERN (insn)) == CLOBBER)
23018 cached_can_issue_more = more;
23019 return cached_can_issue_more;
23022 if (insn_terminates_group_p (insn, current_group))
23024 cached_can_issue_more = 0;
23025 return cached_can_issue_more;
23028 /* If no reservation, but reach here */
23029 if (recog_memoized (insn) < 0)
23032 if (rs6000_sched_groups)
23034 if (is_microcoded_insn (insn))
23035 cached_can_issue_more = 0;
23036 else if (is_cracked_insn (insn))
23037 cached_can_issue_more = more > 2 ? more - 2 : 0;
23039 cached_can_issue_more = more - 1;
23041 return cached_can_issue_more;
23044 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
23047 cached_can_issue_more = more - 1;
23048 return cached_can_issue_more;
23052 rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more)
23054 int r = rs6000_variable_issue_1 (insn, more);
23056 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r);
23060 /* Adjust the cost of a scheduling dependency. Return the new cost of
23061 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
23064 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
23066 enum attr_type attr_type;
23068 if (! recog_memoized (insn))
23071 switch (REG_NOTE_KIND (link))
23075 /* Data dependency; DEP_INSN writes a register that INSN reads
23076 some cycles later. */
23078 /* Separate a load from a narrower, dependent store. */
23079 if (rs6000_sched_groups
23080 && GET_CODE (PATTERN (insn)) == SET
23081 && GET_CODE (PATTERN (dep_insn)) == SET
23082 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
23083 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
23084 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
23085 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
23088 attr_type = get_attr_type (insn);
23093 /* Tell the first scheduling pass about the latency between
23094 a mtctr and bctr (and mtlr and br/blr). The first
23095 scheduling pass will not know about this latency since
23096 the mtctr instruction, which has the latency associated
23097 to it, will be generated by reload. */
23098 return TARGET_POWER ? 5 : 4;
23100 /* Leave some extra cycles between a compare and its
23101 dependent branch, to inhibit expensive mispredicts. */
23102 if ((rs6000_cpu_attr == CPU_PPC603
23103 || rs6000_cpu_attr == CPU_PPC604
23104 || rs6000_cpu_attr == CPU_PPC604E
23105 || rs6000_cpu_attr == CPU_PPC620
23106 || rs6000_cpu_attr == CPU_PPC630
23107 || rs6000_cpu_attr == CPU_PPC750
23108 || rs6000_cpu_attr == CPU_PPC7400
23109 || rs6000_cpu_attr == CPU_PPC7450
23110 || rs6000_cpu_attr == CPU_POWER4
23111 || rs6000_cpu_attr == CPU_POWER5
23112 || rs6000_cpu_attr == CPU_POWER7
23113 || rs6000_cpu_attr == CPU_CELL)
23114 && recog_memoized (dep_insn)
23115 && (INSN_CODE (dep_insn) >= 0))
23117 switch (get_attr_type (dep_insn))
23121 case TYPE_DELAYED_COMPARE:
23122 case TYPE_IMUL_COMPARE:
23123 case TYPE_LMUL_COMPARE:
23124 case TYPE_FPCOMPARE:
23125 case TYPE_CR_LOGICAL:
23126 case TYPE_DELAYED_CR:
23135 case TYPE_STORE_UX:
23137 case TYPE_FPSTORE_U:
23138 case TYPE_FPSTORE_UX:
23139 if ((rs6000_cpu == PROCESSOR_POWER6)
23140 && recog_memoized (dep_insn)
23141 && (INSN_CODE (dep_insn) >= 0))
23144 if (GET_CODE (PATTERN (insn)) != SET)
23145 /* If this happens, we have to extend this to schedule
23146 optimally. Return default for now. */
23149 /* Adjust the cost for the case where the value written
23150 by a fixed point operation is used as the address
23151 gen value on a store. */
23152 switch (get_attr_type (dep_insn))
23159 if (! store_data_bypass_p (dep_insn, insn))
23163 case TYPE_LOAD_EXT:
23164 case TYPE_LOAD_EXT_U:
23165 case TYPE_LOAD_EXT_UX:
23166 case TYPE_VAR_SHIFT_ROTATE:
23167 case TYPE_VAR_DELAYED_COMPARE:
23169 if (! store_data_bypass_p (dep_insn, insn))
23175 case TYPE_FAST_COMPARE:
23178 case TYPE_INSERT_WORD:
23179 case TYPE_INSERT_DWORD:
23180 case TYPE_FPLOAD_U:
23181 case TYPE_FPLOAD_UX:
23183 case TYPE_STORE_UX:
23184 case TYPE_FPSTORE_U:
23185 case TYPE_FPSTORE_UX:
23187 if (! store_data_bypass_p (dep_insn, insn))
23195 case TYPE_IMUL_COMPARE:
23196 case TYPE_LMUL_COMPARE:
23198 if (! store_data_bypass_p (dep_insn, insn))
23204 if (! store_data_bypass_p (dep_insn, insn))
23210 if (! store_data_bypass_p (dep_insn, insn))
23223 case TYPE_LOAD_EXT:
23224 case TYPE_LOAD_EXT_U:
23225 case TYPE_LOAD_EXT_UX:
23226 if ((rs6000_cpu == PROCESSOR_POWER6)
23227 && recog_memoized (dep_insn)
23228 && (INSN_CODE (dep_insn) >= 0))
23231 /* Adjust the cost for the case where the value written
23232 by a fixed point instruction is used within the address
23233 gen portion of a subsequent load(u)(x) */
23234 switch (get_attr_type (dep_insn))
23241 if (set_to_load_agen (dep_insn, insn))
23245 case TYPE_LOAD_EXT:
23246 case TYPE_LOAD_EXT_U:
23247 case TYPE_LOAD_EXT_UX:
23248 case TYPE_VAR_SHIFT_ROTATE:
23249 case TYPE_VAR_DELAYED_COMPARE:
23251 if (set_to_load_agen (dep_insn, insn))
23257 case TYPE_FAST_COMPARE:
23260 case TYPE_INSERT_WORD:
23261 case TYPE_INSERT_DWORD:
23262 case TYPE_FPLOAD_U:
23263 case TYPE_FPLOAD_UX:
23265 case TYPE_STORE_UX:
23266 case TYPE_FPSTORE_U:
23267 case TYPE_FPSTORE_UX:
23269 if (set_to_load_agen (dep_insn, insn))
23277 case TYPE_IMUL_COMPARE:
23278 case TYPE_LMUL_COMPARE:
23280 if (set_to_load_agen (dep_insn, insn))
23286 if (set_to_load_agen (dep_insn, insn))
23292 if (set_to_load_agen (dep_insn, insn))
23303 if ((rs6000_cpu == PROCESSOR_POWER6)
23304 && recog_memoized (dep_insn)
23305 && (INSN_CODE (dep_insn) >= 0)
23306 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
23313 /* Fall out to return default cost. */
23317 case REG_DEP_OUTPUT:
23318 /* Output dependency; DEP_INSN writes a register that INSN writes some
23320 if ((rs6000_cpu == PROCESSOR_POWER6)
23321 && recog_memoized (dep_insn)
23322 && (INSN_CODE (dep_insn) >= 0))
23324 attr_type = get_attr_type (insn);
23329 if (get_attr_type (dep_insn) == TYPE_FP)
23333 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
23341 /* Anti dependency; DEP_INSN reads a register that INSN writes some
23346 gcc_unreachable ();
23352 /* Debug version of rs6000_adjust_cost. */
23355 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
23357 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
23363 switch (REG_NOTE_KIND (link))
23365 default: dep = "unknown depencency"; break;
23366 case REG_DEP_TRUE: dep = "data dependency"; break;
23367 case REG_DEP_OUTPUT: dep = "output dependency"; break;
23368 case REG_DEP_ANTI: dep = "anti depencency"; break;
23372 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
23373 "%s, insn:\n", ret, cost, dep);
23381 /* The function returns a true if INSN is microcoded.
23382 Return false otherwise. */
23385 is_microcoded_insn (rtx insn)
23387 if (!insn || !NONDEBUG_INSN_P (insn)
23388 || GET_CODE (PATTERN (insn)) == USE
23389 || GET_CODE (PATTERN (insn)) == CLOBBER)
23392 if (rs6000_cpu_attr == CPU_CELL)
23393 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
23395 if (rs6000_sched_groups)
23397 enum attr_type type = get_attr_type (insn);
23398 if (type == TYPE_LOAD_EXT_U
23399 || type == TYPE_LOAD_EXT_UX
23400 || type == TYPE_LOAD_UX
23401 || type == TYPE_STORE_UX
23402 || type == TYPE_MFCR)
23409 /* The function returns true if INSN is cracked into 2 instructions
23410 by the processor (and therefore occupies 2 issue slots). */
23413 is_cracked_insn (rtx insn)
23415 if (!insn || !NONDEBUG_INSN_P (insn)
23416 || GET_CODE (PATTERN (insn)) == USE
23417 || GET_CODE (PATTERN (insn)) == CLOBBER)
23420 if (rs6000_sched_groups)
23422 enum attr_type type = get_attr_type (insn);
23423 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
23424 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
23425 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
23426 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
23427 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
23428 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
23429 || type == TYPE_IDIV || type == TYPE_LDIV
23430 || type == TYPE_INSERT_WORD)
23437 /* The function returns true if INSN can be issued only from
23438 the branch slot. */
23441 is_branch_slot_insn (rtx insn)
23443 if (!insn || !NONDEBUG_INSN_P (insn)
23444 || GET_CODE (PATTERN (insn)) == USE
23445 || GET_CODE (PATTERN (insn)) == CLOBBER)
23448 if (rs6000_sched_groups)
23450 enum attr_type type = get_attr_type (insn);
23451 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
23459 /* The function returns true if out_inst sets a value that is
23460 used in the address generation computation of in_insn */
23462 set_to_load_agen (rtx out_insn, rtx in_insn)
23464 rtx out_set, in_set;
23466 /* For performance reasons, only handle the simple case where
23467 both loads are a single_set. */
23468 out_set = single_set (out_insn);
23471 in_set = single_set (in_insn);
23473 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
23479 /* The function returns true if the target storage location of
23480 out_insn is adjacent to the target storage location of in_insn */
23481 /* Return 1 if memory locations are adjacent. */
23484 adjacent_mem_locations (rtx insn1, rtx insn2)
23487 rtx a = get_store_dest (PATTERN (insn1));
23488 rtx b = get_store_dest (PATTERN (insn2));
23490 if ((GET_CODE (XEXP (a, 0)) == REG
23491 || (GET_CODE (XEXP (a, 0)) == PLUS
23492 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
23493 && (GET_CODE (XEXP (b, 0)) == REG
23494 || (GET_CODE (XEXP (b, 0)) == PLUS
23495 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
23497 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
23500 if (GET_CODE (XEXP (a, 0)) == PLUS)
23502 reg0 = XEXP (XEXP (a, 0), 0);
23503 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
23506 reg0 = XEXP (a, 0);
23508 if (GET_CODE (XEXP (b, 0)) == PLUS)
23510 reg1 = XEXP (XEXP (b, 0), 0);
23511 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
23514 reg1 = XEXP (b, 0);
23516 val_diff = val1 - val0;
23518 return ((REGNO (reg0) == REGNO (reg1))
23519 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
23520 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
23526 /* A C statement (sans semicolon) to update the integer scheduling
23527 priority INSN_PRIORITY (INSN). Increase the priority to execute the
23528 INSN earlier, reduce the priority to execute INSN later. Do not
23529 define this macro if you do not need to adjust the scheduling
23530 priorities of insns. */
23533 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
23535 /* On machines (like the 750) which have asymmetric integer units,
23536 where one integer unit can do multiply and divides and the other
23537 can't, reduce the priority of multiply/divide so it is scheduled
23538 before other integer operations. */
23541 if (! INSN_P (insn))
23544 if (GET_CODE (PATTERN (insn)) == USE)
23547 switch (rs6000_cpu_attr) {
23549 switch (get_attr_type (insn))
23556 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
23557 priority, priority);
23558 if (priority >= 0 && priority < 0x01000000)
23565 if (insn_must_be_first_in_group (insn)
23566 && reload_completed
23567 && current_sched_info->sched_max_insns_priority
23568 && rs6000_sched_restricted_insns_priority)
23571 /* Prioritize insns that can be dispatched only in the first
23573 if (rs6000_sched_restricted_insns_priority == 1)
23574 /* Attach highest priority to insn. This means that in
23575 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
23576 precede 'priority' (critical path) considerations. */
23577 return current_sched_info->sched_max_insns_priority;
23578 else if (rs6000_sched_restricted_insns_priority == 2)
23579 /* Increase priority of insn by a minimal amount. This means that in
23580 haifa-sched.c:ready_sort(), only 'priority' (critical path)
23581 considerations precede dispatch-slot restriction considerations. */
23582 return (priority + 1);
23585 if (rs6000_cpu == PROCESSOR_POWER6
23586 && ((load_store_pendulum == -2 && is_load_insn (insn))
23587 || (load_store_pendulum == 2 && is_store_insn (insn))))
23588 /* Attach highest priority to insn if the scheduler has just issued two
23589 stores and this instruction is a load, or two loads and this instruction
23590 is a store. Power6 wants loads and stores scheduled alternately
23592 return current_sched_info->sched_max_insns_priority;
23597 /* Return true if the instruction is nonpipelined on the Cell. */
23599 is_nonpipeline_insn (rtx insn)
23601 enum attr_type type;
23602 if (!insn || !NONDEBUG_INSN_P (insn)
23603 || GET_CODE (PATTERN (insn)) == USE
23604 || GET_CODE (PATTERN (insn)) == CLOBBER)
23607 type = get_attr_type (insn);
23608 if (type == TYPE_IMUL
23609 || type == TYPE_IMUL2
23610 || type == TYPE_IMUL3
23611 || type == TYPE_LMUL
23612 || type == TYPE_IDIV
23613 || type == TYPE_LDIV
23614 || type == TYPE_SDIV
23615 || type == TYPE_DDIV
23616 || type == TYPE_SSQRT
23617 || type == TYPE_DSQRT
23618 || type == TYPE_MFCR
23619 || type == TYPE_MFCRF
23620 || type == TYPE_MFJMPR)
23628 /* Return how many instructions the machine can issue per cycle. */
23631 rs6000_issue_rate (void)
23633 /* Unless scheduling for register pressure, use issue rate of 1 for
23634 first scheduling pass to decrease degradation. */
23635 if (!reload_completed && !flag_sched_pressure)
23638 switch (rs6000_cpu_attr) {
23639 case CPU_RIOS1: /* ? */
23641 case CPU_PPC601: /* ? */
23650 case CPU_PPCE300C2:
23651 case CPU_PPCE300C3:
23652 case CPU_PPCE500MC:
23653 case CPU_PPCE500MC64:
23673 /* Return how many instructions to look ahead for better insn
23677 rs6000_use_sched_lookahead (void)
23679 if (rs6000_cpu_attr == CPU_PPC8540)
23681 if (rs6000_cpu_attr == CPU_CELL)
23682 return (reload_completed ? 8 : 0);
23686 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
23688 rs6000_use_sched_lookahead_guard (rtx insn)
23690 if (rs6000_cpu_attr != CPU_CELL)
23693 if (insn == NULL_RTX || !INSN_P (insn))
23696 if (!reload_completed
23697 || is_nonpipeline_insn (insn)
23698 || is_microcoded_insn (insn))
23704 /* Determine is PAT refers to memory. */
23707 is_mem_ref (rtx pat)
23713 /* stack_tie does not produce any real memory traffic. */
23714 if (GET_CODE (pat) == UNSPEC
23715 && XINT (pat, 1) == UNSPEC_TIE)
23718 if (GET_CODE (pat) == MEM)
23721 /* Recursively process the pattern. */
23722 fmt = GET_RTX_FORMAT (GET_CODE (pat));
23724 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
23727 ret |= is_mem_ref (XEXP (pat, i));
23728 else if (fmt[i] == 'E')
23729 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
23730 ret |= is_mem_ref (XVECEXP (pat, i, j));
23736 /* Determine if PAT is a PATTERN of a load insn. */
23739 is_load_insn1 (rtx pat)
23741 if (!pat || pat == NULL_RTX)
23744 if (GET_CODE (pat) == SET)
23745 return is_mem_ref (SET_SRC (pat));
23747 if (GET_CODE (pat) == PARALLEL)
23751 for (i = 0; i < XVECLEN (pat, 0); i++)
23752 if (is_load_insn1 (XVECEXP (pat, 0, i)))
23759 /* Determine if INSN loads from memory. */
23762 is_load_insn (rtx insn)
23764 if (!insn || !INSN_P (insn))
23767 if (GET_CODE (insn) == CALL_INSN)
23770 return is_load_insn1 (PATTERN (insn));
23773 /* Determine if PAT is a PATTERN of a store insn. */
23776 is_store_insn1 (rtx pat)
23778 if (!pat || pat == NULL_RTX)
23781 if (GET_CODE (pat) == SET)
23782 return is_mem_ref (SET_DEST (pat));
23784 if (GET_CODE (pat) == PARALLEL)
23788 for (i = 0; i < XVECLEN (pat, 0); i++)
23789 if (is_store_insn1 (XVECEXP (pat, 0, i)))
23796 /* Determine if INSN stores to memory. */
23799 is_store_insn (rtx insn)
23801 if (!insn || !INSN_P (insn))
23804 return is_store_insn1 (PATTERN (insn));
23807 /* Return the dest of a store insn. */
23810 get_store_dest (rtx pat)
23812 gcc_assert (is_store_insn1 (pat));
23814 if (GET_CODE (pat) == SET)
23815 return SET_DEST (pat);
23816 else if (GET_CODE (pat) == PARALLEL)
23820 for (i = 0; i < XVECLEN (pat, 0); i++)
23822 rtx inner_pat = XVECEXP (pat, 0, i);
23823 if (GET_CODE (inner_pat) == SET
23824 && is_mem_ref (SET_DEST (inner_pat)))
23828 /* We shouldn't get here, because we should have either a simple
23829 store insn or a store with update which are covered above. */
23833 /* Returns whether the dependence between INSN and NEXT is considered
23834 costly by the given target. */
23837 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
23842 /* If the flag is not enabled - no dependence is considered costly;
23843 allow all dependent insns in the same group.
23844 This is the most aggressive option. */
23845 if (rs6000_sched_costly_dep == no_dep_costly)
23848 /* If the flag is set to 1 - a dependence is always considered costly;
23849 do not allow dependent instructions in the same group.
23850 This is the most conservative option. */
23851 if (rs6000_sched_costly_dep == all_deps_costly)
23854 insn = DEP_PRO (dep);
23855 next = DEP_CON (dep);
23857 if (rs6000_sched_costly_dep == store_to_load_dep_costly
23858 && is_load_insn (next)
23859 && is_store_insn (insn))
23860 /* Prevent load after store in the same group. */
23863 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
23864 && is_load_insn (next)
23865 && is_store_insn (insn)
23866 && DEP_TYPE (dep) == REG_DEP_TRUE)
23867 /* Prevent load after store in the same group if it is a true
23871 /* The flag is set to X; dependences with latency >= X are considered costly,
23872 and will not be scheduled in the same group. */
23873 if (rs6000_sched_costly_dep <= max_dep_latency
23874 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
23880 /* Return the next insn after INSN that is found before TAIL is reached,
23881 skipping any "non-active" insns - insns that will not actually occupy
23882 an issue slot. Return NULL_RTX if such an insn is not found. */
23885 get_next_active_insn (rtx insn, rtx tail)
23887 if (insn == NULL_RTX || insn == tail)
23892 insn = NEXT_INSN (insn);
23893 if (insn == NULL_RTX || insn == tail)
23898 || (NONJUMP_INSN_P (insn)
23899 && GET_CODE (PATTERN (insn)) != USE
23900 && GET_CODE (PATTERN (insn)) != CLOBBER
23901 && INSN_CODE (insn) != CODE_FOR_stack_tie))
23907 /* We are about to begin issuing insns for this clock cycle. */
23910 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
23911 rtx *ready ATTRIBUTE_UNUSED,
23912 int *pn_ready ATTRIBUTE_UNUSED,
23913 int clock_var ATTRIBUTE_UNUSED)
23915 int n_ready = *pn_ready;
23918 fprintf (dump, "// rs6000_sched_reorder :\n");
23920 /* Reorder the ready list, if the second to last ready insn
23921 is a nonepipeline insn. */
23922 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
23924 if (is_nonpipeline_insn (ready[n_ready - 1])
23925 && (recog_memoized (ready[n_ready - 2]) > 0))
23926 /* Simply swap first two insns. */
23928 rtx tmp = ready[n_ready - 1];
23929 ready[n_ready - 1] = ready[n_ready - 2];
23930 ready[n_ready - 2] = tmp;
23934 if (rs6000_cpu == PROCESSOR_POWER6)
23935 load_store_pendulum = 0;
23937 return rs6000_issue_rate ();
23940 /* Like rs6000_sched_reorder, but called after issuing each insn. */
23943 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
23944 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
23947 fprintf (dump, "// rs6000_sched_reorder2 :\n");
23949 /* For Power6, we need to handle some special cases to try and keep the
23950 store queue from overflowing and triggering expensive flushes.
23952 This code monitors how load and store instructions are being issued
23953 and skews the ready list one way or the other to increase the likelihood
23954 that a desired instruction is issued at the proper time.
23956 A couple of things are done. First, we maintain a "load_store_pendulum"
23957 to track the current state of load/store issue.
23959 - If the pendulum is at zero, then no loads or stores have been
23960 issued in the current cycle so we do nothing.
23962 - If the pendulum is 1, then a single load has been issued in this
23963 cycle and we attempt to locate another load in the ready list to
23966 - If the pendulum is -2, then two stores have already been
23967 issued in this cycle, so we increase the priority of the first load
23968 in the ready list to increase it's likelihood of being chosen first
23971 - If the pendulum is -1, then a single store has been issued in this
23972 cycle and we attempt to locate another store in the ready list to
23973 issue with it, preferring a store to an adjacent memory location to
23974 facilitate store pairing in the store queue.
23976 - If the pendulum is 2, then two loads have already been
23977 issued in this cycle, so we increase the priority of the first store
23978 in the ready list to increase it's likelihood of being chosen first
23981 - If the pendulum < -2 or > 2, then do nothing.
23983 Note: This code covers the most common scenarios. There exist non
23984 load/store instructions which make use of the LSU and which
23985 would need to be accounted for to strictly model the behavior
23986 of the machine. Those instructions are currently unaccounted
23987 for to help minimize compile time overhead of this code.
23989 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
23995 if (is_store_insn (last_scheduled_insn))
23996 /* Issuing a store, swing the load_store_pendulum to the left */
23997 load_store_pendulum--;
23998 else if (is_load_insn (last_scheduled_insn))
23999 /* Issuing a load, swing the load_store_pendulum to the right */
24000 load_store_pendulum++;
24002 return cached_can_issue_more;
24004 /* If the pendulum is balanced, or there is only one instruction on
24005 the ready list, then all is well, so return. */
24006 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
24007 return cached_can_issue_more;
24009 if (load_store_pendulum == 1)
24011 /* A load has been issued in this cycle. Scan the ready list
24012 for another load to issue with it */
24017 if (is_load_insn (ready[pos]))
24019 /* Found a load. Move it to the head of the ready list,
24020 and adjust it's priority so that it is more likely to
24023 for (i=pos; i<*pn_ready-1; i++)
24024 ready[i] = ready[i + 1];
24025 ready[*pn_ready-1] = tmp;
24027 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
24028 INSN_PRIORITY (tmp)++;
24034 else if (load_store_pendulum == -2)
24036 /* Two stores have been issued in this cycle. Increase the
24037 priority of the first load in the ready list to favor it for
24038 issuing in the next cycle. */
24043 if (is_load_insn (ready[pos])
24045 && INSN_PRIORITY_KNOWN (ready[pos]))
24047 INSN_PRIORITY (ready[pos])++;
24049 /* Adjust the pendulum to account for the fact that a load
24050 was found and increased in priority. This is to prevent
24051 increasing the priority of multiple loads */
24052 load_store_pendulum--;
24059 else if (load_store_pendulum == -1)
24061 /* A store has been issued in this cycle. Scan the ready list for
24062 another store to issue with it, preferring a store to an adjacent
24064 int first_store_pos = -1;
24070 if (is_store_insn (ready[pos]))
24072 /* Maintain the index of the first store found on the
24074 if (first_store_pos == -1)
24075 first_store_pos = pos;
24077 if (is_store_insn (last_scheduled_insn)
24078 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
24080 /* Found an adjacent store. Move it to the head of the
24081 ready list, and adjust it's priority so that it is
24082 more likely to stay there */
24084 for (i=pos; i<*pn_ready-1; i++)
24085 ready[i] = ready[i + 1];
24086 ready[*pn_ready-1] = tmp;
24088 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
24089 INSN_PRIORITY (tmp)++;
24091 first_store_pos = -1;
24099 if (first_store_pos >= 0)
24101 /* An adjacent store wasn't found, but a non-adjacent store was,
24102 so move the non-adjacent store to the front of the ready
24103 list, and adjust its priority so that it is more likely to
24105 tmp = ready[first_store_pos];
24106 for (i=first_store_pos; i<*pn_ready-1; i++)
24107 ready[i] = ready[i + 1];
24108 ready[*pn_ready-1] = tmp;
24109 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
24110 INSN_PRIORITY (tmp)++;
24113 else if (load_store_pendulum == 2)
24115 /* Two loads have been issued in this cycle. Increase the priority
24116 of the first store in the ready list to favor it for issuing in
24122 if (is_store_insn (ready[pos])
24124 && INSN_PRIORITY_KNOWN (ready[pos]))
24126 INSN_PRIORITY (ready[pos])++;
24128 /* Adjust the pendulum to account for the fact that a store
24129 was found and increased in priority. This is to prevent
24130 increasing the priority of multiple stores */
24131 load_store_pendulum++;
24140 return cached_can_issue_more;
24143 /* Return whether the presence of INSN causes a dispatch group termination
24144 of group WHICH_GROUP.
24146 If WHICH_GROUP == current_group, this function will return true if INSN
24147 causes the termination of the current group (i.e, the dispatch group to
24148 which INSN belongs). This means that INSN will be the last insn in the
24149 group it belongs to.
24151 If WHICH_GROUP == previous_group, this function will return true if INSN
24152 causes the termination of the previous group (i.e, the dispatch group that
24153 precedes the group to which INSN belongs). This means that INSN will be
24154 the first insn in the group it belongs to). */
24157 insn_terminates_group_p (rtx insn, enum group_termination which_group)
24164 first = insn_must_be_first_in_group (insn);
24165 last = insn_must_be_last_in_group (insn);
24170 if (which_group == current_group)
24172 else if (which_group == previous_group)
24180 insn_must_be_first_in_group (rtx insn)
24182 enum attr_type type;
24185 || GET_CODE (insn) == NOTE
24186 || DEBUG_INSN_P (insn)
24187 || GET_CODE (PATTERN (insn)) == USE
24188 || GET_CODE (PATTERN (insn)) == CLOBBER)
24191 switch (rs6000_cpu)
24193 case PROCESSOR_POWER5:
24194 if (is_cracked_insn (insn))
24196 case PROCESSOR_POWER4:
24197 if (is_microcoded_insn (insn))
24200 if (!rs6000_sched_groups)
24203 type = get_attr_type (insn);
24210 case TYPE_DELAYED_CR:
24211 case TYPE_CR_LOGICAL:
24225 case PROCESSOR_POWER6:
24226 type = get_attr_type (insn);
24230 case TYPE_INSERT_DWORD:
24234 case TYPE_VAR_SHIFT_ROTATE:
24241 case TYPE_INSERT_WORD:
24242 case TYPE_DELAYED_COMPARE:
24243 case TYPE_IMUL_COMPARE:
24244 case TYPE_LMUL_COMPARE:
24245 case TYPE_FPCOMPARE:
24256 case TYPE_LOAD_EXT_UX:
24258 case TYPE_STORE_UX:
24259 case TYPE_FPLOAD_U:
24260 case TYPE_FPLOAD_UX:
24261 case TYPE_FPSTORE_U:
24262 case TYPE_FPSTORE_UX:
24268 case PROCESSOR_POWER7:
24269 type = get_attr_type (insn);
24273 case TYPE_CR_LOGICAL:
24280 case TYPE_DELAYED_COMPARE:
24281 case TYPE_VAR_DELAYED_COMPARE:
24287 case TYPE_LOAD_EXT:
24288 case TYPE_LOAD_EXT_U:
24289 case TYPE_LOAD_EXT_UX:
24291 case TYPE_STORE_UX:
24292 case TYPE_FPLOAD_U:
24293 case TYPE_FPLOAD_UX:
24294 case TYPE_FPSTORE_U:
24295 case TYPE_FPSTORE_UX:
24311 insn_must_be_last_in_group (rtx insn)
24313 enum attr_type type;
24316 || GET_CODE (insn) == NOTE
24317 || DEBUG_INSN_P (insn)
24318 || GET_CODE (PATTERN (insn)) == USE
24319 || GET_CODE (PATTERN (insn)) == CLOBBER)
24322 switch (rs6000_cpu) {
24323 case PROCESSOR_POWER4:
24324 case PROCESSOR_POWER5:
24325 if (is_microcoded_insn (insn))
24328 if (is_branch_slot_insn (insn))
24332 case PROCESSOR_POWER6:
24333 type = get_attr_type (insn);
24340 case TYPE_VAR_SHIFT_ROTATE:
24347 case TYPE_DELAYED_COMPARE:
24348 case TYPE_IMUL_COMPARE:
24349 case TYPE_LMUL_COMPARE:
24350 case TYPE_FPCOMPARE:
24364 case PROCESSOR_POWER7:
24365 type = get_attr_type (insn);
24373 case TYPE_LOAD_EXT_U:
24374 case TYPE_LOAD_EXT_UX:
24375 case TYPE_STORE_UX:
24388 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
24389 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
24392 is_costly_group (rtx *group_insns, rtx next_insn)
24395 int issue_rate = rs6000_issue_rate ();
24397 for (i = 0; i < issue_rate; i++)
24399 sd_iterator_def sd_it;
24401 rtx insn = group_insns[i];
24406 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
24408 rtx next = DEP_CON (dep);
24410 if (next == next_insn
24411 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
24419 /* Utility of the function redefine_groups.
24420 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
24421 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
24422 to keep it "far" (in a separate group) from GROUP_INSNS, following
24423 one of the following schemes, depending on the value of the flag
24424 -minsert_sched_nops = X:
24425 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
24426 in order to force NEXT_INSN into a separate group.
24427 (2) X < sched_finish_regroup_exact: insert exactly X nops.
24428 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
24429 insertion (has a group just ended, how many vacant issue slots remain in the
24430 last group, and how many dispatch groups were encountered so far). */
24433 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
24434 rtx next_insn, bool *group_end, int can_issue_more,
24439 int issue_rate = rs6000_issue_rate ();
24440 bool end = *group_end;
24443 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
24444 return can_issue_more;
24446 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
24447 return can_issue_more;
24449 force = is_costly_group (group_insns, next_insn);
24451 return can_issue_more;
24453 if (sched_verbose > 6)
24454 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
24455 *group_count ,can_issue_more);
24457 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
24460 can_issue_more = 0;
24462 /* Since only a branch can be issued in the last issue_slot, it is
24463 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
24464 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
24465 in this case the last nop will start a new group and the branch
24466 will be forced to the new group. */
24467 if (can_issue_more && !is_branch_slot_insn (next_insn))
24470 while (can_issue_more > 0)
24473 emit_insn_before (nop, next_insn);
24481 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
24483 int n_nops = rs6000_sched_insert_nops;
24485 /* Nops can't be issued from the branch slot, so the effective
24486 issue_rate for nops is 'issue_rate - 1'. */
24487 if (can_issue_more == 0)
24488 can_issue_more = issue_rate;
24490 if (can_issue_more == 0)
24492 can_issue_more = issue_rate - 1;
24495 for (i = 0; i < issue_rate; i++)
24497 group_insns[i] = 0;
24504 emit_insn_before (nop, next_insn);
24505 if (can_issue_more == issue_rate - 1) /* new group begins */
24508 if (can_issue_more == 0)
24510 can_issue_more = issue_rate - 1;
24513 for (i = 0; i < issue_rate; i++)
24515 group_insns[i] = 0;
24521 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
24524 /* Is next_insn going to start a new group? */
24527 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24528 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24529 || (can_issue_more < issue_rate &&
24530 insn_terminates_group_p (next_insn, previous_group)));
24531 if (*group_end && end)
24534 if (sched_verbose > 6)
24535 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
24536 *group_count, can_issue_more);
24537 return can_issue_more;
24540 return can_issue_more;
24543 /* This function tries to synch the dispatch groups that the compiler "sees"
24544 with the dispatch groups that the processor dispatcher is expected to
24545 form in practice. It tries to achieve this synchronization by forcing the
24546 estimated processor grouping on the compiler (as opposed to the function
24547 'pad_goups' which tries to force the scheduler's grouping on the processor).
24549 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
24550 examines the (estimated) dispatch groups that will be formed by the processor
24551 dispatcher. It marks these group boundaries to reflect the estimated
24552 processor grouping, overriding the grouping that the scheduler had marked.
24553 Depending on the value of the flag '-minsert-sched-nops' this function can
24554 force certain insns into separate groups or force a certain distance between
24555 them by inserting nops, for example, if there exists a "costly dependence"
24558 The function estimates the group boundaries that the processor will form as
24559 follows: It keeps track of how many vacant issue slots are available after
24560 each insn. A subsequent insn will start a new group if one of the following
24562 - no more vacant issue slots remain in the current dispatch group.
24563 - only the last issue slot, which is the branch slot, is vacant, but the next
24564 insn is not a branch.
24565 - only the last 2 or less issue slots, including the branch slot, are vacant,
24566 which means that a cracked insn (which occupies two issue slots) can't be
24567 issued in this group.
24568 - less than 'issue_rate' slots are vacant, and the next insn always needs to
24569 start a new group. */
24572 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24574 rtx insn, next_insn;
24576 int can_issue_more;
24579 int group_count = 0;
24583 issue_rate = rs6000_issue_rate ();
24584 group_insns = XALLOCAVEC (rtx, issue_rate);
24585 for (i = 0; i < issue_rate; i++)
24587 group_insns[i] = 0;
24589 can_issue_more = issue_rate;
24591 insn = get_next_active_insn (prev_head_insn, tail);
24594 while (insn != NULL_RTX)
24596 slot = (issue_rate - can_issue_more);
24597 group_insns[slot] = insn;
24599 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24600 if (insn_terminates_group_p (insn, current_group))
24601 can_issue_more = 0;
24603 next_insn = get_next_active_insn (insn, tail);
24604 if (next_insn == NULL_RTX)
24605 return group_count + 1;
24607 /* Is next_insn going to start a new group? */
24609 = (can_issue_more == 0
24610 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24611 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24612 || (can_issue_more < issue_rate &&
24613 insn_terminates_group_p (next_insn, previous_group)));
24615 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
24616 next_insn, &group_end, can_issue_more,
24622 can_issue_more = 0;
24623 for (i = 0; i < issue_rate; i++)
24625 group_insns[i] = 0;
24629 if (GET_MODE (next_insn) == TImode && can_issue_more)
24630 PUT_MODE (next_insn, VOIDmode);
24631 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
24632 PUT_MODE (next_insn, TImode);
24635 if (can_issue_more == 0)
24636 can_issue_more = issue_rate;
24639 return group_count;
24642 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
24643 dispatch group boundaries that the scheduler had marked. Pad with nops
24644 any dispatch groups which have vacant issue slots, in order to force the
24645 scheduler's grouping on the processor dispatcher. The function
24646 returns the number of dispatch groups found. */
24649 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24651 rtx insn, next_insn;
24654 int can_issue_more;
24656 int group_count = 0;
24658 /* Initialize issue_rate. */
24659 issue_rate = rs6000_issue_rate ();
24660 can_issue_more = issue_rate;
24662 insn = get_next_active_insn (prev_head_insn, tail);
24663 next_insn = get_next_active_insn (insn, tail);
24665 while (insn != NULL_RTX)
24668 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24670 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
24672 if (next_insn == NULL_RTX)
24677 /* If the scheduler had marked group termination at this location
24678 (between insn and next_insn), and neither insn nor next_insn will
24679 force group termination, pad the group with nops to force group
24682 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
24683 && !insn_terminates_group_p (insn, current_group)
24684 && !insn_terminates_group_p (next_insn, previous_group))
24686 if (!is_branch_slot_insn (next_insn))
24689 while (can_issue_more)
24692 emit_insn_before (nop, next_insn);
24697 can_issue_more = issue_rate;
24702 next_insn = get_next_active_insn (insn, tail);
24705 return group_count;
24708 /* We're beginning a new block. Initialize data structures as necessary. */
24711 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
24712 int sched_verbose ATTRIBUTE_UNUSED,
24713 int max_ready ATTRIBUTE_UNUSED)
24715 last_scheduled_insn = NULL_RTX;
24716 load_store_pendulum = 0;
24719 /* The following function is called at the end of scheduling BB.
24720 After reload, it inserts nops at insn group bundling. */
24723 rs6000_sched_finish (FILE *dump, int sched_verbose)
24728 fprintf (dump, "=== Finishing schedule.\n");
24730 if (reload_completed && rs6000_sched_groups)
24732 /* Do not run sched_finish hook when selective scheduling enabled. */
24733 if (sel_sched_p ())
24736 if (rs6000_sched_insert_nops == sched_finish_none)
24739 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
24740 n_groups = pad_groups (dump, sched_verbose,
24741 current_sched_info->prev_head,
24742 current_sched_info->next_tail);
24744 n_groups = redefine_groups (dump, sched_verbose,
24745 current_sched_info->prev_head,
24746 current_sched_info->next_tail);
24748 if (sched_verbose >= 6)
24750 fprintf (dump, "ngroups = %d\n", n_groups);
24751 print_rtl (dump, current_sched_info->prev_head);
24752 fprintf (dump, "Done finish_sched\n");
24757 struct _rs6000_sched_context
24759 short cached_can_issue_more;
24760 rtx last_scheduled_insn;
24761 int load_store_pendulum;
24764 typedef struct _rs6000_sched_context rs6000_sched_context_def;
24765 typedef rs6000_sched_context_def *rs6000_sched_context_t;
24767 /* Allocate store for new scheduling context. */
24769 rs6000_alloc_sched_context (void)
24771 return xmalloc (sizeof (rs6000_sched_context_def));
24774 /* If CLEAN_P is true then initializes _SC with clean data,
24775 and from the global context otherwise. */
24777 rs6000_init_sched_context (void *_sc, bool clean_p)
24779 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24783 sc->cached_can_issue_more = 0;
24784 sc->last_scheduled_insn = NULL_RTX;
24785 sc->load_store_pendulum = 0;
24789 sc->cached_can_issue_more = cached_can_issue_more;
24790 sc->last_scheduled_insn = last_scheduled_insn;
24791 sc->load_store_pendulum = load_store_pendulum;
24795 /* Sets the global scheduling context to the one pointed to by _SC. */
24797 rs6000_set_sched_context (void *_sc)
24799 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24801 gcc_assert (sc != NULL);
24803 cached_can_issue_more = sc->cached_can_issue_more;
24804 last_scheduled_insn = sc->last_scheduled_insn;
24805 load_store_pendulum = sc->load_store_pendulum;
24810 rs6000_free_sched_context (void *_sc)
24812 gcc_assert (_sc != NULL);
24818 /* Length in units of the trampoline for entering a nested function. */
24821 rs6000_trampoline_size (void)
24825 switch (DEFAULT_ABI)
24828 gcc_unreachable ();
24831 ret = (TARGET_32BIT) ? 12 : 24;
24836 ret = (TARGET_32BIT) ? 40 : 48;
24843 /* Emit RTL insns to initialize the variable parts of a trampoline.
24844 FNADDR is an RTX for the address of the function's pure code.
24845 CXT is an RTX for the static chain value for the function. */
24848 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
24850 int regsize = (TARGET_32BIT) ? 4 : 8;
24851 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
24852 rtx ctx_reg = force_reg (Pmode, cxt);
24853 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
24855 switch (DEFAULT_ABI)
24858 gcc_unreachable ();
24860 /* Under AIX, just build the 3 word function descriptor */
24863 rtx fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
24864 rtx fn_reg = gen_reg_rtx (Pmode);
24865 rtx toc_reg = gen_reg_rtx (Pmode);
24867 /* Macro to shorten the code expansions below. */
24868 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
24870 m_tramp = replace_equiv_address (m_tramp, addr);
24872 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
24873 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
24874 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
24875 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
24876 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
24882 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
24885 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
24886 LCT_NORMAL, VOIDmode, 4,
24888 GEN_INT (rs6000_trampoline_size ()), SImode,
24896 /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
24897 identifier as an argument, so the front end shouldn't look it up. */
24900 rs6000_attribute_takes_identifier_p (const_tree attr_id)
24902 return is_attribute_p ("altivec", attr_id);
24905 /* Handle the "altivec" attribute. The attribute may have
24906 arguments as follows:
24908 __attribute__((altivec(vector__)))
24909 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
24910 __attribute__((altivec(bool__))) (always followed by 'unsigned')
24912 and may appear more than once (e.g., 'vector bool char') in a
24913 given declaration. */
24916 rs6000_handle_altivec_attribute (tree *node,
24917 tree name ATTRIBUTE_UNUSED,
24919 int flags ATTRIBUTE_UNUSED,
24920 bool *no_add_attrs)
24922 tree type = *node, result = NULL_TREE;
24923 enum machine_mode mode;
24926 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
24927 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
24928 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
24931 while (POINTER_TYPE_P (type)
24932 || TREE_CODE (type) == FUNCTION_TYPE
24933 || TREE_CODE (type) == METHOD_TYPE
24934 || TREE_CODE (type) == ARRAY_TYPE)
24935 type = TREE_TYPE (type);
24937 mode = TYPE_MODE (type);
24939 /* Check for invalid AltiVec type qualifiers. */
24940 if (type == long_double_type_node)
24941 error ("use of %<long double%> in AltiVec types is invalid");
24942 else if (type == boolean_type_node)
24943 error ("use of boolean types in AltiVec types is invalid");
24944 else if (TREE_CODE (type) == COMPLEX_TYPE)
24945 error ("use of %<complex%> in AltiVec types is invalid");
24946 else if (DECIMAL_FLOAT_MODE_P (mode))
24947 error ("use of decimal floating point types in AltiVec types is invalid");
24948 else if (!TARGET_VSX)
24950 if (type == long_unsigned_type_node || type == long_integer_type_node)
24953 error ("use of %<long%> in AltiVec types is invalid for "
24954 "64-bit code without -mvsx");
24955 else if (rs6000_warn_altivec_long)
24956 warning (0, "use of %<long%> in AltiVec types is deprecated; "
24959 else if (type == long_long_unsigned_type_node
24960 || type == long_long_integer_type_node)
24961 error ("use of %<long long%> in AltiVec types is invalid without "
24963 else if (type == double_type_node)
24964 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
24967 switch (altivec_type)
24970 unsigned_p = TYPE_UNSIGNED (type);
24974 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
24977 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
24980 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
24983 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
24985 case SFmode: result = V4SF_type_node; break;
24986 case DFmode: result = V2DF_type_node; break;
24987 /* If the user says 'vector int bool', we may be handed the 'bool'
24988 attribute _before_ the 'vector' attribute, and so select the
24989 proper type in the 'b' case below. */
24990 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
24991 case V2DImode: case V2DFmode:
24999 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
25000 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
25001 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
25002 case QImode: case V16QImode: result = bool_V16QI_type_node;
25009 case V8HImode: result = pixel_V8HI_type_node;
25015 /* Propagate qualifiers attached to the element type
25016 onto the vector type. */
25017 if (result && result != type && TYPE_QUALS (type))
25018 result = build_qualified_type (result, TYPE_QUALS (type));
25020 *no_add_attrs = true; /* No need to hang on to the attribute. */
25023 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
25028 /* AltiVec defines four built-in scalar types that serve as vector
25029 elements; we must teach the compiler how to mangle them. */
25031 static const char *
25032 rs6000_mangle_type (const_tree type)
25034 type = TYPE_MAIN_VARIANT (type);
25036 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
25037 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
25040 if (type == bool_char_type_node) return "U6__boolc";
25041 if (type == bool_short_type_node) return "U6__bools";
25042 if (type == pixel_type_node) return "u7__pixel";
25043 if (type == bool_int_type_node) return "U6__booli";
25044 if (type == bool_long_type_node) return "U6__booll";
25046 /* Mangle IBM extended float long double as `g' (__float128) on
25047 powerpc*-linux where long-double-64 previously was the default. */
25048 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
25050 && TARGET_LONG_DOUBLE_128
25051 && !TARGET_IEEEQUAD)
25054 /* For all other types, use normal C++ mangling. */
25058 /* Handle a "longcall" or "shortcall" attribute; arguments as in
25059 struct attribute_spec.handler. */
25062 rs6000_handle_longcall_attribute (tree *node, tree name,
25063 tree args ATTRIBUTE_UNUSED,
25064 int flags ATTRIBUTE_UNUSED,
25065 bool *no_add_attrs)
25067 if (TREE_CODE (*node) != FUNCTION_TYPE
25068 && TREE_CODE (*node) != FIELD_DECL
25069 && TREE_CODE (*node) != TYPE_DECL)
25071 warning (OPT_Wattributes, "%qE attribute only applies to functions",
25073 *no_add_attrs = true;
25079 /* Set longcall attributes on all functions declared when
25080 rs6000_default_long_calls is true. */
25082 rs6000_set_default_type_attributes (tree type)
25084 if (rs6000_default_long_calls
25085 && (TREE_CODE (type) == FUNCTION_TYPE
25086 || TREE_CODE (type) == METHOD_TYPE))
25087 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
25089 TYPE_ATTRIBUTES (type));
25092 darwin_set_default_type_attributes (type);
25096 /* Return a reference suitable for calling a function with the
25097 longcall attribute. */
25100 rs6000_longcall_ref (rtx call_ref)
25102 const char *call_name;
25105 if (GET_CODE (call_ref) != SYMBOL_REF)
25108 /* System V adds '.' to the internal name, so skip them. */
25109 call_name = XSTR (call_ref, 0);
25110 if (*call_name == '.')
25112 while (*call_name == '.')
25115 node = get_identifier (call_name);
25116 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
25119 return force_reg (Pmode, call_ref);
25122 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
25123 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
25126 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
25127 struct attribute_spec.handler. */
25129 rs6000_handle_struct_attribute (tree *node, tree name,
25130 tree args ATTRIBUTE_UNUSED,
25131 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
25134 if (DECL_P (*node))
25136 if (TREE_CODE (*node) == TYPE_DECL)
25137 type = &TREE_TYPE (*node);
25142 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
25143 || TREE_CODE (*type) == UNION_TYPE)))
25145 warning (OPT_Wattributes, "%qE attribute ignored", name);
25146 *no_add_attrs = true;
25149 else if ((is_attribute_p ("ms_struct", name)
25150 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
25151 || ((is_attribute_p ("gcc_struct", name)
25152 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
25154 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
25156 *no_add_attrs = true;
25163 rs6000_ms_bitfield_layout_p (const_tree record_type)
25165 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
25166 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
25167 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
25170 #ifdef USING_ELFOS_H
25172 /* A get_unnamed_section callback, used for switching to toc_section. */
25175 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
25177 if (DEFAULT_ABI == ABI_AIX
25178 && TARGET_MINIMAL_TOC
25179 && !TARGET_RELOCATABLE)
25181 if (!toc_initialized)
25183 toc_initialized = 1;
25184 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
25185 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
25186 fprintf (asm_out_file, "\t.tc ");
25187 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
25188 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
25189 fprintf (asm_out_file, "\n");
25191 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25192 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
25193 fprintf (asm_out_file, " = .+32768\n");
25196 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25198 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
25199 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
25202 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25203 if (!toc_initialized)
25205 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
25206 fprintf (asm_out_file, " = .+32768\n");
25207 toc_initialized = 1;
25212 /* Implement TARGET_ASM_INIT_SECTIONS. */
25215 rs6000_elf_asm_init_sections (void)
25218 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
25221 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
25222 SDATA2_SECTION_ASM_OP);
25225 /* Implement TARGET_SELECT_RTX_SECTION. */
25228 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
25229 unsigned HOST_WIDE_INT align)
25231 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
25232 return toc_section;
25234 return default_elf_select_rtx_section (mode, x, align);
25237 /* For a SYMBOL_REF, set generic flags and then perform some
25238 target-specific processing.
25240 When the AIX ABI is requested on a non-AIX system, replace the
25241 function name with the real name (with a leading .) rather than the
25242 function descriptor name. This saves a lot of overriding code to
25243 read the prefixes. */
25246 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
25248 default_encode_section_info (decl, rtl, first);
25251 && TREE_CODE (decl) == FUNCTION_DECL
25253 && DEFAULT_ABI == ABI_AIX)
25255 rtx sym_ref = XEXP (rtl, 0);
25256 size_t len = strlen (XSTR (sym_ref, 0));
25257 char *str = XALLOCAVEC (char, len + 2);
25259 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
25260 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
25265 compare_section_name (const char *section, const char *templ)
25269 len = strlen (templ);
25270 return (strncmp (section, templ, len) == 0
25271 && (section[len] == 0 || section[len] == '.'));
25275 rs6000_elf_in_small_data_p (const_tree decl)
25277 if (rs6000_sdata == SDATA_NONE)
25280 /* We want to merge strings, so we never consider them small data. */
25281 if (TREE_CODE (decl) == STRING_CST)
25284 /* Functions are never in the small data area. */
25285 if (TREE_CODE (decl) == FUNCTION_DECL)
25288 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
25290 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
25291 if (compare_section_name (section, ".sdata")
25292 || compare_section_name (section, ".sdata2")
25293 || compare_section_name (section, ".gnu.linkonce.s")
25294 || compare_section_name (section, ".sbss")
25295 || compare_section_name (section, ".sbss2")
25296 || compare_section_name (section, ".gnu.linkonce.sb")
25297 || strcmp (section, ".PPC.EMB.sdata0") == 0
25298 || strcmp (section, ".PPC.EMB.sbss0") == 0)
25303 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
25306 && size <= g_switch_value
25307 /* If it's not public, and we're not going to reference it there,
25308 there's no need to put it in the small data section. */
25309 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
25316 #endif /* USING_ELFOS_H */
25318 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
25321 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
25323 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
25326 /* Return a REG that occurs in ADDR with coefficient 1.
25327 ADDR can be effectively incremented by incrementing REG.
25329 r0 is special and we must not select it as an address
25330 register by this routine since our caller will try to
25331 increment the returned register via an "la" instruction. */
25334 find_addr_reg (rtx addr)
25336 while (GET_CODE (addr) == PLUS)
25338 if (GET_CODE (XEXP (addr, 0)) == REG
25339 && REGNO (XEXP (addr, 0)) != 0)
25340 addr = XEXP (addr, 0);
25341 else if (GET_CODE (XEXP (addr, 1)) == REG
25342 && REGNO (XEXP (addr, 1)) != 0)
25343 addr = XEXP (addr, 1);
25344 else if (CONSTANT_P (XEXP (addr, 0)))
25345 addr = XEXP (addr, 1);
25346 else if (CONSTANT_P (XEXP (addr, 1)))
25347 addr = XEXP (addr, 0);
25349 gcc_unreachable ();
25351 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
25356 rs6000_fatal_bad_address (rtx op)
25358 fatal_insn ("bad address", op);
25363 typedef struct branch_island_d {
25364 tree function_name;
25369 DEF_VEC_O(branch_island);
25370 DEF_VEC_ALLOC_O(branch_island,gc);
25372 static VEC(branch_island,gc) *branch_islands;
25374 /* Remember to generate a branch island for far calls to the given
25378 add_compiler_branch_island (tree label_name, tree function_name,
25381 branch_island *bi = VEC_safe_push (branch_island, gc, branch_islands, NULL);
25383 bi->function_name = function_name;
25384 bi->label_name = label_name;
25385 bi->line_number = line_number;
25388 /* Generate far-jump branch islands for everything recorded in
25389 branch_islands. Invoked immediately after the last instruction of
25390 the epilogue has been emitted; the branch islands must be appended
25391 to, and contiguous with, the function body. Mach-O stubs are
25392 generated in machopic_output_stub(). */
25395 macho_branch_islands (void)
25399 while (!VEC_empty (branch_island, branch_islands))
25401 branch_island *bi = VEC_last (branch_island, branch_islands);
25402 const char *label = IDENTIFIER_POINTER (bi->label_name);
25403 const char *name = IDENTIFIER_POINTER (bi->function_name);
25404 char name_buf[512];
25405 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
25406 if (name[0] == '*' || name[0] == '&')
25407 strcpy (name_buf, name+1);
25411 strcpy (name_buf+1, name);
25413 strcpy (tmp_buf, "\n");
25414 strcat (tmp_buf, label);
25415 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25416 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25417 dbxout_stabd (N_SLINE, bi->line_number);
25418 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25421 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
25422 strcat (tmp_buf, label);
25423 strcat (tmp_buf, "_pic\n");
25424 strcat (tmp_buf, label);
25425 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
25427 strcat (tmp_buf, "\taddis r11,r11,ha16(");
25428 strcat (tmp_buf, name_buf);
25429 strcat (tmp_buf, " - ");
25430 strcat (tmp_buf, label);
25431 strcat (tmp_buf, "_pic)\n");
25433 strcat (tmp_buf, "\tmtlr r0\n");
25435 strcat (tmp_buf, "\taddi r12,r11,lo16(");
25436 strcat (tmp_buf, name_buf);
25437 strcat (tmp_buf, " - ");
25438 strcat (tmp_buf, label);
25439 strcat (tmp_buf, "_pic)\n");
25441 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
25445 strcat (tmp_buf, ":\nlis r12,hi16(");
25446 strcat (tmp_buf, name_buf);
25447 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
25448 strcat (tmp_buf, name_buf);
25449 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
25451 output_asm_insn (tmp_buf, 0);
25452 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25453 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25454 dbxout_stabd (N_SLINE, bi->line_number);
25455 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25456 VEC_pop (branch_island, branch_islands);
25460 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
25461 already there or not. */
25464 no_previous_def (tree function_name)
25469 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25470 if (function_name == bi->function_name)
25475 /* GET_PREV_LABEL gets the label name from the previous definition of
25479 get_prev_label (tree function_name)
25484 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25485 if (function_name == bi->function_name)
25486 return bi->label_name;
25490 /* INSN is either a function call or a millicode call. It may have an
25491 unconditional jump in its delay slot.
25493 CALL_DEST is the routine we are calling. */
25496 output_call (rtx insn, rtx *operands, int dest_operand_number,
25497 int cookie_operand_number)
25499 static char buf[256];
25500 if (darwin_emit_branch_islands
25501 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
25502 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
25505 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
25507 if (no_previous_def (funname))
25509 rtx label_rtx = gen_label_rtx ();
25510 char *label_buf, temp_buf[256];
25511 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
25512 CODE_LABEL_NUMBER (label_rtx));
25513 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
25514 labelname = get_identifier (label_buf);
25515 add_compiler_branch_island (labelname, funname, insn_line (insn));
25518 labelname = get_prev_label (funname);
25520 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
25521 instruction will reach 'foo', otherwise link as 'bl L42'".
25522 "L42" should be a 'branch island', that will do a far jump to
25523 'foo'. Branch islands are generated in
25524 macho_branch_islands(). */
25525 sprintf (buf, "jbsr %%z%d,%.246s",
25526 dest_operand_number, IDENTIFIER_POINTER (labelname));
25529 sprintf (buf, "bl %%z%d", dest_operand_number);
25533 /* Generate PIC and indirect symbol stubs. */
25536 machopic_output_stub (FILE *file, const char *symb, const char *stub)
25538 unsigned int length;
25539 char *symbol_name, *lazy_ptr_name;
25540 char *local_label_0;
25541 static int label = 0;
25543 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
25544 symb = (*targetm.strip_name_encoding) (symb);
25547 length = strlen (symb);
25548 symbol_name = XALLOCAVEC (char, length + 32);
25549 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
25551 lazy_ptr_name = XALLOCAVEC (char, length + 32);
25552 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
25555 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
25557 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
25561 fprintf (file, "\t.align 5\n");
25563 fprintf (file, "%s:\n", stub);
25564 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25567 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
25568 sprintf (local_label_0, "\"L%011d$spb\"", label);
25570 fprintf (file, "\tmflr r0\n");
25571 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
25572 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
25573 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
25574 lazy_ptr_name, local_label_0);
25575 fprintf (file, "\tmtlr r0\n");
25576 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
25577 (TARGET_64BIT ? "ldu" : "lwzu"),
25578 lazy_ptr_name, local_label_0);
25579 fprintf (file, "\tmtctr r12\n");
25580 fprintf (file, "\tbctr\n");
25584 fprintf (file, "\t.align 4\n");
25586 fprintf (file, "%s:\n", stub);
25587 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25589 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
25590 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
25591 (TARGET_64BIT ? "ldu" : "lwzu"),
25593 fprintf (file, "\tmtctr r12\n");
25594 fprintf (file, "\tbctr\n");
25597 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
25598 fprintf (file, "%s:\n", lazy_ptr_name);
25599 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25600 fprintf (file, "%sdyld_stub_binding_helper\n",
25601 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
25604 /* Legitimize PIC addresses. If the address is already
25605 position-independent, we return ORIG. Newly generated
25606 position-independent addresses go into a reg. This is REG if non
25607 zero, otherwise we allocate register(s) as necessary. */
25609 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
25612 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
25617 if (reg == NULL && ! reload_in_progress && ! reload_completed)
25618 reg = gen_reg_rtx (Pmode);
25620 if (GET_CODE (orig) == CONST)
25624 if (GET_CODE (XEXP (orig, 0)) == PLUS
25625 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
25628 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
25630 /* Use a different reg for the intermediate value, as
25631 it will be marked UNCHANGING. */
25632 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
25633 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
25636 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
25639 if (GET_CODE (offset) == CONST_INT)
25641 if (SMALL_INT (offset))
25642 return plus_constant (base, INTVAL (offset));
25643 else if (! reload_in_progress && ! reload_completed)
25644 offset = force_reg (Pmode, offset);
25647 rtx mem = force_const_mem (Pmode, orig);
25648 return machopic_legitimize_pic_address (mem, Pmode, reg);
25651 return gen_rtx_PLUS (Pmode, base, offset);
25654 /* Fall back on generic machopic code. */
25655 return machopic_legitimize_pic_address (orig, mode, reg);
25658 /* Output a .machine directive for the Darwin assembler, and call
25659 the generic start_file routine. */
25662 rs6000_darwin_file_start (void)
25664 static const struct
25670 { "ppc64", "ppc64", MASK_64BIT },
25671 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
25672 { "power4", "ppc970", 0 },
25673 { "G5", "ppc970", 0 },
25674 { "7450", "ppc7450", 0 },
25675 { "7400", "ppc7400", MASK_ALTIVEC },
25676 { "G4", "ppc7400", 0 },
25677 { "750", "ppc750", 0 },
25678 { "740", "ppc750", 0 },
25679 { "G3", "ppc750", 0 },
25680 { "604e", "ppc604e", 0 },
25681 { "604", "ppc604", 0 },
25682 { "603e", "ppc603", 0 },
25683 { "603", "ppc603", 0 },
25684 { "601", "ppc601", 0 },
25685 { NULL, "ppc", 0 } };
25686 const char *cpu_id = "";
25689 rs6000_file_start ();
25690 darwin_file_start ();
25692 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
25693 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
25694 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
25695 && rs6000_select[i].string[0] != '\0')
25696 cpu_id = rs6000_select[i].string;
25698 /* Look through the mapping array. Pick the first name that either
25699 matches the argument, has a bit set in IF_SET that is also set
25700 in the target flags, or has a NULL name. */
25703 while (mapping[i].arg != NULL
25704 && strcmp (mapping[i].arg, cpu_id) != 0
25705 && (mapping[i].if_set & target_flags) == 0)
25708 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
25711 #endif /* TARGET_MACHO */
25715 rs6000_elf_reloc_rw_mask (void)
25719 else if (DEFAULT_ABI == ABI_AIX)
25725 /* Record an element in the table of global constructors. SYMBOL is
25726 a SYMBOL_REF of the function to be called; PRIORITY is a number
25727 between 0 and MAX_INIT_PRIORITY.
25729 This differs from default_named_section_asm_out_constructor in
25730 that we have special handling for -mrelocatable. */
25733 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
25735 const char *section = ".ctors";
25738 if (priority != DEFAULT_INIT_PRIORITY)
25740 sprintf (buf, ".ctors.%.5u",
25741 /* Invert the numbering so the linker puts us in the proper
25742 order; constructors are run from right to left, and the
25743 linker sorts in increasing order. */
25744 MAX_INIT_PRIORITY - priority);
25748 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25749 assemble_align (POINTER_SIZE);
25751 if (TARGET_RELOCATABLE)
25753 fputs ("\t.long (", asm_out_file);
25754 output_addr_const (asm_out_file, symbol);
25755 fputs (")@fixup\n", asm_out_file);
25758 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25762 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
25764 const char *section = ".dtors";
25767 if (priority != DEFAULT_INIT_PRIORITY)
25769 sprintf (buf, ".dtors.%.5u",
25770 /* Invert the numbering so the linker puts us in the proper
25771 order; constructors are run from right to left, and the
25772 linker sorts in increasing order. */
25773 MAX_INIT_PRIORITY - priority);
25777 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25778 assemble_align (POINTER_SIZE);
25780 if (TARGET_RELOCATABLE)
25782 fputs ("\t.long (", asm_out_file);
25783 output_addr_const (asm_out_file, symbol);
25784 fputs (")@fixup\n", asm_out_file);
25787 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25791 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
25795 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
25796 ASM_OUTPUT_LABEL (file, name);
25797 fputs (DOUBLE_INT_ASM_OP, file);
25798 rs6000_output_function_entry (file, name);
25799 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
25802 fputs ("\t.size\t", file);
25803 assemble_name (file, name);
25804 fputs (",24\n\t.type\t.", file);
25805 assemble_name (file, name);
25806 fputs (",@function\n", file);
25807 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
25809 fputs ("\t.globl\t.", file);
25810 assemble_name (file, name);
25815 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25816 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25817 rs6000_output_function_entry (file, name);
25818 fputs (":\n", file);
25822 if (TARGET_RELOCATABLE
25823 && !TARGET_SECURE_PLT
25824 && (get_pool_size () != 0 || crtl->profile)
25829 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
25831 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
25832 fprintf (file, "\t.long ");
25833 assemble_name (file, buf);
25835 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
25836 assemble_name (file, buf);
25840 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25841 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25843 if (DEFAULT_ABI == ABI_AIX)
25845 const char *desc_name, *orig_name;
25847 orig_name = (*targetm.strip_name_encoding) (name);
25848 desc_name = orig_name;
25849 while (*desc_name == '.')
25852 if (TREE_PUBLIC (decl))
25853 fprintf (file, "\t.globl %s\n", desc_name);
25855 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25856 fprintf (file, "%s:\n", desc_name);
25857 fprintf (file, "\t.long %s\n", orig_name);
25858 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
25859 if (DEFAULT_ABI == ABI_AIX)
25860 fputs ("\t.long 0\n", file);
25861 fprintf (file, "\t.previous\n");
25863 ASM_OUTPUT_LABEL (file, name);
25867 rs6000_elf_file_end (void)
25869 #ifdef HAVE_AS_GNU_ATTRIBUTE
25870 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
25872 if (rs6000_passes_float)
25873 fprintf (asm_out_file, "\t.gnu_attribute 4, %d\n",
25874 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
25875 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
25877 if (rs6000_passes_vector)
25878 fprintf (asm_out_file, "\t.gnu_attribute 8, %d\n",
25879 (TARGET_ALTIVEC_ABI ? 2
25880 : TARGET_SPE_ABI ? 3
25882 if (rs6000_returns_struct)
25883 fprintf (asm_out_file, "\t.gnu_attribute 12, %d\n",
25884 aix_struct_return ? 2 : 1);
25887 #ifdef POWERPC_LINUX
25889 file_end_indicate_exec_stack ();
25896 rs6000_xcoff_asm_output_anchor (rtx symbol)
25900 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
25901 SYMBOL_REF_BLOCK_OFFSET (symbol));
25902 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
25906 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
25908 fputs (GLOBAL_ASM_OP, stream);
25909 RS6000_OUTPUT_BASENAME (stream, name);
25910 putc ('\n', stream);
25913 /* A get_unnamed_decl callback, used for read-only sections. PTR
25914 points to the section string variable. */
25917 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
25919 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
25920 *(const char *const *) directive,
25921 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
25924 /* Likewise for read-write sections. */
25927 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
25929 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
25930 *(const char *const *) directive,
25931 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
25934 /* A get_unnamed_section callback, used for switching to toc_section. */
25937 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
25939 if (TARGET_MINIMAL_TOC)
25941 /* toc_section is always selected at least once from
25942 rs6000_xcoff_file_start, so this is guaranteed to
25943 always be defined once and only once in each file. */
25944 if (!toc_initialized)
25946 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
25947 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
25948 toc_initialized = 1;
25950 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
25951 (TARGET_32BIT ? "" : ",3"));
25954 fputs ("\t.toc\n", asm_out_file);
25957 /* Implement TARGET_ASM_INIT_SECTIONS. */
25960 rs6000_xcoff_asm_init_sections (void)
25962 read_only_data_section
25963 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
25964 &xcoff_read_only_section_name);
25966 private_data_section
25967 = get_unnamed_section (SECTION_WRITE,
25968 rs6000_xcoff_output_readwrite_section_asm_op,
25969 &xcoff_private_data_section_name);
25971 read_only_private_data_section
25972 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
25973 &xcoff_private_data_section_name);
25976 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
25978 readonly_data_section = read_only_data_section;
25979 exception_section = data_section;
25983 rs6000_xcoff_reloc_rw_mask (void)
25989 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
25990 tree decl ATTRIBUTE_UNUSED)
25993 static const char * const suffix[3] = { "PR", "RO", "RW" };
25995 if (flags & SECTION_CODE)
25997 else if (flags & SECTION_WRITE)
26002 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
26003 (flags & SECTION_CODE) ? "." : "",
26004 name, suffix[smclass], flags & SECTION_ENTSIZE);
26008 rs6000_xcoff_select_section (tree decl, int reloc,
26009 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
26011 if (decl_readonly_section (decl, reloc))
26013 if (TREE_PUBLIC (decl))
26014 return read_only_data_section;
26016 return read_only_private_data_section;
26020 if (TREE_PUBLIC (decl))
26021 return data_section;
26023 return private_data_section;
26028 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
26032 /* Use select_section for private and uninitialized data. */
26033 if (!TREE_PUBLIC (decl)
26034 || DECL_COMMON (decl)
26035 || DECL_INITIAL (decl) == NULL_TREE
26036 || DECL_INITIAL (decl) == error_mark_node
26037 || (flag_zero_initialized_in_bss
26038 && initializer_zerop (DECL_INITIAL (decl))))
26041 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
26042 name = (*targetm.strip_name_encoding) (name);
26043 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
26046 /* Select section for constant in constant pool.
26048 On RS/6000, all constants are in the private read-only data area.
26049 However, if this is being placed in the TOC it must be output as a
26053 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
26054 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
26056 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
26057 return toc_section;
26059 return read_only_private_data_section;
26062 /* Remove any trailing [DS] or the like from the symbol name. */
26064 static const char *
26065 rs6000_xcoff_strip_name_encoding (const char *name)
26070 len = strlen (name);
26071 if (name[len - 1] == ']')
26072 return ggc_alloc_string (name, len - 4);
26077 /* Section attributes. AIX is always PIC. */
26079 static unsigned int
26080 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
26082 unsigned int align;
26083 unsigned int flags = default_section_type_flags (decl, name, reloc);
26085 /* Align to at least UNIT size. */
26086 if (flags & SECTION_CODE)
26087 align = MIN_UNITS_PER_WORD;
26089 /* Increase alignment of large objects if not already stricter. */
26090 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
26091 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
26092 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
26094 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
26097 /* Output at beginning of assembler file.
26099 Initialize the section names for the RS/6000 at this point.
26101 Specify filename, including full path, to assembler.
26103 We want to go into the TOC section so at least one .toc will be emitted.
26104 Also, in order to output proper .bs/.es pairs, we need at least one static
26105 [RW] section emitted.
26107 Finally, declare mcount when profiling to make the assembler happy. */
26110 rs6000_xcoff_file_start (void)
26112 rs6000_gen_section_name (&xcoff_bss_section_name,
26113 main_input_filename, ".bss_");
26114 rs6000_gen_section_name (&xcoff_private_data_section_name,
26115 main_input_filename, ".rw_");
26116 rs6000_gen_section_name (&xcoff_read_only_section_name,
26117 main_input_filename, ".ro_");
26119 fputs ("\t.file\t", asm_out_file);
26120 output_quoted_string (asm_out_file, main_input_filename);
26121 fputc ('\n', asm_out_file);
26122 if (write_symbols != NO_DEBUG)
26123 switch_to_section (private_data_section);
26124 switch_to_section (text_section);
26126 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
26127 rs6000_file_start ();
26130 /* Output at end of assembler file.
26131 On the RS/6000, referencing data should automatically pull in text. */
26134 rs6000_xcoff_file_end (void)
26136 switch_to_section (text_section);
26137 fputs ("_section_.text:\n", asm_out_file);
26138 switch_to_section (data_section);
26139 fputs (TARGET_32BIT
26140 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
26143 #endif /* TARGET_XCOFF */
26145 /* Compute a (partial) cost for rtx X. Return true if the complete
26146 cost has been computed, and false if subexpressions should be
26147 scanned. In either case, *TOTAL contains the cost result. */
26150 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
26153 enum machine_mode mode = GET_MODE (x);
26157 /* On the RS/6000, if it is valid in the insn, it is free. */
26159 if (((outer_code == SET
26160 || outer_code == PLUS
26161 || outer_code == MINUS)
26162 && (satisfies_constraint_I (x)
26163 || satisfies_constraint_L (x)))
26164 || (outer_code == AND
26165 && (satisfies_constraint_K (x)
26167 ? satisfies_constraint_L (x)
26168 : satisfies_constraint_J (x))
26169 || mask_operand (x, mode)
26171 && mask64_operand (x, DImode))))
26172 || ((outer_code == IOR || outer_code == XOR)
26173 && (satisfies_constraint_K (x)
26175 ? satisfies_constraint_L (x)
26176 : satisfies_constraint_J (x))))
26177 || outer_code == ASHIFT
26178 || outer_code == ASHIFTRT
26179 || outer_code == LSHIFTRT
26180 || outer_code == ROTATE
26181 || outer_code == ROTATERT
26182 || outer_code == ZERO_EXTRACT
26183 || (outer_code == MULT
26184 && satisfies_constraint_I (x))
26185 || ((outer_code == DIV || outer_code == UDIV
26186 || outer_code == MOD || outer_code == UMOD)
26187 && exact_log2 (INTVAL (x)) >= 0)
26188 || (outer_code == COMPARE
26189 && (satisfies_constraint_I (x)
26190 || satisfies_constraint_K (x)))
26191 || ((outer_code == EQ || outer_code == NE)
26192 && (satisfies_constraint_I (x)
26193 || satisfies_constraint_K (x)
26195 ? satisfies_constraint_L (x)
26196 : satisfies_constraint_J (x))))
26197 || (outer_code == GTU
26198 && satisfies_constraint_I (x))
26199 || (outer_code == LTU
26200 && satisfies_constraint_P (x)))
26205 else if ((outer_code == PLUS
26206 && reg_or_add_cint_operand (x, VOIDmode))
26207 || (outer_code == MINUS
26208 && reg_or_sub_cint_operand (x, VOIDmode))
26209 || ((outer_code == SET
26210 || outer_code == IOR
26211 || outer_code == XOR)
26213 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
26215 *total = COSTS_N_INSNS (1);
26221 if (mode == DImode && code == CONST_DOUBLE)
26223 if ((outer_code == IOR || outer_code == XOR)
26224 && CONST_DOUBLE_HIGH (x) == 0
26225 && (CONST_DOUBLE_LOW (x)
26226 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
26231 else if ((outer_code == AND && and64_2_operand (x, DImode))
26232 || ((outer_code == SET
26233 || outer_code == IOR
26234 || outer_code == XOR)
26235 && CONST_DOUBLE_HIGH (x) == 0))
26237 *total = COSTS_N_INSNS (1);
26247 /* When optimizing for size, MEM should be slightly more expensive
26248 than generating address, e.g., (plus (reg) (const)).
26249 L1 cache latency is about two instructions. */
26250 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
26259 if (FLOAT_MODE_P (mode))
26260 *total = rs6000_cost->fp;
26262 *total = COSTS_N_INSNS (1);
26266 if (GET_CODE (XEXP (x, 1)) == CONST_INT
26267 && satisfies_constraint_I (XEXP (x, 1)))
26269 if (INTVAL (XEXP (x, 1)) >= -256
26270 && INTVAL (XEXP (x, 1)) <= 255)
26271 *total = rs6000_cost->mulsi_const9;
26273 *total = rs6000_cost->mulsi_const;
26275 else if (mode == SFmode)
26276 *total = rs6000_cost->fp;
26277 else if (FLOAT_MODE_P (mode))
26278 *total = rs6000_cost->dmul;
26279 else if (mode == DImode)
26280 *total = rs6000_cost->muldi;
26282 *total = rs6000_cost->mulsi;
26286 if (mode == SFmode)
26287 *total = rs6000_cost->fp;
26289 *total = rs6000_cost->dmul;
26294 if (FLOAT_MODE_P (mode))
26296 *total = mode == DFmode ? rs6000_cost->ddiv
26297 : rs6000_cost->sdiv;
26304 if (GET_CODE (XEXP (x, 1)) == CONST_INT
26305 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
26307 if (code == DIV || code == MOD)
26309 *total = COSTS_N_INSNS (2);
26312 *total = COSTS_N_INSNS (1);
26316 if (GET_MODE (XEXP (x, 1)) == DImode)
26317 *total = rs6000_cost->divdi;
26319 *total = rs6000_cost->divsi;
26321 /* Add in shift and subtract for MOD. */
26322 if (code == MOD || code == UMOD)
26323 *total += COSTS_N_INSNS (2);
26328 *total = COSTS_N_INSNS (4);
26332 *total = COSTS_N_INSNS (TARGET_POPCNTD ? 1 : 6);
26336 *total = COSTS_N_INSNS (TARGET_CMPB ? 2 : 6);
26340 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
26352 *total = COSTS_N_INSNS (1);
26360 /* Handle mul_highpart. */
26361 if (outer_code == TRUNCATE
26362 && GET_CODE (XEXP (x, 0)) == MULT)
26364 if (mode == DImode)
26365 *total = rs6000_cost->muldi;
26367 *total = rs6000_cost->mulsi;
26370 else if (outer_code == AND)
26373 *total = COSTS_N_INSNS (1);
26378 if (GET_CODE (XEXP (x, 0)) == MEM)
26381 *total = COSTS_N_INSNS (1);
26387 if (!FLOAT_MODE_P (mode))
26389 *total = COSTS_N_INSNS (1);
26395 case UNSIGNED_FLOAT:
26398 case FLOAT_TRUNCATE:
26399 *total = rs6000_cost->fp;
26403 if (mode == DFmode)
26406 *total = rs6000_cost->fp;
26410 switch (XINT (x, 1))
26413 *total = rs6000_cost->fp;
26425 *total = COSTS_N_INSNS (1);
26428 else if (FLOAT_MODE_P (mode)
26429 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
26431 *total = rs6000_cost->fp;
26439 /* Carry bit requires mode == Pmode.
26440 NEG or PLUS already counted so only add one. */
26442 && (outer_code == NEG || outer_code == PLUS))
26444 *total = COSTS_N_INSNS (1);
26447 if (outer_code == SET)
26449 if (XEXP (x, 1) == const0_rtx)
26451 if (TARGET_ISEL && !TARGET_MFCRF)
26452 *total = COSTS_N_INSNS (8);
26454 *total = COSTS_N_INSNS (2);
26457 else if (mode == Pmode)
26459 *total = COSTS_N_INSNS (3);
26468 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
26470 if (TARGET_ISEL && !TARGET_MFCRF)
26471 *total = COSTS_N_INSNS (8);
26473 *total = COSTS_N_INSNS (2);
26477 if (outer_code == COMPARE)
26491 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
26494 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
26497 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
26500 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
26501 "total = %d, speed = %s, x:\n",
26502 ret ? "complete" : "scan inner",
26503 GET_RTX_NAME (code),
26504 GET_RTX_NAME (outer_code),
26506 speed ? "true" : "false");
26513 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
26516 rs6000_debug_address_cost (rtx x, bool speed)
26518 int ret = TARGET_ADDRESS_COST (x, speed);
26520 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
26521 ret, speed ? "true" : "false");
26528 /* A C expression returning the cost of moving data from a register of class
26529 CLASS1 to one of CLASS2. */
26532 rs6000_register_move_cost (enum machine_mode mode,
26533 reg_class_t from, reg_class_t to)
26537 /* Moves from/to GENERAL_REGS. */
26538 if (reg_classes_intersect_p (to, GENERAL_REGS)
26539 || reg_classes_intersect_p (from, GENERAL_REGS))
26541 if (! reg_classes_intersect_p (to, GENERAL_REGS))
26544 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
26545 ret = (rs6000_memory_move_cost (mode, from, false)
26546 + rs6000_memory_move_cost (mode, GENERAL_REGS, false));
26548 /* It's more expensive to move CR_REGS than CR0_REGS because of the
26550 else if (from == CR_REGS)
26553 /* Power6 has slower LR/CTR moves so make them more expensive than
26554 memory in order to bias spills to memory .*/
26555 else if (rs6000_cpu == PROCESSOR_POWER6
26556 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
26557 ret = 6 * hard_regno_nregs[0][mode];
26560 /* A move will cost one instruction per GPR moved. */
26561 ret = 2 * hard_regno_nregs[0][mode];
26564 /* If we have VSX, we can easily move between FPR or Altivec registers. */
26565 else if (VECTOR_UNIT_VSX_P (mode)
26566 && reg_classes_intersect_p (to, VSX_REGS)
26567 && reg_classes_intersect_p (from, VSX_REGS))
26568 ret = 2 * hard_regno_nregs[32][mode];
26570 /* Moving between two similar registers is just one instruction. */
26571 else if (reg_classes_intersect_p (to, from))
26572 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
26574 /* Everything else has to go through GENERAL_REGS. */
26576 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
26577 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
26579 if (TARGET_DEBUG_COST)
26581 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
26582 ret, GET_MODE_NAME (mode), reg_class_names[from],
26583 reg_class_names[to]);
26588 /* A C expressions returning the cost of moving data of MODE from a register to
26592 rs6000_memory_move_cost (enum machine_mode mode, reg_class_t rclass,
26593 bool in ATTRIBUTE_UNUSED)
26597 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
26598 ret = 4 * hard_regno_nregs[0][mode];
26599 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
26600 ret = 4 * hard_regno_nregs[32][mode];
26601 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
26602 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
26604 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
26606 if (TARGET_DEBUG_COST)
26608 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
26609 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
26614 /* Returns a code for a target-specific builtin that implements
26615 reciprocal of the function, or NULL_TREE if not available. */
26618 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
26619 bool sqrt ATTRIBUTE_UNUSED)
26621 if (optimize_insn_for_size_p ())
26627 case VSX_BUILTIN_XVSQRTDP:
26628 if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode))
26631 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
26633 case VSX_BUILTIN_XVSQRTSP:
26634 if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode))
26637 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V4SF];
26646 case BUILT_IN_SQRT:
26647 if (!RS6000_RECIP_AUTO_RSQRTE_P (DFmode))
26650 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRT];
26652 case BUILT_IN_SQRTF:
26653 if (!RS6000_RECIP_AUTO_RSQRTE_P (SFmode))
26656 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
26663 /* Load up a constant. If the mode is a vector mode, splat the value across
26664 all of the vector elements. */
26667 rs6000_load_constant_and_splat (enum machine_mode mode, REAL_VALUE_TYPE dconst)
26671 if (mode == SFmode || mode == DFmode)
26673 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, mode);
26674 reg = force_reg (mode, d);
26676 else if (mode == V4SFmode)
26678 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, SFmode);
26679 rtvec v = gen_rtvec (4, d, d, d, d);
26680 reg = gen_reg_rtx (mode);
26681 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26683 else if (mode == V2DFmode)
26685 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, DFmode);
26686 rtvec v = gen_rtvec (2, d, d);
26687 reg = gen_reg_rtx (mode);
26688 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26691 gcc_unreachable ();
26696 /* Generate an FMA instruction. */
26699 rs6000_emit_madd (rtx target, rtx m1, rtx m2, rtx a)
26701 enum machine_mode mode = GET_MODE (target);
26704 dst = expand_ternary_op (mode, fma_optab, m1, m2, a, target, 0);
26705 gcc_assert (dst != NULL);
26708 emit_move_insn (target, dst);
26711 /* Generate a FMSUB instruction: dst = fma(m1, m2, -a). */
26714 rs6000_emit_msub (rtx target, rtx m1, rtx m2, rtx a)
26716 enum machine_mode mode = GET_MODE (target);
26719 /* Altivec does not support fms directly;
26720 generate in terms of fma in that case. */
26721 if (optab_handler (fms_optab, mode) != CODE_FOR_nothing)
26722 dst = expand_ternary_op (mode, fms_optab, m1, m2, a, target, 0);
26725 a = expand_unop (mode, neg_optab, a, NULL_RTX, 0);
26726 dst = expand_ternary_op (mode, fma_optab, m1, m2, a, target, 0);
26728 gcc_assert (dst != NULL);
26731 emit_move_insn (target, dst);
26734 /* Generate a FNMSUB instruction: dst = -fma(m1, m2, -a). */
26737 rs6000_emit_nmsub (rtx dst, rtx m1, rtx m2, rtx a)
26739 enum machine_mode mode = GET_MODE (dst);
26742 /* This is a tad more complicated, since the fnma_optab is for
26743 a different expression: fma(-m1, m2, a), which is the same
26744 thing except in the case of signed zeros.
26746 Fortunately we know that if FMA is supported that FNMSUB is
26747 also supported in the ISA. Just expand it directly. */
26749 gcc_assert (optab_handler (fma_optab, mode) != CODE_FOR_nothing);
26751 r = gen_rtx_NEG (mode, a);
26752 r = gen_rtx_FMA (mode, m1, m2, r);
26753 r = gen_rtx_NEG (mode, r);
26754 emit_insn (gen_rtx_SET (VOIDmode, dst, r));
26757 /* Newton-Raphson approximation of floating point divide with just 2 passes
26758 (either single precision floating point, or newer machines with higher
26759 accuracy estimates). Support both scalar and vector divide. Assumes no
26760 trapping math and finite arguments. */
26763 rs6000_emit_swdiv_high_precision (rtx dst, rtx n, rtx d)
26765 enum machine_mode mode = GET_MODE (dst);
26766 rtx x0, e0, e1, y1, u0, v0;
26767 enum insn_code code = optab_handler (smul_optab, mode);
26768 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26769 rtx one = rs6000_load_constant_and_splat (mode, dconst1);
26771 gcc_assert (code != CODE_FOR_nothing);
26773 /* x0 = 1./d estimate */
26774 x0 = gen_reg_rtx (mode);
26775 emit_insn (gen_rtx_SET (VOIDmode, x0,
26776 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26779 e0 = gen_reg_rtx (mode);
26780 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - (d * x0) */
26782 e1 = gen_reg_rtx (mode);
26783 rs6000_emit_madd (e1, e0, e0, e0); /* e1 = (e0 * e0) + e0 */
26785 y1 = gen_reg_rtx (mode);
26786 rs6000_emit_madd (y1, e1, x0, x0); /* y1 = (e1 * x0) + x0 */
26788 u0 = gen_reg_rtx (mode);
26789 emit_insn (gen_mul (u0, n, y1)); /* u0 = n * y1 */
26791 v0 = gen_reg_rtx (mode);
26792 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - (d * u0) */
26794 rs6000_emit_madd (dst, v0, y1, u0); /* dst = (v0 * y1) + u0 */
26797 /* Newton-Raphson approximation of floating point divide that has a low
26798 precision estimate. Assumes no trapping math and finite arguments. */
26801 rs6000_emit_swdiv_low_precision (rtx dst, rtx n, rtx d)
26803 enum machine_mode mode = GET_MODE (dst);
26804 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
26805 enum insn_code code = optab_handler (smul_optab, mode);
26806 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26808 gcc_assert (code != CODE_FOR_nothing);
26810 one = rs6000_load_constant_and_splat (mode, dconst1);
26812 /* x0 = 1./d estimate */
26813 x0 = gen_reg_rtx (mode);
26814 emit_insn (gen_rtx_SET (VOIDmode, x0,
26815 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26818 e0 = gen_reg_rtx (mode);
26819 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - d * x0 */
26821 y1 = gen_reg_rtx (mode);
26822 rs6000_emit_madd (y1, e0, x0, x0); /* y1 = x0 + e0 * x0 */
26824 e1 = gen_reg_rtx (mode);
26825 emit_insn (gen_mul (e1, e0, e0)); /* e1 = e0 * e0 */
26827 y2 = gen_reg_rtx (mode);
26828 rs6000_emit_madd (y2, e1, y1, y1); /* y2 = y1 + e1 * y1 */
26830 e2 = gen_reg_rtx (mode);
26831 emit_insn (gen_mul (e2, e1, e1)); /* e2 = e1 * e1 */
26833 y3 = gen_reg_rtx (mode);
26834 rs6000_emit_madd (y3, e2, y2, y2); /* y3 = y2 + e2 * y2 */
26836 u0 = gen_reg_rtx (mode);
26837 emit_insn (gen_mul (u0, n, y3)); /* u0 = n * y3 */
26839 v0 = gen_reg_rtx (mode);
26840 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - d * u0 */
26842 rs6000_emit_madd (dst, v0, y3, u0); /* dst = u0 + v0 * y3 */
26845 /* Newton-Raphson approximation of floating point divide DST = N/D. If NOTE_P,
26846 add a reg_note saying that this was a division. Support both scalar and
26847 vector divide. Assumes no trapping math and finite arguments. */
26850 rs6000_emit_swdiv (rtx dst, rtx n, rtx d, bool note_p)
26852 enum machine_mode mode = GET_MODE (dst);
26854 if (RS6000_RECIP_HIGH_PRECISION_P (mode))
26855 rs6000_emit_swdiv_high_precision (dst, n, d);
26857 rs6000_emit_swdiv_low_precision (dst, n, d);
26860 add_reg_note (get_last_insn (), REG_EQUAL, gen_rtx_DIV (mode, n, d));
26863 /* Newton-Raphson approximation of single/double-precision floating point
26864 rsqrt. Assumes no trapping math and finite arguments. */
26867 rs6000_emit_swrsqrt (rtx dst, rtx src)
26869 enum machine_mode mode = GET_MODE (src);
26870 rtx x0 = gen_reg_rtx (mode);
26871 rtx y = gen_reg_rtx (mode);
26872 int passes = (TARGET_RECIP_PRECISION) ? 2 : 3;
26873 REAL_VALUE_TYPE dconst3_2;
26876 enum insn_code code = optab_handler (smul_optab, mode);
26877 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26879 gcc_assert (code != CODE_FOR_nothing);
26881 /* Load up the constant 1.5 either as a scalar, or as a vector. */
26882 real_from_integer (&dconst3_2, VOIDmode, 3, 0, 0);
26883 SET_REAL_EXP (&dconst3_2, REAL_EXP (&dconst3_2) - 1);
26885 halfthree = rs6000_load_constant_and_splat (mode, dconst3_2);
26887 /* x0 = rsqrt estimate */
26888 emit_insn (gen_rtx_SET (VOIDmode, x0,
26889 gen_rtx_UNSPEC (mode, gen_rtvec (1, src),
26892 /* y = 0.5 * src = 1.5 * src - src -> fewer constants */
26893 rs6000_emit_msub (y, src, halfthree, src);
26895 for (i = 0; i < passes; i++)
26897 rtx x1 = gen_reg_rtx (mode);
26898 rtx u = gen_reg_rtx (mode);
26899 rtx v = gen_reg_rtx (mode);
26901 /* x1 = x0 * (1.5 - y * (x0 * x0)) */
26902 emit_insn (gen_mul (u, x0, x0));
26903 rs6000_emit_nmsub (v, y, u, halfthree);
26904 emit_insn (gen_mul (x1, x0, v));
26908 emit_move_insn (dst, x0);
26912 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
26913 (Power7) targets. DST is the target, and SRC is the argument operand. */
26916 rs6000_emit_popcount (rtx dst, rtx src)
26918 enum machine_mode mode = GET_MODE (dst);
26921 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
26922 if (TARGET_POPCNTD)
26924 if (mode == SImode)
26925 emit_insn (gen_popcntdsi2 (dst, src));
26927 emit_insn (gen_popcntddi2 (dst, src));
26931 tmp1 = gen_reg_rtx (mode);
26933 if (mode == SImode)
26935 emit_insn (gen_popcntbsi2 (tmp1, src));
26936 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
26938 tmp2 = force_reg (SImode, tmp2);
26939 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
26943 emit_insn (gen_popcntbdi2 (tmp1, src));
26944 tmp2 = expand_mult (DImode, tmp1,
26945 GEN_INT ((HOST_WIDE_INT)
26946 0x01010101 << 32 | 0x01010101),
26948 tmp2 = force_reg (DImode, tmp2);
26949 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
26954 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
26955 target, and SRC is the argument operand. */
26958 rs6000_emit_parity (rtx dst, rtx src)
26960 enum machine_mode mode = GET_MODE (dst);
26963 tmp = gen_reg_rtx (mode);
26965 /* Use the PPC ISA 2.05 prtyw/prtyd instruction if we can. */
26968 if (mode == SImode)
26970 emit_insn (gen_popcntbsi2 (tmp, src));
26971 emit_insn (gen_paritysi2_cmpb (dst, tmp));
26975 emit_insn (gen_popcntbdi2 (tmp, src));
26976 emit_insn (gen_paritydi2_cmpb (dst, tmp));
26981 if (mode == SImode)
26983 /* Is mult+shift >= shift+xor+shift+xor? */
26984 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
26986 rtx tmp1, tmp2, tmp3, tmp4;
26988 tmp1 = gen_reg_rtx (SImode);
26989 emit_insn (gen_popcntbsi2 (tmp1, src));
26991 tmp2 = gen_reg_rtx (SImode);
26992 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
26993 tmp3 = gen_reg_rtx (SImode);
26994 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
26996 tmp4 = gen_reg_rtx (SImode);
26997 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
26998 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
27001 rs6000_emit_popcount (tmp, src);
27002 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
27006 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
27007 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
27009 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
27011 tmp1 = gen_reg_rtx (DImode);
27012 emit_insn (gen_popcntbdi2 (tmp1, src));
27014 tmp2 = gen_reg_rtx (DImode);
27015 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
27016 tmp3 = gen_reg_rtx (DImode);
27017 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
27019 tmp4 = gen_reg_rtx (DImode);
27020 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
27021 tmp5 = gen_reg_rtx (DImode);
27022 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
27024 tmp6 = gen_reg_rtx (DImode);
27025 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
27026 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
27029 rs6000_emit_popcount (tmp, src);
27030 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
27034 /* Return an RTX representing where to find the function value of a
27035 function returning MODE. */
27037 rs6000_complex_function_value (enum machine_mode mode)
27039 unsigned int regno;
27041 enum machine_mode inner = GET_MODE_INNER (mode);
27042 unsigned int inner_bytes = GET_MODE_SIZE (inner);
27044 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
27045 regno = FP_ARG_RETURN;
27048 regno = GP_ARG_RETURN;
27050 /* 32-bit is OK since it'll go in r3/r4. */
27051 if (TARGET_32BIT && inner_bytes >= 4)
27052 return gen_rtx_REG (mode, regno);
27055 if (inner_bytes >= 8)
27056 return gen_rtx_REG (mode, regno);
27058 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
27060 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
27061 GEN_INT (inner_bytes));
27062 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
27065 /* Target hook for TARGET_FUNCTION_VALUE.
27067 On the SPE, both FPs and vectors are returned in r3.
27069 On RS/6000 an integer value is in r3 and a floating-point value is in
27070 fp1, unless -msoft-float. */
27073 rs6000_function_value (const_tree valtype,
27074 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
27075 bool outgoing ATTRIBUTE_UNUSED)
27077 enum machine_mode mode;
27078 unsigned int regno;
27080 /* Special handling for structs in darwin64. */
27082 && rs6000_darwin64_struct_check_p (TYPE_MODE (valtype), valtype))
27084 CUMULATIVE_ARGS valcum;
27088 valcum.fregno = FP_ARG_MIN_REG;
27089 valcum.vregno = ALTIVEC_ARG_MIN_REG;
27090 /* Do a trial code generation as if this were going to be passed as
27091 an argument; if any part goes in memory, we return NULL. */
27092 valret = rs6000_darwin64_record_arg (&valcum, valtype, true, /* retval= */ true);
27095 /* Otherwise fall through to standard ABI rules. */
27098 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
27100 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
27101 return gen_rtx_PARALLEL (DImode,
27103 gen_rtx_EXPR_LIST (VOIDmode,
27104 gen_rtx_REG (SImode, GP_ARG_RETURN),
27106 gen_rtx_EXPR_LIST (VOIDmode,
27107 gen_rtx_REG (SImode,
27108 GP_ARG_RETURN + 1),
27111 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
27113 return gen_rtx_PARALLEL (DCmode,
27115 gen_rtx_EXPR_LIST (VOIDmode,
27116 gen_rtx_REG (SImode, GP_ARG_RETURN),
27118 gen_rtx_EXPR_LIST (VOIDmode,
27119 gen_rtx_REG (SImode,
27120 GP_ARG_RETURN + 1),
27122 gen_rtx_EXPR_LIST (VOIDmode,
27123 gen_rtx_REG (SImode,
27124 GP_ARG_RETURN + 2),
27126 gen_rtx_EXPR_LIST (VOIDmode,
27127 gen_rtx_REG (SImode,
27128 GP_ARG_RETURN + 3),
27132 mode = TYPE_MODE (valtype);
27133 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
27134 || POINTER_TYPE_P (valtype))
27135 mode = TARGET_32BIT ? SImode : DImode;
27137 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
27138 /* _Decimal128 must use an even/odd register pair. */
27139 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
27140 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
27141 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
27142 regno = FP_ARG_RETURN;
27143 else if (TREE_CODE (valtype) == COMPLEX_TYPE
27144 && targetm.calls.split_complex_arg)
27145 return rs6000_complex_function_value (mode);
27146 else if (TREE_CODE (valtype) == VECTOR_TYPE
27147 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
27148 && ALTIVEC_VECTOR_MODE (mode))
27149 regno = ALTIVEC_ARG_RETURN;
27150 else if (TREE_CODE (valtype) == VECTOR_TYPE
27151 && TARGET_VSX && TARGET_ALTIVEC_ABI
27152 && VSX_VECTOR_MODE (mode))
27153 regno = ALTIVEC_ARG_RETURN;
27154 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
27155 && (mode == DFmode || mode == DCmode
27156 || mode == TFmode || mode == TCmode))
27157 return spe_build_register_parallel (mode, GP_ARG_RETURN);
27159 regno = GP_ARG_RETURN;
27161 return gen_rtx_REG (mode, regno);
27164 /* Define how to find the value returned by a library function
27165 assuming the value has mode MODE. */
27167 rs6000_libcall_value (enum machine_mode mode)
27169 unsigned int regno;
27171 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
27173 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
27174 return gen_rtx_PARALLEL (DImode,
27176 gen_rtx_EXPR_LIST (VOIDmode,
27177 gen_rtx_REG (SImode, GP_ARG_RETURN),
27179 gen_rtx_EXPR_LIST (VOIDmode,
27180 gen_rtx_REG (SImode,
27181 GP_ARG_RETURN + 1),
27185 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
27186 /* _Decimal128 must use an even/odd register pair. */
27187 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
27188 else if (SCALAR_FLOAT_MODE_P (mode)
27189 && TARGET_HARD_FLOAT && TARGET_FPRS
27190 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
27191 regno = FP_ARG_RETURN;
27192 else if (ALTIVEC_VECTOR_MODE (mode)
27193 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
27194 regno = ALTIVEC_ARG_RETURN;
27195 else if (VSX_VECTOR_MODE (mode)
27196 && TARGET_VSX && TARGET_ALTIVEC_ABI)
27197 regno = ALTIVEC_ARG_RETURN;
27198 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
27199 return rs6000_complex_function_value (mode);
27200 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
27201 && (mode == DFmode || mode == DCmode
27202 || mode == TFmode || mode == TCmode))
27203 return spe_build_register_parallel (mode, GP_ARG_RETURN);
27205 regno = GP_ARG_RETURN;
27207 return gen_rtx_REG (mode, regno);
27211 /* Given FROM and TO register numbers, say whether this elimination is allowed.
27212 Frame pointer elimination is automatically handled.
27214 For the RS/6000, if frame pointer elimination is being done, we would like
27215 to convert ap into fp, not sp.
27217 We need r30 if -mminimal-toc was specified, and there are constant pool
27221 rs6000_can_eliminate (const int from, const int to)
27223 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
27224 ? ! frame_pointer_needed
27225 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
27226 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
27230 /* Define the offset between two registers, FROM to be eliminated and its
27231 replacement TO, at the start of a routine. */
27233 rs6000_initial_elimination_offset (int from, int to)
27235 rs6000_stack_t *info = rs6000_stack_info ();
27236 HOST_WIDE_INT offset;
27238 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
27239 offset = info->push_p ? 0 : -info->total_size;
27240 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
27242 offset = info->push_p ? 0 : -info->total_size;
27243 if (FRAME_GROWS_DOWNWARD)
27244 offset += info->fixed_size + info->vars_size + info->parm_size;
27246 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
27247 offset = FRAME_GROWS_DOWNWARD
27248 ? info->fixed_size + info->vars_size + info->parm_size
27250 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
27251 offset = info->total_size;
27252 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
27253 offset = info->push_p ? info->total_size : 0;
27254 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
27257 gcc_unreachable ();
27263 rs6000_dwarf_register_span (rtx reg)
27267 unsigned regno = REGNO (reg);
27268 enum machine_mode mode = GET_MODE (reg);
27272 && (SPE_VECTOR_MODE (GET_MODE (reg))
27273 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
27274 && mode != SFmode && mode != SDmode && mode != SCmode)))
27279 regno = REGNO (reg);
27281 /* The duality of the SPE register size wreaks all kinds of havoc.
27282 This is a way of distinguishing r0 in 32-bits from r0 in
27284 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
27285 gcc_assert (words <= 4);
27286 for (i = 0; i < words; i++, regno++)
27288 if (BYTES_BIG_ENDIAN)
27290 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
27291 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
27295 parts[2 * i] = gen_rtx_REG (SImode, regno);
27296 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
27300 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
27303 /* Fill in sizes for SPE register high parts in table used by unwinder. */
27306 rs6000_init_dwarf_reg_sizes_extra (tree address)
27311 enum machine_mode mode = TYPE_MODE (char_type_node);
27312 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
27313 rtx mem = gen_rtx_MEM (BLKmode, addr);
27314 rtx value = gen_int_mode (4, mode);
27316 for (i = 1201; i < 1232; i++)
27318 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
27319 HOST_WIDE_INT offset
27320 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
27322 emit_move_insn (adjust_address (mem, mode, offset), value);
27327 /* Map internal gcc register numbers to DWARF2 register numbers. */
27330 rs6000_dbx_register_number (unsigned int regno)
27332 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
27334 if (regno == MQ_REGNO)
27336 if (regno == LR_REGNO)
27338 if (regno == CTR_REGNO)
27340 if (CR_REGNO_P (regno))
27341 return regno - CR0_REGNO + 86;
27342 if (regno == CA_REGNO)
27343 return 101; /* XER */
27344 if (ALTIVEC_REGNO_P (regno))
27345 return regno - FIRST_ALTIVEC_REGNO + 1124;
27346 if (regno == VRSAVE_REGNO)
27348 if (regno == VSCR_REGNO)
27350 if (regno == SPE_ACC_REGNO)
27352 if (regno == SPEFSCR_REGNO)
27354 /* SPE high reg number. We get these values of regno from
27355 rs6000_dwarf_register_span. */
27356 gcc_assert (regno >= 1200 && regno < 1232);
27360 /* target hook eh_return_filter_mode */
27361 static enum machine_mode
27362 rs6000_eh_return_filter_mode (void)
27364 return TARGET_32BIT ? SImode : word_mode;
27367 /* Target hook for scalar_mode_supported_p. */
27369 rs6000_scalar_mode_supported_p (enum machine_mode mode)
27371 if (DECIMAL_FLOAT_MODE_P (mode))
27372 return default_decimal_float_supported_p ();
27374 return default_scalar_mode_supported_p (mode);
27377 /* Target hook for vector_mode_supported_p. */
27379 rs6000_vector_mode_supported_p (enum machine_mode mode)
27382 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
27385 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
27388 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
27395 /* Target hook for invalid_arg_for_unprototyped_fn. */
27396 static const char *
27397 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
27399 return (!rs6000_darwin64_abi
27401 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
27402 && (funcdecl == NULL_TREE
27403 || (TREE_CODE (funcdecl) == FUNCTION_DECL
27404 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
27405 ? N_("AltiVec argument passed to unprototyped function")
27409 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
27410 setup by using __stack_chk_fail_local hidden function instead of
27411 calling __stack_chk_fail directly. Otherwise it is better to call
27412 __stack_chk_fail directly. */
27415 rs6000_stack_protect_fail (void)
27417 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
27418 ? default_hidden_stack_protect_fail ()
27419 : default_external_stack_protect_fail ();
27423 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
27424 int num_operands ATTRIBUTE_UNUSED)
27426 if (rs6000_warn_cell_microcode)
27429 int insn_code_number = recog_memoized (insn);
27430 location_t location = locator_location (INSN_LOCATOR (insn));
27432 /* Punt on insns we cannot recognize. */
27433 if (insn_code_number < 0)
27436 temp = get_insn_template (insn_code_number, insn);
27438 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
27439 warning_at (location, OPT_mwarn_cell_microcode,
27440 "emitting microcode insn %s\t[%s] #%d",
27441 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27442 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
27443 warning_at (location, OPT_mwarn_cell_microcode,
27444 "emitting conditional microcode insn %s\t[%s] #%d",
27445 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27450 /* Mask options that we want to support inside of attribute((target)) and
27451 #pragma GCC target operations. Note, we do not include things like
27452 64/32-bit, endianess, hard/soft floating point, etc. that would have
27453 different calling sequences. */
27455 struct rs6000_opt_mask {
27456 const char *name; /* option name */
27457 int mask; /* mask to set */
27458 bool invert; /* invert sense of mask */
27459 bool valid_target; /* option is a target option */
27462 static struct rs6000_opt_mask const rs6000_opt_masks[] =
27464 { "altivec", MASK_ALTIVEC, false, true },
27465 { "cmpb", MASK_CMPB, false, true },
27466 { "dlmzb", MASK_DLMZB, false, true },
27467 { "fprnd", MASK_FPRND, false, true },
27468 { "hard-dfp", MASK_DFP, false, true },
27469 { "isel", MASK_ISEL, false, true },
27470 { "mfcrf", MASK_MFCRF, false, true },
27471 { "mfpgpr", MASK_MFPGPR, false, true },
27472 { "mulhw", MASK_MULHW, false, true },
27473 { "multiple", MASK_MULTIPLE, false, true },
27474 { "update", MASK_NO_UPDATE, true , true },
27475 { "popcntb", MASK_POPCNTB, false, true },
27476 { "popcntd", MASK_POPCNTD, false, true },
27477 { "powerpc-gfxopt", MASK_PPC_GFXOPT, false, true },
27478 { "powerpc-gpopt", MASK_PPC_GPOPT, false, true },
27479 { "recip-precision", MASK_RECIP_PRECISION, false, true },
27480 { "string", MASK_STRING, false, true },
27481 { "vsx", MASK_VSX, false, true },
27484 { "aix64", MASK_64BIT, false, false },
27485 { "aix32", MASK_64BIT, true, false },
27487 { "64", MASK_64BIT, false, false },
27488 { "32", MASK_64BIT, true, false },
27492 { "eabi", MASK_EABI, false, false },
27494 #ifdef MASK_LITTLE_ENDIAN
27495 { "little", MASK_LITTLE_ENDIAN, false, false },
27496 { "big", MASK_LITTLE_ENDIAN, true, false },
27498 #ifdef MASK_RELOCATABLE
27499 { "relocatable", MASK_RELOCATABLE, false, false },
27501 #ifdef MASK_STRICT_ALIGN
27502 { "strict-align", MASK_STRICT_ALIGN, false, false },
27504 { "power", MASK_POWER, false, false },
27505 { "power2", MASK_POWER2, false, false },
27506 { "powerpc", MASK_POWERPC, false, false },
27507 { "soft-float", MASK_SOFT_FLOAT, false, false },
27508 { "string", MASK_STRING, false, false },
27511 /* Option variables that we want to support inside attribute((target)) and
27512 #pragma GCC target operations. */
27514 struct rs6000_opt_var {
27515 const char *name; /* option name */
27516 size_t global_offset; /* offset of the option in global_options. */
27517 size_t target_offset; /* offset of the option in target optiosn. */
27520 static struct rs6000_opt_var const rs6000_opt_vars[] =
27523 offsetof (struct gcc_options, x_TARGET_FRIZ),
27524 offsetof (struct cl_target_option, x_TARGET_FRIZ), },
27525 { "avoid-indexed-addresses",
27526 offsetof (struct gcc_options, x_TARGET_AVOID_XFORM),
27527 offsetof (struct cl_target_option, x_TARGET_AVOID_XFORM) },
27529 offsetof (struct gcc_options, x_rs6000_paired_float),
27530 offsetof (struct cl_target_option, x_rs6000_paired_float), },
27532 offsetof (struct gcc_options, x_rs6000_default_long_calls),
27533 offsetof (struct cl_target_option, x_rs6000_default_long_calls), },
27536 /* Inner function to handle attribute((target("..."))) and #pragma GCC target
27537 parsing. Return true if there were no errors. */
27540 rs6000_inner_target_options (tree args, bool attr_p)
27544 if (args == NULL_TREE)
27547 else if (TREE_CODE (args) == STRING_CST)
27549 char *p = ASTRDUP (TREE_STRING_POINTER (args));
27552 while ((q = strtok (p, ",")) != NULL)
27554 bool error_p = false;
27555 bool not_valid_p = false;
27556 const char *cpu_opt = NULL;
27559 if (strncmp (q, "cpu=", 4) == 0)
27561 int cpu_index = rs6000_cpu_name_lookup (q+4);
27562 if (cpu_index >= 0)
27563 rs6000_cpu_index = cpu_index;
27570 else if (strncmp (q, "tune=", 5) == 0)
27572 int tune_index = rs6000_cpu_name_lookup (q+5);
27573 if (tune_index >= 0)
27574 rs6000_tune_index = tune_index;
27584 bool invert = false;
27588 if (strncmp (r, "no-", 3) == 0)
27594 for (i = 0; i < ARRAY_SIZE (rs6000_opt_masks); i++)
27595 if (strcmp (r, rs6000_opt_masks[i].name) == 0)
27597 int mask = rs6000_opt_masks[i].mask;
27599 if (!rs6000_opt_masks[i].valid_target)
27600 not_valid_p = true;
27604 target_flags_explicit |= mask;
27606 if (rs6000_opt_masks[i].invert)
27610 target_flags &= ~mask;
27612 target_flags |= mask;
27617 if (error_p && !not_valid_p)
27619 for (i = 0; i < ARRAY_SIZE (rs6000_opt_vars); i++)
27620 if (strcmp (r, rs6000_opt_vars[i].name) == 0)
27622 size_t j = rs6000_opt_vars[i].global_offset;
27623 ((int *) &global_options)[j] = !invert;
27632 const char *eprefix, *esuffix;
27637 eprefix = "__attribute__((__target__(";
27642 eprefix = "#pragma GCC target ";
27647 error ("invalid cpu \"%s\" for %s\"%s\"%s", cpu_opt, eprefix,
27649 else if (not_valid_p)
27650 error ("%s\"%s\"%s is not allowed", eprefix, q, esuffix);
27652 error ("%s\"%s\"%s is invalid", eprefix, q, esuffix);
27657 else if (TREE_CODE (args) == TREE_LIST)
27661 tree value = TREE_VALUE (args);
27664 bool ret2 = rs6000_inner_target_options (value, attr_p);
27668 args = TREE_CHAIN (args);
27670 while (args != NULL_TREE);
27674 gcc_unreachable ();
27679 /* Print out the target options as a list for -mdebug=target. */
27682 rs6000_debug_target_options (tree args, const char *prefix)
27684 if (args == NULL_TREE)
27685 fprintf (stderr, "%s<NULL>", prefix);
27687 else if (TREE_CODE (args) == STRING_CST)
27689 char *p = ASTRDUP (TREE_STRING_POINTER (args));
27692 while ((q = strtok (p, ",")) != NULL)
27695 fprintf (stderr, "%s\"%s\"", prefix, q);
27700 else if (TREE_CODE (args) == TREE_LIST)
27704 tree value = TREE_VALUE (args);
27707 rs6000_debug_target_options (value, prefix);
27710 args = TREE_CHAIN (args);
27712 while (args != NULL_TREE);
27716 gcc_unreachable ();
27722 /* Hook to validate attribute((target("..."))). */
27725 rs6000_valid_attribute_p (tree fndecl,
27726 tree ARG_UNUSED (name),
27730 struct cl_target_option cur_target;
27732 tree old_optimize = build_optimization_node ();
27733 tree new_target, new_optimize;
27734 tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
27736 gcc_assert ((fndecl != NULL_TREE) && (args != NULL_TREE));
27738 if (TARGET_DEBUG_TARGET)
27740 tree tname = DECL_NAME (fndecl);
27741 fprintf (stderr, "\n==================== rs6000_valid_attribute_p:\n");
27743 fprintf (stderr, "function: %.*s\n",
27744 (int) IDENTIFIER_LENGTH (tname),
27745 IDENTIFIER_POINTER (tname));
27747 fprintf (stderr, "function: unknown\n");
27749 fprintf (stderr, "args:");
27750 rs6000_debug_target_options (args, " ");
27751 fprintf (stderr, "\n");
27754 fprintf (stderr, "flags: 0x%x\n", flags);
27756 fprintf (stderr, "--------------------\n");
27759 old_optimize = build_optimization_node ();
27760 func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
27762 /* If the function changed the optimization levels as well as setting target
27763 options, start with the optimizations specified. */
27764 if (func_optimize && func_optimize != old_optimize)
27765 cl_optimization_restore (&global_options,
27766 TREE_OPTIMIZATION (func_optimize));
27768 /* The target attributes may also change some optimization flags, so update
27769 the optimization options if necessary. */
27770 cl_target_option_save (&cur_target, &global_options);
27771 rs6000_cpu_index = rs6000_tune_index = -1;
27772 ret = rs6000_inner_target_options (args, true);
27774 /* Set up any additional state. */
27777 ret = rs6000_option_override_internal (false);
27778 new_target = build_target_option_node ();
27783 new_optimize = build_optimization_node ();
27790 DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target;
27792 if (old_optimize != new_optimize)
27793 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
27796 cl_target_option_restore (&global_options, &cur_target);
27798 if (old_optimize != new_optimize)
27799 cl_optimization_restore (&global_options,
27800 TREE_OPTIMIZATION (old_optimize));
27806 /* Hook to validate the current #pragma GCC target and set the state, and
27807 update the macros based on what was changed. If ARGS is NULL, then
27808 POP_TARGET is used to reset the options. */
27811 rs6000_pragma_target_parse (tree args, tree pop_target)
27816 if (TARGET_DEBUG_TARGET)
27818 fprintf (stderr, "\n==================== rs6000_pragma_target_parse\n");
27819 fprintf (stderr, "args:");
27820 rs6000_debug_target_options (args, " ");
27821 fprintf (stderr, "\n");
27825 fprintf (stderr, "pop_target:\n");
27826 debug_tree (pop_target);
27829 fprintf (stderr, "pop_target: <NULL>\n");
27831 fprintf (stderr, "--------------------\n");
27837 cur_tree = ((pop_target)
27839 : target_option_default_node);
27840 cl_target_option_restore (&global_options,
27841 TREE_TARGET_OPTION (cur_tree));
27845 rs6000_cpu_index = rs6000_tune_index = -1;
27846 ret = rs6000_inner_target_options (args, false);
27847 cur_tree = build_target_option_node ();
27854 target_option_current_node = cur_tree;
27860 /* Remember the last target of rs6000_set_current_function. */
27861 static GTY(()) tree rs6000_previous_fndecl;
27863 /* Establish appropriate back-end context for processing the function
27864 FNDECL. The argument might be NULL to indicate processing at top
27865 level, outside of any function scope. */
27867 rs6000_set_current_function (tree fndecl)
27869 tree old_tree = (rs6000_previous_fndecl
27870 ? DECL_FUNCTION_SPECIFIC_TARGET (rs6000_previous_fndecl)
27873 tree new_tree = (fndecl
27874 ? DECL_FUNCTION_SPECIFIC_TARGET (fndecl)
27877 if (TARGET_DEBUG_TARGET)
27879 bool print_final = false;
27880 fprintf (stderr, "\n==================== rs6000_set_current_function");
27883 fprintf (stderr, ", fndecl %s (%p)",
27884 (DECL_NAME (fndecl)
27885 ? IDENTIFIER_POINTER (DECL_NAME (fndecl))
27886 : "<unknown>"), (void *)fndecl);
27888 if (rs6000_previous_fndecl)
27889 fprintf (stderr, ", prev_fndecl (%p)", (void *)rs6000_previous_fndecl);
27891 fprintf (stderr, "\n");
27894 fprintf (stderr, "\nnew fndecl target specific options:\n");
27895 debug_tree (new_tree);
27896 print_final = true;
27901 fprintf (stderr, "\nold fndecl target specific options:\n");
27902 debug_tree (old_tree);
27903 print_final = true;
27907 fprintf (stderr, "--------------------\n");
27910 /* Only change the context if the function changes. This hook is called
27911 several times in the course of compiling a function, and we don't want to
27912 slow things down too much or call target_reinit when it isn't safe. */
27913 if (fndecl && fndecl != rs6000_previous_fndecl)
27915 rs6000_previous_fndecl = fndecl;
27916 if (old_tree == new_tree)
27921 cl_target_option_restore (&global_options,
27922 TREE_TARGET_OPTION (new_tree));
27928 struct cl_target_option *def
27929 = TREE_TARGET_OPTION (target_option_current_node);
27931 cl_target_option_restore (&global_options, def);
27938 /* Save the current options */
27941 rs6000_function_specific_save (struct cl_target_option *ptr)
27943 ptr->rs6000_target_flags_explicit = target_flags_explicit;
27946 /* Restore the current options */
27949 rs6000_function_specific_restore (struct cl_target_option *ptr)
27951 target_flags_explicit = ptr->rs6000_target_flags_explicit;
27952 (void) rs6000_option_override_internal (false);
27955 /* Print the current options */
27958 rs6000_function_specific_print (FILE *file, int indent,
27959 struct cl_target_option *ptr)
27962 int flags = ptr->x_target_flags;
27964 /* Print the various mask options. */
27965 for (i = 0; i < ARRAY_SIZE (rs6000_opt_masks); i++)
27966 if ((flags & rs6000_opt_masks[i].mask) != 0)
27968 flags &= ~ rs6000_opt_masks[i].mask;
27969 fprintf (file, "%*s-m%s%s\n", indent, "",
27970 rs6000_opt_masks[i].invert ? "no-" : "",
27971 rs6000_opt_masks[i].name);
27974 /* Print the various options that are variables. */
27975 for (i = 0; i < ARRAY_SIZE (rs6000_opt_vars); i++)
27977 size_t j = rs6000_opt_vars[i].target_offset;
27978 if (((signed char *) ptr)[j])
27979 fprintf (file, "%*s-m%s\n", indent, "",
27980 rs6000_opt_vars[i].name);
27985 /* Hook to determine if one function can safely inline another. */
27988 rs6000_can_inline_p (tree caller, tree callee)
27991 tree caller_tree = DECL_FUNCTION_SPECIFIC_TARGET (caller);
27992 tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (callee);
27994 /* If callee has no option attributes, then it is ok to inline. */
27998 /* If caller has no option attributes, but callee does then it is not ok to
28000 else if (!caller_tree)
28005 struct cl_target_option *caller_opts = TREE_TARGET_OPTION (caller_tree);
28006 struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree);
28008 /* Callee's options should a subset of the caller's, i.e. a vsx function
28009 can inline an altivec function but a non-vsx function can't inline a
28011 if ((caller_opts->x_target_flags & callee_opts->x_target_flags)
28012 == callee_opts->x_target_flags)
28016 if (TARGET_DEBUG_TARGET)
28017 fprintf (stderr, "rs6000_can_inline_p:, caller %s, callee %s, %s inline\n",
28018 (DECL_NAME (caller)
28019 ? IDENTIFIER_POINTER (DECL_NAME (caller))
28021 (DECL_NAME (callee)
28022 ? IDENTIFIER_POINTER (DECL_NAME (callee))
28024 (ret ? "can" : "cannot"));
28029 /* Allocate a stack temp and fixup the address so it meets the particular
28030 memory requirements (either offetable or REG+REG addressing). */
28033 rs6000_allocate_stack_temp (enum machine_mode mode,
28034 bool offsettable_p,
28037 rtx stack = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
28038 rtx addr = XEXP (stack, 0);
28039 int strict_p = (reload_in_progress || reload_completed);
28041 if (!legitimate_indirect_address_p (addr, strict_p))
28044 && !rs6000_legitimate_offset_address_p (mode, addr, strict_p))
28045 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
28047 else if (reg_reg_p && !legitimate_indexed_address_p (addr, strict_p))
28048 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
28054 /* Given a memory reference, if it is not a reg or reg+reg addressing, convert
28055 to such a form to deal with memory reference instructions like STFIWX that
28056 only take reg+reg addressing. */
28059 rs6000_address_for_fpconvert (rtx x)
28061 int strict_p = (reload_in_progress || reload_completed);
28064 gcc_assert (MEM_P (x));
28065 addr = XEXP (x, 0);
28066 if (! legitimate_indirect_address_p (addr, strict_p)
28067 && ! legitimate_indexed_address_p (addr, strict_p))
28069 if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)
28071 rtx reg = XEXP (addr, 0);
28072 HOST_WIDE_INT size = GET_MODE_SIZE (GET_MODE (x));
28073 rtx size_rtx = GEN_INT ((GET_CODE (addr) == PRE_DEC) ? -size : size);
28074 gcc_assert (REG_P (reg));
28075 emit_insn (gen_add3_insn (reg, reg, size_rtx));
28078 else if (GET_CODE (addr) == PRE_MODIFY)
28080 rtx reg = XEXP (addr, 0);
28081 rtx expr = XEXP (addr, 1);
28082 gcc_assert (REG_P (reg));
28083 gcc_assert (GET_CODE (expr) == PLUS);
28084 emit_insn (gen_add3_insn (reg, XEXP (expr, 0), XEXP (expr, 1)));
28088 x = replace_equiv_address (x, copy_addr_to_reg (addr));
28094 /* Given a memory reference, if it is not in the form for altivec memory
28095 reference instructions (i.e. reg or reg+reg addressing with AND of -16),
28096 convert to the altivec format. */
28099 rs6000_address_for_altivec (rtx x)
28101 gcc_assert (MEM_P (x));
28102 if (!altivec_indexed_or_indirect_operand (x, GET_MODE (x)))
28104 rtx addr = XEXP (x, 0);
28105 int strict_p = (reload_in_progress || reload_completed);
28107 if (!legitimate_indexed_address_p (addr, strict_p)
28108 && !legitimate_indirect_address_p (addr, strict_p))
28109 addr = copy_to_mode_reg (Pmode, addr);
28111 addr = gen_rtx_AND (Pmode, addr, GEN_INT (-16));
28112 x = change_address (x, GET_MODE (x), addr);
28119 #include "gt-rs6000.h"