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 "common/common-target.h"
52 #include "langhooks.h"
54 #include "cfglayout.h"
56 #include "sched-int.h"
58 #include "tree-flow.h"
61 #include "tm-constrs.h"
64 #include "xcoffout.h" /* get declarations of xcoff_*_section_name */
67 #include "gstab.h" /* for N_SLINE */
70 #ifndef TARGET_NO_PROTOTYPE
71 #define TARGET_NO_PROTOTYPE 0
74 #define min(A,B) ((A) < (B) ? (A) : (B))
75 #define max(A,B) ((A) > (B) ? (A) : (B))
77 /* Structure used to define the rs6000 stack */
78 typedef struct rs6000_stack {
79 int reload_completed; /* stack info won't change from here on */
80 int first_gp_reg_save; /* first callee saved GP register used */
81 int first_fp_reg_save; /* first callee saved FP register used */
82 int first_altivec_reg_save; /* first callee saved AltiVec register used */
83 int lr_save_p; /* true if the link reg needs to be saved */
84 int cr_save_p; /* true if the CR reg needs to be saved */
85 unsigned int vrsave_mask; /* mask of vec registers to save */
86 int push_p; /* true if we need to allocate stack space */
87 int calls_p; /* true if the function makes any calls */
88 int world_save_p; /* true if we're saving *everything*:
89 r13-r31, cr, f14-f31, vrsave, v20-v31 */
90 enum rs6000_abi abi; /* which ABI to use */
91 int gp_save_offset; /* offset to save GP regs from initial SP */
92 int fp_save_offset; /* offset to save FP regs from initial SP */
93 int altivec_save_offset; /* offset to save AltiVec regs from initial SP */
94 int lr_save_offset; /* offset to save LR from initial SP */
95 int cr_save_offset; /* offset to save CR from initial SP */
96 int vrsave_save_offset; /* offset to save VRSAVE from initial SP */
97 int spe_gp_save_offset; /* offset to save spe 64-bit gprs */
98 int varargs_save_offset; /* offset to save the varargs registers */
99 int ehrd_offset; /* offset to EH return data */
100 int reg_size; /* register size (4 or 8) */
101 HOST_WIDE_INT vars_size; /* variable save area size */
102 int parm_size; /* outgoing parameter size */
103 int save_size; /* save area size */
104 int fixed_size; /* fixed size of stack frame */
105 int gp_size; /* size of saved GP registers */
106 int fp_size; /* size of saved FP registers */
107 int altivec_size; /* size of saved AltiVec registers */
108 int cr_size; /* size to hold CR if not in save_size */
109 int vrsave_size; /* size to hold VRSAVE if not in save_size */
110 int altivec_padding_size; /* size of altivec alignment padding if
112 int spe_gp_size; /* size of 64-bit GPR save size for SPE */
113 int spe_padding_size;
114 HOST_WIDE_INT total_size; /* total bytes allocated for stack */
115 int spe_64bit_regs_used;
119 /* A C structure for machine-specific, per-function data.
120 This is added to the cfun structure. */
121 typedef struct GTY(()) machine_function
123 /* Some local-dynamic symbol. */
124 const char *some_ld_name;
125 /* Whether the instruction chain has been scanned already. */
126 int insn_chain_scanned_p;
127 /* Flags if __builtin_return_address (n) with n >= 1 was used. */
128 int ra_needs_full_frame;
129 /* Flags if __builtin_return_address (0) was used. */
131 /* Cache lr_save_p after expansion of builtin_eh_return. */
133 /* Whether we need to save the TOC to the reserved stack location in the
134 function prologue. */
135 bool save_toc_in_prologue;
136 /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4
137 varargs save area. */
138 HOST_WIDE_INT varargs_save_offset;
139 /* Temporary stack slot to use for SDmode copies. This slot is
140 64-bits wide and is allocated early enough so that the offset
141 does not overflow the 16-bit load/store offset field. */
142 rtx sdmode_stack_slot;
145 /* Support targetm.vectorize.builtin_mask_for_load. */
146 static GTY(()) tree altivec_builtin_mask_for_load;
148 /* Set to nonzero once AIX common-mode calls have been defined. */
149 static GTY(()) int common_mode_defined;
151 /* Label number of label created for -mrelocatable, to call to so we can
152 get the address of the GOT section */
153 static int rs6000_pic_labelno;
156 /* Counter for labels which are to be placed in .fixup. */
157 int fixuplabelno = 0;
160 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
163 /* Specify the machine mode that pointers have. After generation of rtl, the
164 compiler makes no further distinction between pointers and any other objects
165 of this machine mode. The type is unsigned since not all things that
166 include rs6000.h also include machmode.h. */
167 unsigned rs6000_pmode;
169 /* Width in bits of a pointer. */
170 unsigned rs6000_pointer_size;
172 #ifdef HAVE_AS_GNU_ATTRIBUTE
173 /* Flag whether floating point values have been passed/returned. */
174 static bool rs6000_passes_float;
175 /* Flag whether vector values have been passed/returned. */
176 static bool rs6000_passes_vector;
177 /* Flag whether small (<= 8 byte) structures have been returned. */
178 static bool rs6000_returns_struct;
181 /* Value is TRUE if register/mode pair is acceptable. */
182 bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
184 /* Maximum number of registers needed for a given register class and mode. */
185 unsigned char rs6000_class_max_nregs[NUM_MACHINE_MODES][LIM_REG_CLASSES];
187 /* How many registers are needed for a given register and mode. */
188 unsigned char rs6000_hard_regno_nregs[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
190 /* Map register number to register class. */
191 enum reg_class rs6000_regno_regclass[FIRST_PSEUDO_REGISTER];
193 /* Reload functions based on the type and the vector unit. */
194 static enum insn_code rs6000_vector_reload[NUM_MACHINE_MODES][2];
196 static int dbg_cost_ctrl;
198 /* Built in types. */
199 tree rs6000_builtin_types[RS6000_BTI_MAX];
200 tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
202 /* Flag to say the TOC is initialized */
204 char toc_label_name[10];
206 /* Cached value of rs6000_variable_issue. This is cached in
207 rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */
208 static short cached_can_issue_more;
210 static GTY(()) section *read_only_data_section;
211 static GTY(()) section *private_data_section;
212 static GTY(()) section *read_only_private_data_section;
213 static GTY(()) section *sdata2_section;
214 static GTY(()) section *toc_section;
216 struct builtin_description
218 /* mask is not const because we're going to alter it below. This
219 nonsense will go away when we rewrite the -march infrastructure
220 to give us more target flag bits. */
222 const enum insn_code icode;
223 const char *const name;
224 const enum rs6000_builtins code;
227 /* Describe the vector unit used for modes. */
228 enum rs6000_vector rs6000_vector_unit[NUM_MACHINE_MODES];
229 enum rs6000_vector rs6000_vector_mem[NUM_MACHINE_MODES];
231 /* Register classes for various constraints that are based on the target
233 enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX];
235 /* Describe the alignment of a vector. */
236 int rs6000_vector_align[NUM_MACHINE_MODES];
238 /* Map selected modes to types for builtins. */
239 static GTY(()) tree builtin_mode_to_type[MAX_MACHINE_MODE][2];
241 /* What modes to automatically generate reciprocal divide estimate (fre) and
242 reciprocal sqrt (frsqrte) for. */
243 unsigned char rs6000_recip_bits[MAX_MACHINE_MODE];
245 /* Masks to determine which reciprocal esitmate instructions to generate
247 enum rs6000_recip_mask {
248 RECIP_SF_DIV = 0x001, /* Use divide estimate */
249 RECIP_DF_DIV = 0x002,
250 RECIP_V4SF_DIV = 0x004,
251 RECIP_V2DF_DIV = 0x008,
253 RECIP_SF_RSQRT = 0x010, /* Use reciprocal sqrt estimate. */
254 RECIP_DF_RSQRT = 0x020,
255 RECIP_V4SF_RSQRT = 0x040,
256 RECIP_V2DF_RSQRT = 0x080,
258 /* Various combination of flags for -mrecip=xxx. */
260 RECIP_ALL = (RECIP_SF_DIV | RECIP_DF_DIV | RECIP_V4SF_DIV
261 | RECIP_V2DF_DIV | RECIP_SF_RSQRT | RECIP_DF_RSQRT
262 | RECIP_V4SF_RSQRT | RECIP_V2DF_RSQRT),
264 RECIP_HIGH_PRECISION = RECIP_ALL,
266 /* On low precision machines like the power5, don't enable double precision
267 reciprocal square root estimate, since it isn't accurate enough. */
268 RECIP_LOW_PRECISION = (RECIP_ALL & ~(RECIP_DF_RSQRT | RECIP_V2DF_RSQRT))
271 /* -mrecip options. */
274 const char *string; /* option name */
275 unsigned int mask; /* mask bits to set */
276 } recip_options[] = {
277 { "all", RECIP_ALL },
278 { "none", RECIP_NONE },
279 { "div", (RECIP_SF_DIV | RECIP_DF_DIV | RECIP_V4SF_DIV
281 { "divf", (RECIP_SF_DIV | RECIP_V4SF_DIV) },
282 { "divd", (RECIP_DF_DIV | RECIP_V2DF_DIV) },
283 { "rsqrt", (RECIP_SF_RSQRT | RECIP_DF_RSQRT | RECIP_V4SF_RSQRT
284 | RECIP_V2DF_RSQRT) },
285 { "rsqrtf", (RECIP_SF_RSQRT | RECIP_V4SF_RSQRT) },
286 { "rsqrtd", (RECIP_DF_RSQRT | RECIP_V2DF_RSQRT) },
289 /* 2 argument gen function typedef. */
290 typedef rtx (*gen_2arg_fn_t) (rtx, rtx, rtx);
293 /* Target cpu costs. */
295 struct processor_costs {
296 const int mulsi; /* cost of SImode multiplication. */
297 const int mulsi_const; /* cost of SImode multiplication by constant. */
298 const int mulsi_const9; /* cost of SImode mult by short constant. */
299 const int muldi; /* cost of DImode multiplication. */
300 const int divsi; /* cost of SImode division. */
301 const int divdi; /* cost of DImode division. */
302 const int fp; /* cost of simple SFmode and DFmode insns. */
303 const int dmul; /* cost of DFmode multiplication (and fmadd). */
304 const int sdiv; /* cost of SFmode division (fdivs). */
305 const int ddiv; /* cost of DFmode division (fdiv). */
306 const int cache_line_size; /* cache line size in bytes. */
307 const int l1_cache_size; /* size of l1 cache, in kilobytes. */
308 const int l2_cache_size; /* size of l2 cache, in kilobytes. */
309 const int simultaneous_prefetches; /* number of parallel prefetch
313 const struct processor_costs *rs6000_cost;
315 /* Processor costs (relative to an add) */
317 /* Instruction size costs on 32bit processors. */
319 struct processor_costs size32_cost = {
320 COSTS_N_INSNS (1), /* mulsi */
321 COSTS_N_INSNS (1), /* mulsi_const */
322 COSTS_N_INSNS (1), /* mulsi_const9 */
323 COSTS_N_INSNS (1), /* muldi */
324 COSTS_N_INSNS (1), /* divsi */
325 COSTS_N_INSNS (1), /* divdi */
326 COSTS_N_INSNS (1), /* fp */
327 COSTS_N_INSNS (1), /* dmul */
328 COSTS_N_INSNS (1), /* sdiv */
329 COSTS_N_INSNS (1), /* ddiv */
336 /* Instruction size costs on 64bit processors. */
338 struct processor_costs size64_cost = {
339 COSTS_N_INSNS (1), /* mulsi */
340 COSTS_N_INSNS (1), /* mulsi_const */
341 COSTS_N_INSNS (1), /* mulsi_const9 */
342 COSTS_N_INSNS (1), /* muldi */
343 COSTS_N_INSNS (1), /* divsi */
344 COSTS_N_INSNS (1), /* divdi */
345 COSTS_N_INSNS (1), /* fp */
346 COSTS_N_INSNS (1), /* dmul */
347 COSTS_N_INSNS (1), /* sdiv */
348 COSTS_N_INSNS (1), /* ddiv */
355 /* Instruction costs on RIOS1 processors. */
357 struct processor_costs rios1_cost = {
358 COSTS_N_INSNS (5), /* mulsi */
359 COSTS_N_INSNS (4), /* mulsi_const */
360 COSTS_N_INSNS (3), /* mulsi_const9 */
361 COSTS_N_INSNS (5), /* muldi */
362 COSTS_N_INSNS (19), /* divsi */
363 COSTS_N_INSNS (19), /* divdi */
364 COSTS_N_INSNS (2), /* fp */
365 COSTS_N_INSNS (2), /* dmul */
366 COSTS_N_INSNS (19), /* sdiv */
367 COSTS_N_INSNS (19), /* ddiv */
368 128, /* cache line size */
374 /* Instruction costs on RIOS2 processors. */
376 struct processor_costs rios2_cost = {
377 COSTS_N_INSNS (2), /* mulsi */
378 COSTS_N_INSNS (2), /* mulsi_const */
379 COSTS_N_INSNS (2), /* mulsi_const9 */
380 COSTS_N_INSNS (2), /* muldi */
381 COSTS_N_INSNS (13), /* divsi */
382 COSTS_N_INSNS (13), /* divdi */
383 COSTS_N_INSNS (2), /* fp */
384 COSTS_N_INSNS (2), /* dmul */
385 COSTS_N_INSNS (17), /* sdiv */
386 COSTS_N_INSNS (17), /* ddiv */
387 256, /* cache line size */
393 /* Instruction costs on RS64A processors. */
395 struct processor_costs rs64a_cost = {
396 COSTS_N_INSNS (20), /* mulsi */
397 COSTS_N_INSNS (12), /* mulsi_const */
398 COSTS_N_INSNS (8), /* mulsi_const9 */
399 COSTS_N_INSNS (34), /* muldi */
400 COSTS_N_INSNS (65), /* divsi */
401 COSTS_N_INSNS (67), /* divdi */
402 COSTS_N_INSNS (4), /* fp */
403 COSTS_N_INSNS (4), /* dmul */
404 COSTS_N_INSNS (31), /* sdiv */
405 COSTS_N_INSNS (31), /* ddiv */
406 128, /* cache line size */
412 /* Instruction costs on MPCCORE processors. */
414 struct processor_costs mpccore_cost = {
415 COSTS_N_INSNS (2), /* mulsi */
416 COSTS_N_INSNS (2), /* mulsi_const */
417 COSTS_N_INSNS (2), /* mulsi_const9 */
418 COSTS_N_INSNS (2), /* muldi */
419 COSTS_N_INSNS (6), /* divsi */
420 COSTS_N_INSNS (6), /* divdi */
421 COSTS_N_INSNS (4), /* fp */
422 COSTS_N_INSNS (5), /* dmul */
423 COSTS_N_INSNS (10), /* sdiv */
424 COSTS_N_INSNS (17), /* ddiv */
425 32, /* cache line size */
431 /* Instruction costs on PPC403 processors. */
433 struct processor_costs ppc403_cost = {
434 COSTS_N_INSNS (4), /* mulsi */
435 COSTS_N_INSNS (4), /* mulsi_const */
436 COSTS_N_INSNS (4), /* mulsi_const9 */
437 COSTS_N_INSNS (4), /* muldi */
438 COSTS_N_INSNS (33), /* divsi */
439 COSTS_N_INSNS (33), /* divdi */
440 COSTS_N_INSNS (11), /* fp */
441 COSTS_N_INSNS (11), /* dmul */
442 COSTS_N_INSNS (11), /* sdiv */
443 COSTS_N_INSNS (11), /* ddiv */
444 32, /* cache line size */
450 /* Instruction costs on PPC405 processors. */
452 struct processor_costs ppc405_cost = {
453 COSTS_N_INSNS (5), /* mulsi */
454 COSTS_N_INSNS (4), /* mulsi_const */
455 COSTS_N_INSNS (3), /* mulsi_const9 */
456 COSTS_N_INSNS (5), /* muldi */
457 COSTS_N_INSNS (35), /* divsi */
458 COSTS_N_INSNS (35), /* divdi */
459 COSTS_N_INSNS (11), /* fp */
460 COSTS_N_INSNS (11), /* dmul */
461 COSTS_N_INSNS (11), /* sdiv */
462 COSTS_N_INSNS (11), /* ddiv */
463 32, /* cache line size */
469 /* Instruction costs on PPC440 processors. */
471 struct processor_costs ppc440_cost = {
472 COSTS_N_INSNS (3), /* mulsi */
473 COSTS_N_INSNS (2), /* mulsi_const */
474 COSTS_N_INSNS (2), /* mulsi_const9 */
475 COSTS_N_INSNS (3), /* muldi */
476 COSTS_N_INSNS (34), /* divsi */
477 COSTS_N_INSNS (34), /* divdi */
478 COSTS_N_INSNS (5), /* fp */
479 COSTS_N_INSNS (5), /* dmul */
480 COSTS_N_INSNS (19), /* sdiv */
481 COSTS_N_INSNS (33), /* ddiv */
482 32, /* cache line size */
488 /* Instruction costs on PPC476 processors. */
490 struct processor_costs ppc476_cost = {
491 COSTS_N_INSNS (4), /* mulsi */
492 COSTS_N_INSNS (4), /* mulsi_const */
493 COSTS_N_INSNS (4), /* mulsi_const9 */
494 COSTS_N_INSNS (4), /* muldi */
495 COSTS_N_INSNS (11), /* divsi */
496 COSTS_N_INSNS (11), /* divdi */
497 COSTS_N_INSNS (6), /* fp */
498 COSTS_N_INSNS (6), /* dmul */
499 COSTS_N_INSNS (19), /* sdiv */
500 COSTS_N_INSNS (33), /* ddiv */
501 32, /* l1 cache line size */
507 /* Instruction costs on PPC601 processors. */
509 struct processor_costs ppc601_cost = {
510 COSTS_N_INSNS (5), /* mulsi */
511 COSTS_N_INSNS (5), /* mulsi_const */
512 COSTS_N_INSNS (5), /* mulsi_const9 */
513 COSTS_N_INSNS (5), /* muldi */
514 COSTS_N_INSNS (36), /* divsi */
515 COSTS_N_INSNS (36), /* divdi */
516 COSTS_N_INSNS (4), /* fp */
517 COSTS_N_INSNS (5), /* dmul */
518 COSTS_N_INSNS (17), /* sdiv */
519 COSTS_N_INSNS (31), /* ddiv */
520 32, /* cache line size */
526 /* Instruction costs on PPC603 processors. */
528 struct processor_costs ppc603_cost = {
529 COSTS_N_INSNS (5), /* mulsi */
530 COSTS_N_INSNS (3), /* mulsi_const */
531 COSTS_N_INSNS (2), /* mulsi_const9 */
532 COSTS_N_INSNS (5), /* muldi */
533 COSTS_N_INSNS (37), /* divsi */
534 COSTS_N_INSNS (37), /* divdi */
535 COSTS_N_INSNS (3), /* fp */
536 COSTS_N_INSNS (4), /* dmul */
537 COSTS_N_INSNS (18), /* sdiv */
538 COSTS_N_INSNS (33), /* ddiv */
539 32, /* cache line size */
545 /* Instruction costs on PPC604 processors. */
547 struct processor_costs ppc604_cost = {
548 COSTS_N_INSNS (4), /* mulsi */
549 COSTS_N_INSNS (4), /* mulsi_const */
550 COSTS_N_INSNS (4), /* mulsi_const9 */
551 COSTS_N_INSNS (4), /* muldi */
552 COSTS_N_INSNS (20), /* divsi */
553 COSTS_N_INSNS (20), /* divdi */
554 COSTS_N_INSNS (3), /* fp */
555 COSTS_N_INSNS (3), /* dmul */
556 COSTS_N_INSNS (18), /* sdiv */
557 COSTS_N_INSNS (32), /* ddiv */
558 32, /* cache line size */
564 /* Instruction costs on PPC604e processors. */
566 struct processor_costs ppc604e_cost = {
567 COSTS_N_INSNS (2), /* mulsi */
568 COSTS_N_INSNS (2), /* mulsi_const */
569 COSTS_N_INSNS (2), /* mulsi_const9 */
570 COSTS_N_INSNS (2), /* muldi */
571 COSTS_N_INSNS (20), /* divsi */
572 COSTS_N_INSNS (20), /* divdi */
573 COSTS_N_INSNS (3), /* fp */
574 COSTS_N_INSNS (3), /* dmul */
575 COSTS_N_INSNS (18), /* sdiv */
576 COSTS_N_INSNS (32), /* ddiv */
577 32, /* cache line size */
583 /* Instruction costs on PPC620 processors. */
585 struct processor_costs ppc620_cost = {
586 COSTS_N_INSNS (5), /* mulsi */
587 COSTS_N_INSNS (4), /* mulsi_const */
588 COSTS_N_INSNS (3), /* mulsi_const9 */
589 COSTS_N_INSNS (7), /* muldi */
590 COSTS_N_INSNS (21), /* divsi */
591 COSTS_N_INSNS (37), /* divdi */
592 COSTS_N_INSNS (3), /* fp */
593 COSTS_N_INSNS (3), /* dmul */
594 COSTS_N_INSNS (18), /* sdiv */
595 COSTS_N_INSNS (32), /* ddiv */
596 128, /* cache line size */
602 /* Instruction costs on PPC630 processors. */
604 struct processor_costs ppc630_cost = {
605 COSTS_N_INSNS (5), /* mulsi */
606 COSTS_N_INSNS (4), /* mulsi_const */
607 COSTS_N_INSNS (3), /* mulsi_const9 */
608 COSTS_N_INSNS (7), /* muldi */
609 COSTS_N_INSNS (21), /* divsi */
610 COSTS_N_INSNS (37), /* divdi */
611 COSTS_N_INSNS (3), /* fp */
612 COSTS_N_INSNS (3), /* dmul */
613 COSTS_N_INSNS (17), /* sdiv */
614 COSTS_N_INSNS (21), /* ddiv */
615 128, /* cache line size */
621 /* Instruction costs on Cell processor. */
622 /* COSTS_N_INSNS (1) ~ one add. */
624 struct processor_costs ppccell_cost = {
625 COSTS_N_INSNS (9/2)+2, /* mulsi */
626 COSTS_N_INSNS (6/2), /* mulsi_const */
627 COSTS_N_INSNS (6/2), /* mulsi_const9 */
628 COSTS_N_INSNS (15/2)+2, /* muldi */
629 COSTS_N_INSNS (38/2), /* divsi */
630 COSTS_N_INSNS (70/2), /* divdi */
631 COSTS_N_INSNS (10/2), /* fp */
632 COSTS_N_INSNS (10/2), /* dmul */
633 COSTS_N_INSNS (74/2), /* sdiv */
634 COSTS_N_INSNS (74/2), /* ddiv */
635 128, /* cache line size */
641 /* Instruction costs on PPC750 and PPC7400 processors. */
643 struct processor_costs ppc750_cost = {
644 COSTS_N_INSNS (5), /* mulsi */
645 COSTS_N_INSNS (3), /* mulsi_const */
646 COSTS_N_INSNS (2), /* mulsi_const9 */
647 COSTS_N_INSNS (5), /* muldi */
648 COSTS_N_INSNS (17), /* divsi */
649 COSTS_N_INSNS (17), /* divdi */
650 COSTS_N_INSNS (3), /* fp */
651 COSTS_N_INSNS (3), /* dmul */
652 COSTS_N_INSNS (17), /* sdiv */
653 COSTS_N_INSNS (31), /* ddiv */
654 32, /* cache line size */
660 /* Instruction costs on PPC7450 processors. */
662 struct processor_costs ppc7450_cost = {
663 COSTS_N_INSNS (4), /* mulsi */
664 COSTS_N_INSNS (3), /* mulsi_const */
665 COSTS_N_INSNS (3), /* mulsi_const9 */
666 COSTS_N_INSNS (4), /* muldi */
667 COSTS_N_INSNS (23), /* divsi */
668 COSTS_N_INSNS (23), /* divdi */
669 COSTS_N_INSNS (5), /* fp */
670 COSTS_N_INSNS (5), /* dmul */
671 COSTS_N_INSNS (21), /* sdiv */
672 COSTS_N_INSNS (35), /* ddiv */
673 32, /* cache line size */
679 /* Instruction costs on PPC8540 processors. */
681 struct processor_costs ppc8540_cost = {
682 COSTS_N_INSNS (4), /* mulsi */
683 COSTS_N_INSNS (4), /* mulsi_const */
684 COSTS_N_INSNS (4), /* mulsi_const9 */
685 COSTS_N_INSNS (4), /* muldi */
686 COSTS_N_INSNS (19), /* divsi */
687 COSTS_N_INSNS (19), /* divdi */
688 COSTS_N_INSNS (4), /* fp */
689 COSTS_N_INSNS (4), /* dmul */
690 COSTS_N_INSNS (29), /* sdiv */
691 COSTS_N_INSNS (29), /* ddiv */
692 32, /* cache line size */
695 1, /* prefetch streams /*/
698 /* Instruction costs on E300C2 and E300C3 cores. */
700 struct processor_costs ppce300c2c3_cost = {
701 COSTS_N_INSNS (4), /* mulsi */
702 COSTS_N_INSNS (4), /* mulsi_const */
703 COSTS_N_INSNS (4), /* mulsi_const9 */
704 COSTS_N_INSNS (4), /* muldi */
705 COSTS_N_INSNS (19), /* divsi */
706 COSTS_N_INSNS (19), /* divdi */
707 COSTS_N_INSNS (3), /* fp */
708 COSTS_N_INSNS (4), /* dmul */
709 COSTS_N_INSNS (18), /* sdiv */
710 COSTS_N_INSNS (33), /* ddiv */
714 1, /* prefetch streams /*/
717 /* Instruction costs on PPCE500MC processors. */
719 struct processor_costs ppce500mc_cost = {
720 COSTS_N_INSNS (4), /* mulsi */
721 COSTS_N_INSNS (4), /* mulsi_const */
722 COSTS_N_INSNS (4), /* mulsi_const9 */
723 COSTS_N_INSNS (4), /* muldi */
724 COSTS_N_INSNS (14), /* divsi */
725 COSTS_N_INSNS (14), /* divdi */
726 COSTS_N_INSNS (8), /* fp */
727 COSTS_N_INSNS (10), /* dmul */
728 COSTS_N_INSNS (36), /* sdiv */
729 COSTS_N_INSNS (66), /* ddiv */
730 64, /* cache line size */
733 1, /* prefetch streams /*/
736 /* Instruction costs on PPCE500MC64 processors. */
738 struct processor_costs ppce500mc64_cost = {
739 COSTS_N_INSNS (4), /* mulsi */
740 COSTS_N_INSNS (4), /* mulsi_const */
741 COSTS_N_INSNS (4), /* mulsi_const9 */
742 COSTS_N_INSNS (4), /* muldi */
743 COSTS_N_INSNS (14), /* divsi */
744 COSTS_N_INSNS (14), /* divdi */
745 COSTS_N_INSNS (4), /* fp */
746 COSTS_N_INSNS (10), /* dmul */
747 COSTS_N_INSNS (36), /* sdiv */
748 COSTS_N_INSNS (66), /* ddiv */
749 64, /* cache line size */
752 1, /* prefetch streams /*/
755 /* Instruction costs on AppliedMicro Titan processors. */
757 struct processor_costs titan_cost = {
758 COSTS_N_INSNS (5), /* mulsi */
759 COSTS_N_INSNS (5), /* mulsi_const */
760 COSTS_N_INSNS (5), /* mulsi_const9 */
761 COSTS_N_INSNS (5), /* muldi */
762 COSTS_N_INSNS (18), /* divsi */
763 COSTS_N_INSNS (18), /* divdi */
764 COSTS_N_INSNS (10), /* fp */
765 COSTS_N_INSNS (10), /* dmul */
766 COSTS_N_INSNS (46), /* sdiv */
767 COSTS_N_INSNS (72), /* ddiv */
768 32, /* cache line size */
771 1, /* prefetch streams /*/
774 /* Instruction costs on POWER4 and POWER5 processors. */
776 struct processor_costs power4_cost = {
777 COSTS_N_INSNS (3), /* mulsi */
778 COSTS_N_INSNS (2), /* mulsi_const */
779 COSTS_N_INSNS (2), /* mulsi_const9 */
780 COSTS_N_INSNS (4), /* muldi */
781 COSTS_N_INSNS (18), /* divsi */
782 COSTS_N_INSNS (34), /* divdi */
783 COSTS_N_INSNS (3), /* fp */
784 COSTS_N_INSNS (3), /* dmul */
785 COSTS_N_INSNS (17), /* sdiv */
786 COSTS_N_INSNS (17), /* ddiv */
787 128, /* cache line size */
790 8, /* prefetch streams /*/
793 /* Instruction costs on POWER6 processors. */
795 struct processor_costs power6_cost = {
796 COSTS_N_INSNS (8), /* mulsi */
797 COSTS_N_INSNS (8), /* mulsi_const */
798 COSTS_N_INSNS (8), /* mulsi_const9 */
799 COSTS_N_INSNS (8), /* muldi */
800 COSTS_N_INSNS (22), /* divsi */
801 COSTS_N_INSNS (28), /* divdi */
802 COSTS_N_INSNS (3), /* fp */
803 COSTS_N_INSNS (3), /* dmul */
804 COSTS_N_INSNS (13), /* sdiv */
805 COSTS_N_INSNS (16), /* ddiv */
806 128, /* cache line size */
809 16, /* prefetch streams */
812 /* Instruction costs on POWER7 processors. */
814 struct processor_costs power7_cost = {
815 COSTS_N_INSNS (2), /* mulsi */
816 COSTS_N_INSNS (2), /* mulsi_const */
817 COSTS_N_INSNS (2), /* mulsi_const9 */
818 COSTS_N_INSNS (2), /* muldi */
819 COSTS_N_INSNS (18), /* divsi */
820 COSTS_N_INSNS (34), /* divdi */
821 COSTS_N_INSNS (3), /* fp */
822 COSTS_N_INSNS (3), /* dmul */
823 COSTS_N_INSNS (13), /* sdiv */
824 COSTS_N_INSNS (16), /* ddiv */
825 128, /* cache line size */
828 12, /* prefetch streams */
831 /* Instruction costs on POWER A2 processors. */
833 struct processor_costs ppca2_cost = {
834 COSTS_N_INSNS (16), /* mulsi */
835 COSTS_N_INSNS (16), /* mulsi_const */
836 COSTS_N_INSNS (16), /* mulsi_const9 */
837 COSTS_N_INSNS (16), /* muldi */
838 COSTS_N_INSNS (22), /* divsi */
839 COSTS_N_INSNS (28), /* divdi */
840 COSTS_N_INSNS (3), /* fp */
841 COSTS_N_INSNS (3), /* dmul */
842 COSTS_N_INSNS (59), /* sdiv */
843 COSTS_N_INSNS (72), /* ddiv */
847 16, /* prefetch streams */
851 /* Table that classifies rs6000 builtin functions (pure, const, etc.). */
852 #undef RS6000_BUILTIN
853 #undef RS6000_BUILTIN_EQUATE
854 #define RS6000_BUILTIN(NAME, TYPE) TYPE,
855 #define RS6000_BUILTIN_EQUATE(NAME, VALUE)
857 static const enum rs6000_btc builtin_classify[(int)RS6000_BUILTIN_COUNT] =
859 #include "rs6000-builtin.def"
862 #undef RS6000_BUILTIN
863 #undef RS6000_BUILTIN_EQUATE
865 /* Support for -mveclibabi=<xxx> to control which vector library to use. */
866 static tree (*rs6000_veclib_handler) (tree, tree, tree);
869 static bool rs6000_function_ok_for_sibcall (tree, tree);
870 static const char *rs6000_invalid_within_doloop (const_rtx);
871 static bool rs6000_legitimate_address_p (enum machine_mode, rtx, bool);
872 static bool rs6000_debug_legitimate_address_p (enum machine_mode, rtx, bool);
873 static rtx rs6000_generate_compare (rtx, enum machine_mode);
874 static void rs6000_emit_stack_tie (void);
875 static bool spe_func_has_64bit_regs_p (void);
876 static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
877 static unsigned rs6000_hash_constant (rtx);
878 static unsigned toc_hash_function (const void *);
879 static int toc_hash_eq (const void *, const void *);
880 static bool reg_offset_addressing_ok_p (enum machine_mode);
881 static bool virtual_stack_registers_memory_p (rtx);
882 static bool constant_pool_expr_p (rtx);
883 static bool legitimate_small_data_p (enum machine_mode, rtx);
884 static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
885 static struct machine_function * rs6000_init_machine_status (void);
886 static bool rs6000_assemble_integer (rtx, unsigned int, int);
887 static bool no_global_regs_above (int, bool);
888 #if defined (HAVE_GAS_HIDDEN) && !defined (TARGET_MACHO)
889 static void rs6000_assemble_visibility (tree, int);
891 static int rs6000_ra_ever_killed (void);
892 static bool rs6000_attribute_takes_identifier_p (const_tree);
893 static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
894 static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
895 static bool rs6000_ms_bitfield_layout_p (const_tree);
896 static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *);
897 static void rs6000_eliminate_indexed_memrefs (rtx operands[2]);
898 static const char *rs6000_mangle_type (const_tree);
899 static void rs6000_set_default_type_attributes (tree);
900 static rtx rs6000_savres_routine_sym (rs6000_stack_t *, bool, bool, bool);
901 static rtx rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool);
902 static bool rs6000_reg_live_or_pic_offset_p (int);
903 static tree rs6000_builtin_vectorized_libmass (tree, tree, tree);
904 static tree rs6000_builtin_vectorized_function (tree, tree, tree);
905 static void rs6000_restore_saved_cr (rtx, int);
906 static bool rs6000_output_addr_const_extra (FILE *, rtx);
907 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
908 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
909 static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
911 static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
912 static bool rs6000_return_in_memory (const_tree, const_tree);
913 static rtx rs6000_function_value (const_tree, const_tree, bool);
914 static void rs6000_file_start (void);
916 static int rs6000_elf_reloc_rw_mask (void);
917 static void rs6000_elf_asm_out_constructor (rtx, int) ATTRIBUTE_UNUSED;
918 static void rs6000_elf_asm_out_destructor (rtx, int) ATTRIBUTE_UNUSED;
919 static void rs6000_elf_file_end (void) ATTRIBUTE_UNUSED;
920 static void rs6000_elf_asm_init_sections (void);
921 static section *rs6000_elf_select_rtx_section (enum machine_mode, rtx,
922 unsigned HOST_WIDE_INT);
923 static void rs6000_elf_encode_section_info (tree, rtx, int)
926 static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx);
927 static void rs6000_alloc_sdmode_stack_slot (void);
928 static void rs6000_instantiate_decls (void);
930 static void rs6000_xcoff_asm_output_anchor (rtx);
931 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
932 static void rs6000_xcoff_asm_init_sections (void);
933 static int rs6000_xcoff_reloc_rw_mask (void);
934 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree);
935 static section *rs6000_xcoff_select_section (tree, int,
936 unsigned HOST_WIDE_INT);
937 static void rs6000_xcoff_unique_section (tree, int);
938 static section *rs6000_xcoff_select_rtx_section
939 (enum machine_mode, rtx, unsigned HOST_WIDE_INT);
940 static const char * rs6000_xcoff_strip_name_encoding (const char *);
941 static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
942 static void rs6000_xcoff_file_start (void);
943 static void rs6000_xcoff_file_end (void);
945 static int rs6000_variable_issue (FILE *, int, rtx, int);
946 static int rs6000_register_move_cost (enum machine_mode,
947 reg_class_t, reg_class_t);
948 static int rs6000_memory_move_cost (enum machine_mode, reg_class_t, bool);
949 static bool rs6000_rtx_costs (rtx, int, int, int, int *, bool);
950 static bool rs6000_debug_rtx_costs (rtx, int, int, int, int *, bool);
951 static int rs6000_debug_address_cost (rtx, bool);
952 static int rs6000_adjust_cost (rtx, rtx, rtx, int);
953 static int rs6000_debug_adjust_cost (rtx, rtx, rtx, int);
954 static void rs6000_sched_init (FILE *, int, int);
955 static bool is_microcoded_insn (rtx);
956 static bool is_nonpipeline_insn (rtx);
957 static bool is_cracked_insn (rtx);
958 static bool is_branch_slot_insn (rtx);
959 static bool is_load_insn (rtx);
960 static rtx get_store_dest (rtx pat);
961 static bool is_store_insn (rtx);
962 static bool set_to_load_agen (rtx,rtx);
963 static bool adjacent_mem_locations (rtx,rtx);
964 static int rs6000_adjust_priority (rtx, int);
965 static int rs6000_issue_rate (void);
966 static bool rs6000_is_costly_dependence (dep_t, int, int);
967 static rtx get_next_active_insn (rtx, rtx);
968 static bool insn_terminates_group_p (rtx , enum group_termination);
969 static bool insn_must_be_first_in_group (rtx);
970 static bool insn_must_be_last_in_group (rtx);
971 static bool is_costly_group (rtx *, rtx);
972 static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
973 static int redefine_groups (FILE *, int, rtx, rtx);
974 static int pad_groups (FILE *, int, rtx, rtx);
975 static void rs6000_sched_finish (FILE *, int);
976 static int rs6000_sched_reorder (FILE *, int, rtx *, int *, int);
977 static int rs6000_sched_reorder2 (FILE *, int, rtx *, int *, int);
978 static int rs6000_use_sched_lookahead (void);
979 static int rs6000_use_sched_lookahead_guard (rtx);
980 static void * rs6000_alloc_sched_context (void);
981 static void rs6000_init_sched_context (void *, bool);
982 static void rs6000_set_sched_context (void *);
983 static void rs6000_free_sched_context (void *);
984 static tree rs6000_builtin_reciprocal (unsigned int, bool, bool);
985 static tree rs6000_builtin_mask_for_load (void);
986 static tree rs6000_builtin_mul_widen_even (tree);
987 static tree rs6000_builtin_mul_widen_odd (tree);
988 static tree rs6000_builtin_conversion (unsigned int, tree, tree);
989 static bool rs6000_builtin_support_vector_misalignment (enum
993 static int rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt,
995 static enum machine_mode rs6000_preferred_simd_mode (enum machine_mode);
997 static void def_builtin (int, const char *, tree, int);
998 static bool rs6000_vector_alignment_reachable (const_tree, bool);
999 static void rs6000_init_builtins (void);
1000 static tree rs6000_builtin_decl (unsigned, bool);
1002 static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
1003 static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
1004 static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
1005 static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
1006 static void altivec_init_builtins (void);
1007 static unsigned builtin_hash_function (const void *);
1008 static int builtin_hash_eq (const void *, const void *);
1009 static tree builtin_function_type (enum machine_mode, enum machine_mode,
1010 enum machine_mode, enum machine_mode,
1011 enum rs6000_builtins, const char *name);
1012 static void rs6000_common_init_builtins (void);
1013 static void rs6000_init_libfuncs (void);
1015 static void paired_init_builtins (void);
1016 static rtx paired_expand_builtin (tree, rtx, bool *);
1017 static rtx paired_expand_lv_builtin (enum insn_code, tree, rtx);
1018 static rtx paired_expand_stv_builtin (enum insn_code, tree);
1019 static rtx paired_expand_predicate_builtin (enum insn_code, tree, rtx);
1021 static void enable_mask_for_builtins (struct builtin_description *, int,
1022 enum rs6000_builtins,
1023 enum rs6000_builtins);
1024 static void spe_init_builtins (void);
1025 static rtx spe_expand_builtin (tree, rtx, bool *);
1026 static rtx spe_expand_stv_builtin (enum insn_code, tree);
1027 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
1028 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
1029 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
1030 static rs6000_stack_t *rs6000_stack_info (void);
1031 static void debug_stack_info (rs6000_stack_t *);
1033 static rtx altivec_expand_builtin (tree, rtx, bool *);
1034 static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
1035 static rtx altivec_expand_st_builtin (tree, rtx, bool *);
1036 static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
1037 static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
1038 static rtx altivec_expand_predicate_builtin (enum insn_code, tree, rtx);
1039 static rtx altivec_expand_stv_builtin (enum insn_code, tree);
1040 static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
1041 static rtx altivec_expand_vec_set_builtin (tree);
1042 static rtx altivec_expand_vec_ext_builtin (tree, rtx);
1043 static int get_element_number (tree, tree);
1044 static void rs6000_option_override (void);
1045 static int rs6000_loop_align_max_skip (rtx);
1046 static int first_altivec_reg_to_save (void);
1047 static unsigned int compute_vrsave_mask (void);
1048 static void compute_save_world_info (rs6000_stack_t *info_ptr);
1049 static void is_altivec_return_reg (rtx, void *);
1050 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
1051 int easy_vector_constant (rtx, enum machine_mode);
1052 static rtx rs6000_dwarf_register_span (rtx);
1053 static void rs6000_init_dwarf_reg_sizes_extra (tree);
1054 static rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode);
1055 static rtx rs6000_debug_legitimize_address (rtx, rtx, enum machine_mode);
1056 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
1057 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
1058 static rtx rs6000_delegitimize_address (rtx);
1059 static rtx rs6000_tls_get_addr (void);
1060 static rtx rs6000_got_sym (void);
1061 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
1062 static const char *rs6000_get_some_local_dynamic_name (void);
1063 static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
1064 static rtx rs6000_complex_function_value (enum machine_mode);
1065 static rtx rs6000_spe_function_arg (const CUMULATIVE_ARGS *,
1066 enum machine_mode, const_tree);
1067 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
1068 HOST_WIDE_INT, int);
1069 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
1072 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
1075 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
1076 const_tree, HOST_WIDE_INT,
1078 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, bool, bool);
1079 static rtx rs6000_mixed_function_arg (enum machine_mode, const_tree, int);
1080 static void rs6000_function_arg_advance (cumulative_args_t, enum machine_mode,
1082 static rtx rs6000_function_arg (cumulative_args_t, enum machine_mode,
1084 static unsigned int rs6000_function_arg_boundary (enum machine_mode,
1086 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
1087 static void setup_incoming_varargs (cumulative_args_t,
1088 enum machine_mode, tree,
1090 static bool rs6000_pass_by_reference (cumulative_args_t, enum machine_mode,
1092 static int rs6000_arg_partial_bytes (cumulative_args_t, enum machine_mode,
1094 static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree);
1096 static void macho_branch_islands (void);
1097 static int no_previous_def (tree function_name);
1098 static tree get_prev_label (tree function_name);
1099 static void rs6000_darwin_file_start (void);
1102 static tree rs6000_build_builtin_va_list (void);
1103 static void rs6000_va_start (tree, rtx);
1104 static tree rs6000_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
1105 static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree);
1106 static bool rs6000_scalar_mode_supported_p (enum machine_mode);
1107 static bool rs6000_vector_mode_supported_p (enum machine_mode);
1108 static rtx rs6000_emit_vector_compare_inner (enum rtx_code, rtx, rtx);
1109 static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
1111 static tree rs6000_stack_protect_fail (void);
1113 static rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, int, int,
1116 static rtx rs6000_debug_legitimize_reload_address (rtx, enum machine_mode, int,
1119 rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode, int, int,
1121 = rs6000_legitimize_reload_address;
1123 static bool rs6000_mode_dependent_address_p (const_rtx);
1124 static bool rs6000_mode_dependent_address (const_rtx);
1125 static bool rs6000_debug_mode_dependent_address (const_rtx);
1126 static bool (*rs6000_mode_dependent_address_ptr) (const_rtx)
1127 = rs6000_mode_dependent_address;
1129 static enum reg_class rs6000_secondary_reload_class (enum reg_class,
1130 enum machine_mode, rtx);
1131 static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class,
1134 enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class,
1135 enum machine_mode, rtx)
1136 = rs6000_secondary_reload_class;
1138 static enum reg_class rs6000_preferred_reload_class (rtx, enum reg_class);
1139 static enum reg_class rs6000_debug_preferred_reload_class (rtx,
1141 enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, enum reg_class)
1142 = rs6000_preferred_reload_class;
1144 static bool rs6000_secondary_memory_needed (enum reg_class, enum reg_class,
1147 static bool rs6000_debug_secondary_memory_needed (enum reg_class,
1151 bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class,
1153 = rs6000_secondary_memory_needed;
1155 static bool rs6000_cannot_change_mode_class (enum machine_mode,
1158 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode,
1162 bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode,
1165 = rs6000_cannot_change_mode_class;
1167 static reg_class_t rs6000_secondary_reload (bool, rtx, reg_class_t,
1169 struct secondary_reload_info *);
1171 const int INSN_NOT_AVAILABLE = -1;
1172 static enum machine_mode rs6000_eh_return_filter_mode (void);
1173 static bool rs6000_can_eliminate (const int, const int);
1174 static void rs6000_conditional_register_usage (void);
1175 static void rs6000_trampoline_init (rtx, tree, rtx);
1176 static bool rs6000_cannot_force_const_mem (enum machine_mode, rtx);
1177 static bool rs6000_legitimate_constant_p (enum machine_mode, rtx);
1178 static bool rs6000_save_toc_in_prologue_p (void);
1179 static void rs6000_code_end (void) ATTRIBUTE_UNUSED;
1181 /* Hash table stuff for keeping track of TOC entries. */
1183 struct GTY(()) toc_hash_struct
1185 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1186 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1188 enum machine_mode key_mode;
1192 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
1194 /* Hash table to keep track of the argument types for builtin functions. */
1196 struct GTY(()) builtin_hash_struct
1199 enum machine_mode mode[4]; /* return value + 3 arguments. */
1200 unsigned char uns_p[4]; /* and whether the types are unsigned. */
1203 static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table;
1205 static bool rs6000_valid_attribute_p (tree, tree, tree, int);
1206 static void rs6000_function_specific_save (struct cl_target_option *);
1207 static void rs6000_function_specific_restore (struct cl_target_option *);
1208 static void rs6000_function_specific_print (FILE *, int,
1209 struct cl_target_option *);
1210 static bool rs6000_can_inline_p (tree, tree);
1211 static void rs6000_set_current_function (tree);
1214 /* Default register names. */
1215 char rs6000_reg_names[][8] =
1217 "0", "1", "2", "3", "4", "5", "6", "7",
1218 "8", "9", "10", "11", "12", "13", "14", "15",
1219 "16", "17", "18", "19", "20", "21", "22", "23",
1220 "24", "25", "26", "27", "28", "29", "30", "31",
1221 "0", "1", "2", "3", "4", "5", "6", "7",
1222 "8", "9", "10", "11", "12", "13", "14", "15",
1223 "16", "17", "18", "19", "20", "21", "22", "23",
1224 "24", "25", "26", "27", "28", "29", "30", "31",
1225 "mq", "lr", "ctr","ap",
1226 "0", "1", "2", "3", "4", "5", "6", "7",
1228 /* AltiVec registers. */
1229 "0", "1", "2", "3", "4", "5", "6", "7",
1230 "8", "9", "10", "11", "12", "13", "14", "15",
1231 "16", "17", "18", "19", "20", "21", "22", "23",
1232 "24", "25", "26", "27", "28", "29", "30", "31",
1234 /* SPE registers. */
1235 "spe_acc", "spefscr",
1236 /* Soft frame pointer. */
1240 #ifdef TARGET_REGNAMES
1241 static const char alt_reg_names[][8] =
1243 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1244 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1245 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1246 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1247 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1248 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1249 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1250 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1251 "mq", "lr", "ctr", "ap",
1252 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1254 /* AltiVec registers. */
1255 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1256 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1257 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1258 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1260 /* SPE registers. */
1261 "spe_acc", "spefscr",
1262 /* Soft frame pointer. */
1267 /* Table of valid machine attributes. */
1269 static const struct attribute_spec rs6000_attribute_table[] =
1271 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
1272 affects_type_identity } */
1273 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute,
1275 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute,
1277 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute,
1279 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute,
1281 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute,
1283 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1284 SUBTARGET_ATTRIBUTE_TABLE,
1286 { NULL, 0, 0, false, false, false, NULL, false }
1289 #ifndef MASK_STRICT_ALIGN
1290 #define MASK_STRICT_ALIGN 0
1292 #ifndef TARGET_PROFILE_KERNEL
1293 #define TARGET_PROFILE_KERNEL 0
1296 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1297 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1299 /* Initialize the GCC target structure. */
1300 #undef TARGET_ATTRIBUTE_TABLE
1301 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1302 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1303 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1304 #undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P
1305 #define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P rs6000_attribute_takes_identifier_p
1307 #undef TARGET_ASM_ALIGNED_DI_OP
1308 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1310 /* Default unaligned ops are only provided for ELF. Find the ops needed
1311 for non-ELF systems. */
1312 #ifndef OBJECT_FORMAT_ELF
1314 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1316 #undef TARGET_ASM_UNALIGNED_HI_OP
1317 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1318 #undef TARGET_ASM_UNALIGNED_SI_OP
1319 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1320 #undef TARGET_ASM_UNALIGNED_DI_OP
1321 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1324 #undef TARGET_ASM_UNALIGNED_HI_OP
1325 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1326 #undef TARGET_ASM_UNALIGNED_SI_OP
1327 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1328 #undef TARGET_ASM_UNALIGNED_DI_OP
1329 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1330 #undef TARGET_ASM_ALIGNED_DI_OP
1331 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1335 /* This hook deals with fixups for relocatable code and DI-mode objects
1337 #undef TARGET_ASM_INTEGER
1338 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1340 #if defined (HAVE_GAS_HIDDEN) && !defined (TARGET_MACHO)
1341 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1342 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1345 #undef TARGET_HAVE_TLS
1346 #define TARGET_HAVE_TLS HAVE_AS_TLS
1348 #undef TARGET_CANNOT_FORCE_CONST_MEM
1349 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_cannot_force_const_mem
1351 #undef TARGET_DELEGITIMIZE_ADDRESS
1352 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1354 #undef TARGET_ASM_FUNCTION_PROLOGUE
1355 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1356 #undef TARGET_ASM_FUNCTION_EPILOGUE
1357 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1359 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
1360 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA rs6000_output_addr_const_extra
1362 #undef TARGET_LEGITIMIZE_ADDRESS
1363 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1365 #undef TARGET_SCHED_VARIABLE_ISSUE
1366 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1368 #undef TARGET_SCHED_ISSUE_RATE
1369 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1370 #undef TARGET_SCHED_ADJUST_COST
1371 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1372 #undef TARGET_SCHED_ADJUST_PRIORITY
1373 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1374 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1375 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1376 #undef TARGET_SCHED_INIT
1377 #define TARGET_SCHED_INIT rs6000_sched_init
1378 #undef TARGET_SCHED_FINISH
1379 #define TARGET_SCHED_FINISH rs6000_sched_finish
1380 #undef TARGET_SCHED_REORDER
1381 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1382 #undef TARGET_SCHED_REORDER2
1383 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1385 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1386 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1388 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1389 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1391 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1392 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1393 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1394 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1395 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1396 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1397 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1398 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1400 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1401 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1402 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1403 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1404 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1405 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1406 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1407 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1408 #undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
1409 #define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT \
1410 rs6000_builtin_support_vector_misalignment
1411 #undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE
1412 #define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1413 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
1414 #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
1415 rs6000_builtin_vectorization_cost
1416 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
1417 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE \
1418 rs6000_preferred_simd_mode
1420 #undef TARGET_INIT_BUILTINS
1421 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1422 #undef TARGET_BUILTIN_DECL
1423 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1425 #undef TARGET_EXPAND_BUILTIN
1426 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1428 #undef TARGET_MANGLE_TYPE
1429 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1431 #undef TARGET_INIT_LIBFUNCS
1432 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1435 #undef TARGET_BINDS_LOCAL_P
1436 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1439 #undef TARGET_MS_BITFIELD_LAYOUT_P
1440 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1442 #undef TARGET_ASM_OUTPUT_MI_THUNK
1443 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1445 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1446 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1448 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1449 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1451 #undef TARGET_INVALID_WITHIN_DOLOOP
1452 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1454 #undef TARGET_REGISTER_MOVE_COST
1455 #define TARGET_REGISTER_MOVE_COST rs6000_register_move_cost
1456 #undef TARGET_MEMORY_MOVE_COST
1457 #define TARGET_MEMORY_MOVE_COST rs6000_memory_move_cost
1458 #undef TARGET_RTX_COSTS
1459 #define TARGET_RTX_COSTS rs6000_rtx_costs
1460 #undef TARGET_ADDRESS_COST
1461 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1463 #undef TARGET_DWARF_REGISTER_SPAN
1464 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1466 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1467 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1469 /* On rs6000, function arguments are promoted, as are function return
1471 #undef TARGET_PROMOTE_FUNCTION_MODE
1472 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1474 #undef TARGET_RETURN_IN_MEMORY
1475 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1477 #undef TARGET_SETUP_INCOMING_VARARGS
1478 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1480 /* Always strict argument naming on rs6000. */
1481 #undef TARGET_STRICT_ARGUMENT_NAMING
1482 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1483 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1484 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1485 #undef TARGET_SPLIT_COMPLEX_ARG
1486 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1487 #undef TARGET_MUST_PASS_IN_STACK
1488 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1489 #undef TARGET_PASS_BY_REFERENCE
1490 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1491 #undef TARGET_ARG_PARTIAL_BYTES
1492 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1493 #undef TARGET_FUNCTION_ARG_ADVANCE
1494 #define TARGET_FUNCTION_ARG_ADVANCE rs6000_function_arg_advance
1495 #undef TARGET_FUNCTION_ARG
1496 #define TARGET_FUNCTION_ARG rs6000_function_arg
1497 #undef TARGET_FUNCTION_ARG_BOUNDARY
1498 #define TARGET_FUNCTION_ARG_BOUNDARY rs6000_function_arg_boundary
1500 #undef TARGET_BUILD_BUILTIN_VA_LIST
1501 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1503 #undef TARGET_EXPAND_BUILTIN_VA_START
1504 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1506 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1507 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1509 #undef TARGET_EH_RETURN_FILTER_MODE
1510 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1512 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1513 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1515 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1516 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1518 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1519 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1521 #undef TARGET_ASM_LOOP_ALIGN_MAX_SKIP
1522 #define TARGET_ASM_LOOP_ALIGN_MAX_SKIP rs6000_loop_align_max_skip
1524 #undef TARGET_OPTION_OVERRIDE
1525 #define TARGET_OPTION_OVERRIDE rs6000_option_override
1527 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1528 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1529 rs6000_builtin_vectorized_function
1531 #ifndef TARGET_MACHO
1532 #undef TARGET_STACK_PROTECT_FAIL
1533 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1536 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1537 The PowerPC architecture requires only weak consistency among
1538 processors--that is, memory accesses between processors need not be
1539 sequentially consistent and memory accesses among processors can occur
1540 in any order. The ability to order memory accesses weakly provides
1541 opportunities for more efficient use of the system bus. Unless a
1542 dependency exists, the 604e allows read operations to precede store
1544 #undef TARGET_RELAXED_ORDERING
1545 #define TARGET_RELAXED_ORDERING true
1548 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1549 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1552 /* Use a 32-bit anchor range. This leads to sequences like:
1554 addis tmp,anchor,high
1557 where tmp itself acts as an anchor, and can be shared between
1558 accesses to the same 64k page. */
1559 #undef TARGET_MIN_ANCHOR_OFFSET
1560 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1561 #undef TARGET_MAX_ANCHOR_OFFSET
1562 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1563 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1564 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1566 #undef TARGET_BUILTIN_RECIPROCAL
1567 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1569 #undef TARGET_EXPAND_TO_RTL_HOOK
1570 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1572 #undef TARGET_INSTANTIATE_DECLS
1573 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1575 #undef TARGET_SECONDARY_RELOAD
1576 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1578 #undef TARGET_LEGITIMATE_ADDRESS_P
1579 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1581 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
1582 #define TARGET_MODE_DEPENDENT_ADDRESS_P rs6000_mode_dependent_address_p
1584 #undef TARGET_CAN_ELIMINATE
1585 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1587 #undef TARGET_CONDITIONAL_REGISTER_USAGE
1588 #define TARGET_CONDITIONAL_REGISTER_USAGE rs6000_conditional_register_usage
1590 #undef TARGET_TRAMPOLINE_INIT
1591 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1593 #undef TARGET_FUNCTION_VALUE
1594 #define TARGET_FUNCTION_VALUE rs6000_function_value
1596 #undef TARGET_OPTION_VALID_ATTRIBUTE_P
1597 #define TARGET_OPTION_VALID_ATTRIBUTE_P rs6000_valid_attribute_p
1599 #undef TARGET_OPTION_SAVE
1600 #define TARGET_OPTION_SAVE rs6000_function_specific_save
1602 #undef TARGET_OPTION_RESTORE
1603 #define TARGET_OPTION_RESTORE rs6000_function_specific_restore
1605 #undef TARGET_OPTION_PRINT
1606 #define TARGET_OPTION_PRINT rs6000_function_specific_print
1608 #undef TARGET_CAN_INLINE_P
1609 #define TARGET_CAN_INLINE_P rs6000_can_inline_p
1611 #undef TARGET_SET_CURRENT_FUNCTION
1612 #define TARGET_SET_CURRENT_FUNCTION rs6000_set_current_function
1614 #undef TARGET_LEGITIMATE_CONSTANT_P
1615 #define TARGET_LEGITIMATE_CONSTANT_P rs6000_legitimate_constant_p
1619 /* Simplifications for entries below. */
1622 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
1623 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
1626 /* Some OSs don't support saving the high part of 64-bit registers on context
1627 switch. Other OSs don't support saving Altivec registers. On those OSs, we
1628 don't touch the MASK_POWERPC64 or MASK_ALTIVEC settings; if the user wants
1629 either, the user must explicitly specify them and we won't interfere with
1630 the user's specification. */
1633 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
1634 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
1635 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
1636 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
1637 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
1638 | MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE
1639 | MASK_RECIP_PRECISION)
1642 /* Masks for instructions set at various powerpc ISAs. */
1644 ISA_2_1_MASKS = MASK_MFCRF,
1645 ISA_2_2_MASKS = (ISA_2_1_MASKS | MASK_POPCNTB),
1646 ISA_2_4_MASKS = (ISA_2_2_MASKS | MASK_FPRND),
1648 /* For ISA 2.05, do not add MFPGPR, since it isn't in ISA 2.06, and don't add
1649 ALTIVEC, since in general it isn't a win on power6. In ISA 2.04, fsel,
1650 fre, fsqrt, etc. were no longer documented as optional. Group masks by
1651 server and embedded. */
1652 ISA_2_5_MASKS_EMBEDDED = (ISA_2_2_MASKS | MASK_CMPB | MASK_RECIP_PRECISION
1653 | MASK_PPC_GFXOPT | MASK_PPC_GPOPT),
1654 ISA_2_5_MASKS_SERVER = (ISA_2_5_MASKS_EMBEDDED | MASK_DFP),
1656 /* For ISA 2.06, don't add ISEL, since in general it isn't a win, but
1657 altivec is a win so enable it. */
1658 ISA_2_6_MASKS_EMBEDDED = (ISA_2_5_MASKS_EMBEDDED | MASK_POPCNTD),
1659 ISA_2_6_MASKS_SERVER = (ISA_2_5_MASKS_SERVER | MASK_POPCNTD | MASK_ALTIVEC
1665 const char *const name; /* Canonical processor name. */
1666 const enum processor_type processor; /* Processor type enum value. */
1667 const int target_enable; /* Target flags to enable. */
1670 static struct rs6000_ptt const processor_target_table[] =
1672 #define RS6000_CPU(NAME, CPU, FLAGS) { NAME, CPU, FLAGS },
1673 #include "rs6000-cpus.def"
1677 /* Look up a processor name for -mcpu=xxx and -mtune=xxx. Return -1 if the
1681 rs6000_cpu_name_lookup (const char *name)
1687 for (i = 0; i < ARRAY_SIZE (processor_target_table); i++)
1688 if (! strcmp (name, processor_target_table[i].name))
1696 /* Return number of consecutive hard regs needed starting at reg REGNO
1697 to hold something of mode MODE.
1698 This is ordinarily the length in words of a value of mode MODE
1699 but can be less for certain modes in special long registers.
1701 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1702 scalar instructions. The upper 32 bits are only available to the
1705 POWER and PowerPC GPRs hold 32 bits worth;
1706 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1709 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1711 unsigned HOST_WIDE_INT reg_size;
1713 if (FP_REGNO_P (regno))
1714 reg_size = (VECTOR_MEM_VSX_P (mode)
1715 ? UNITS_PER_VSX_WORD
1716 : UNITS_PER_FP_WORD);
1718 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1719 reg_size = UNITS_PER_SPE_WORD;
1721 else if (ALTIVEC_REGNO_P (regno))
1722 reg_size = UNITS_PER_ALTIVEC_WORD;
1724 /* The value returned for SCmode in the E500 double case is 2 for
1725 ABI compatibility; storing an SCmode value in a single register
1726 would require function_arg and rs6000_spe_function_arg to handle
1727 SCmode so as to pass the value correctly in a pair of
1729 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1730 && !DECIMAL_FLOAT_MODE_P (mode))
1731 reg_size = UNITS_PER_FP_WORD;
1734 reg_size = UNITS_PER_WORD;
1736 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1739 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1742 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1744 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1746 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1747 implementations. Don't allow an item to be split between a FP register
1748 and an Altivec register. */
1749 if (VECTOR_MEM_VSX_P (mode))
1751 if (FP_REGNO_P (regno))
1752 return FP_REGNO_P (last_regno);
1754 if (ALTIVEC_REGNO_P (regno))
1755 return ALTIVEC_REGNO_P (last_regno);
1758 /* The GPRs can hold any mode, but values bigger than one register
1759 cannot go past R31. */
1760 if (INT_REGNO_P (regno))
1761 return INT_REGNO_P (last_regno);
1763 /* The float registers (except for VSX vector modes) can only hold floating
1764 modes and DImode. This excludes the 32-bit decimal float mode for
1766 if (FP_REGNO_P (regno))
1768 if (SCALAR_FLOAT_MODE_P (mode)
1769 && (mode != TDmode || (regno % 2) == 0)
1770 && FP_REGNO_P (last_regno))
1773 if (GET_MODE_CLASS (mode) == MODE_INT
1774 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1777 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1778 && PAIRED_VECTOR_MODE (mode))
1784 /* The CR register can only hold CC modes. */
1785 if (CR_REGNO_P (regno))
1786 return GET_MODE_CLASS (mode) == MODE_CC;
1788 if (CA_REGNO_P (regno))
1789 return mode == BImode;
1791 /* AltiVec only in AldyVec registers. */
1792 if (ALTIVEC_REGNO_P (regno))
1793 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1795 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1796 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1799 /* We cannot put TImode anywhere except general register and it must be able
1800 to fit within the register set. In the future, allow TImode in the
1801 Altivec or VSX registers. */
1803 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1806 /* Print interesting facts about registers. */
1808 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1812 for (r = first_regno; r <= last_regno; ++r)
1814 const char *comma = "";
1817 if (first_regno == last_regno)
1818 fprintf (stderr, "%s:\t", reg_name);
1820 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1823 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1824 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1828 fprintf (stderr, ",\n\t");
1833 if (rs6000_hard_regno_nregs[m][r] > 1)
1834 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
1835 rs6000_hard_regno_nregs[m][r]);
1837 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
1842 if (call_used_regs[r])
1846 fprintf (stderr, ",\n\t");
1851 len += fprintf (stderr, "%s%s", comma, "call-used");
1859 fprintf (stderr, ",\n\t");
1864 len += fprintf (stderr, "%s%s", comma, "fixed");
1870 fprintf (stderr, ",\n\t");
1874 fprintf (stderr, "%sregno = %d\n", comma, r);
1878 #define DEBUG_FMT_D "%-32s= %d\n"
1879 #define DEBUG_FMT_S "%-32s= %s\n"
1881 /* Print various interesting information with -mdebug=reg. */
1883 rs6000_debug_reg_global (void)
1885 static const char *const tf[2] = { "false", "true" };
1886 const char *nl = (const char *)0;
1888 char costly_num[20];
1890 const char *costly_str;
1891 const char *nop_str;
1892 const char *trace_str;
1893 const char *abi_str;
1894 const char *cmodel_str;
1896 /* Map enum rs6000_vector to string. */
1897 static const char *rs6000_debug_vector_unit[] = {
1906 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
1907 LAST_VIRTUAL_REGISTER);
1908 rs6000_debug_reg_print (0, 31, "gr");
1909 rs6000_debug_reg_print (32, 63, "fp");
1910 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
1913 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
1914 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
1915 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
1916 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
1917 rs6000_debug_reg_print (CA_REGNO, CA_REGNO, "ca");
1918 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
1919 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
1920 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
1921 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
1925 "d reg_class = %s\n"
1926 "f reg_class = %s\n"
1927 "v reg_class = %s\n"
1928 "wa reg_class = %s\n"
1929 "wd reg_class = %s\n"
1930 "wf reg_class = %s\n"
1931 "ws reg_class = %s\n\n",
1932 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
1933 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
1934 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
1935 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
1936 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
1937 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
1938 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
1940 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1941 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
1944 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
1946 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
1947 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
1953 if (rs6000_recip_control)
1955 fprintf (stderr, "\nReciprocal mask = 0x%x\n", rs6000_recip_control);
1957 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1958 if (rs6000_recip_bits[m])
1961 "Reciprocal estimate mode: %-5s divide: %s rsqrt: %s\n",
1963 (RS6000_RECIP_AUTO_RE_P (m)
1965 : (RS6000_RECIP_HAVE_RE_P (m) ? "have" : "none")),
1966 (RS6000_RECIP_AUTO_RSQRTE_P (m)
1968 : (RS6000_RECIP_HAVE_RSQRTE_P (m) ? "have" : "none")));
1971 fputs ("\n", stderr);
1974 if (rs6000_cpu_index >= 0)
1975 fprintf (stderr, DEBUG_FMT_S, "cpu",
1976 processor_target_table[rs6000_cpu_index].name);
1978 if (rs6000_tune_index >= 0)
1979 fprintf (stderr, DEBUG_FMT_S, "tune",
1980 processor_target_table[rs6000_tune_index].name);
1982 switch (rs6000_sched_costly_dep)
1984 case max_dep_latency:
1985 costly_str = "max_dep_latency";
1989 costly_str = "no_dep_costly";
1992 case all_deps_costly:
1993 costly_str = "all_deps_costly";
1996 case true_store_to_load_dep_costly:
1997 costly_str = "true_store_to_load_dep_costly";
2000 case store_to_load_dep_costly:
2001 costly_str = "store_to_load_dep_costly";
2005 costly_str = costly_num;
2006 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
2010 fprintf (stderr, DEBUG_FMT_S, "sched_costly_dep", costly_str);
2012 switch (rs6000_sched_insert_nops)
2014 case sched_finish_regroup_exact:
2015 nop_str = "sched_finish_regroup_exact";
2018 case sched_finish_pad_groups:
2019 nop_str = "sched_finish_pad_groups";
2022 case sched_finish_none:
2023 nop_str = "sched_finish_none";
2028 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
2032 fprintf (stderr, DEBUG_FMT_S, "sched_insert_nops", nop_str);
2034 switch (rs6000_sdata)
2041 fprintf (stderr, DEBUG_FMT_S, "sdata", "data");
2045 fprintf (stderr, DEBUG_FMT_S, "sdata", "sysv");
2049 fprintf (stderr, DEBUG_FMT_S, "sdata", "eabi");
2054 switch (rs6000_traceback)
2056 case traceback_default: trace_str = "default"; break;
2057 case traceback_none: trace_str = "none"; break;
2058 case traceback_part: trace_str = "part"; break;
2059 case traceback_full: trace_str = "full"; break;
2060 default: trace_str = "unknown"; break;
2063 fprintf (stderr, DEBUG_FMT_S, "traceback", trace_str);
2065 switch (rs6000_current_cmodel)
2067 case CMODEL_SMALL: cmodel_str = "small"; break;
2068 case CMODEL_MEDIUM: cmodel_str = "medium"; break;
2069 case CMODEL_LARGE: cmodel_str = "large"; break;
2070 default: cmodel_str = "unknown"; break;
2073 fprintf (stderr, DEBUG_FMT_S, "cmodel", cmodel_str);
2075 switch (rs6000_current_abi)
2077 case ABI_NONE: abi_str = "none"; break;
2078 case ABI_AIX: abi_str = "aix"; break;
2079 case ABI_V4: abi_str = "V4"; break;
2080 case ABI_DARWIN: abi_str = "darwin"; break;
2081 default: abi_str = "unknown"; break;
2084 fprintf (stderr, DEBUG_FMT_S, "abi", abi_str);
2086 if (rs6000_altivec_abi)
2087 fprintf (stderr, DEBUG_FMT_S, "altivec_abi", "true");
2090 fprintf (stderr, DEBUG_FMT_S, "spe_abi", "true");
2092 if (rs6000_darwin64_abi)
2093 fprintf (stderr, DEBUG_FMT_S, "darwin64_abi", "true");
2095 if (rs6000_float_gprs)
2096 fprintf (stderr, DEBUG_FMT_S, "float_gprs", "true");
2098 fprintf (stderr, DEBUG_FMT_S, "always_hint", tf[!!rs6000_always_hint]);
2099 fprintf (stderr, DEBUG_FMT_S, "align_branch",
2100 tf[!!rs6000_align_branch_targets]);
2101 fprintf (stderr, DEBUG_FMT_D, "tls_size", rs6000_tls_size);
2102 fprintf (stderr, DEBUG_FMT_D, "long_double_size",
2103 rs6000_long_double_type_size);
2104 fprintf (stderr, DEBUG_FMT_D, "sched_restricted_insns_priority",
2105 (int)rs6000_sched_restricted_insns_priority);
2108 /* Initialize the various global tables that are based on register size. */
2110 rs6000_init_hard_regno_mode_ok (bool global_init_p)
2116 /* Precalculate REGNO_REG_CLASS. */
2117 rs6000_regno_regclass[0] = GENERAL_REGS;
2118 for (r = 1; r < 32; ++r)
2119 rs6000_regno_regclass[r] = BASE_REGS;
2121 for (r = 32; r < 64; ++r)
2122 rs6000_regno_regclass[r] = FLOAT_REGS;
2124 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
2125 rs6000_regno_regclass[r] = NO_REGS;
2127 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
2128 rs6000_regno_regclass[r] = ALTIVEC_REGS;
2130 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
2131 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
2132 rs6000_regno_regclass[r] = CR_REGS;
2134 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
2135 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
2136 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
2137 rs6000_regno_regclass[CA_REGNO] = CA_REGS;
2138 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
2139 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
2140 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
2141 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
2142 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
2143 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
2145 /* Precalculate vector information, this must be set up before the
2146 rs6000_hard_regno_nregs_internal below. */
2147 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2149 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
2150 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
2151 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
2154 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
2155 rs6000_constraints[c] = NO_REGS;
2157 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
2158 believes it can use native alignment or still uses 128-bit alignment. */
2159 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
2170 /* V2DF mode, VSX only. */
2173 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
2174 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
2175 rs6000_vector_align[V2DFmode] = align64;
2178 /* V4SF mode, either VSX or Altivec. */
2181 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
2182 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
2183 rs6000_vector_align[V4SFmode] = align32;
2185 else if (TARGET_ALTIVEC)
2187 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
2188 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
2189 rs6000_vector_align[V4SFmode] = align32;
2192 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
2196 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
2197 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
2198 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
2199 rs6000_vector_align[V4SImode] = align32;
2200 rs6000_vector_align[V8HImode] = align32;
2201 rs6000_vector_align[V16QImode] = align32;
2205 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
2206 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
2207 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
2211 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
2212 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
2213 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
2217 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
2218 Altivec doesn't have 64-bit support. */
2221 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
2222 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
2223 rs6000_vector_align[V2DImode] = align64;
2226 /* DFmode, see if we want to use the VSX unit. */
2227 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
2229 rs6000_vector_unit[DFmode] = VECTOR_VSX;
2230 rs6000_vector_mem[DFmode]
2231 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
2232 rs6000_vector_align[DFmode] = align64;
2235 /* TODO add SPE and paired floating point vector support. */
2237 /* Register class constaints for the constraints that depend on compile
2239 if (TARGET_HARD_FLOAT && TARGET_FPRS)
2240 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
2242 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
2243 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
2247 /* At present, we just use VSX_REGS, but we have different constraints
2248 based on the use, in case we want to fine tune the default register
2249 class used. wa = any VSX register, wf = register class to use for
2250 V4SF, wd = register class to use for V2DF, and ws = register classs to
2251 use for DF scalars. */
2252 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
2253 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
2254 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
2255 rs6000_constraints[RS6000_CONSTRAINT_ws] = (TARGET_VSX_SCALAR_MEMORY
2261 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
2263 /* Set up the reload helper functions. */
2264 if (TARGET_VSX || TARGET_ALTIVEC)
2268 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
2269 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
2270 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
2271 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
2272 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
2273 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
2274 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
2275 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
2276 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
2277 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
2278 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
2279 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
2283 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
2284 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
2285 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
2286 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
2287 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
2288 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
2289 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
2290 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
2291 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
2292 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
2293 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
2294 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
2298 /* Precalculate HARD_REGNO_NREGS. */
2299 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2300 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2301 rs6000_hard_regno_nregs[m][r]
2302 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
2304 /* Precalculate HARD_REGNO_MODE_OK. */
2305 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2306 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2307 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
2308 rs6000_hard_regno_mode_ok_p[m][r] = true;
2310 /* Precalculate CLASS_MAX_NREGS sizes. */
2311 for (c = 0; c < LIM_REG_CLASSES; ++c)
2315 if (TARGET_VSX && VSX_REG_CLASS_P (c))
2316 reg_size = UNITS_PER_VSX_WORD;
2318 else if (c == ALTIVEC_REGS)
2319 reg_size = UNITS_PER_ALTIVEC_WORD;
2321 else if (c == FLOAT_REGS)
2322 reg_size = UNITS_PER_FP_WORD;
2325 reg_size = UNITS_PER_WORD;
2327 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2328 rs6000_class_max_nregs[m][c]
2329 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
2332 if (TARGET_E500_DOUBLE)
2333 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
2335 /* Calculate which modes to automatically generate code to use a the
2336 reciprocal divide and square root instructions. In the future, possibly
2337 automatically generate the instructions even if the user did not specify
2338 -mrecip. The older machines double precision reciprocal sqrt estimate is
2339 not accurate enough. */
2340 memset (rs6000_recip_bits, 0, sizeof (rs6000_recip_bits));
2342 rs6000_recip_bits[SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2344 rs6000_recip_bits[DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2345 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2346 rs6000_recip_bits[V4SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2347 if (VECTOR_UNIT_VSX_P (V2DFmode))
2348 rs6000_recip_bits[V2DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2350 if (TARGET_FRSQRTES)
2351 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2353 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2354 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2355 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2356 if (VECTOR_UNIT_VSX_P (V2DFmode))
2357 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2359 if (rs6000_recip_control)
2361 if (!flag_finite_math_only)
2362 warning (0, "-mrecip requires -ffinite-math or -ffast-math");
2363 if (flag_trapping_math)
2364 warning (0, "-mrecip requires -fno-trapping-math or -ffast-math");
2365 if (!flag_reciprocal_math)
2366 warning (0, "-mrecip requires -freciprocal-math or -ffast-math");
2367 if (flag_finite_math_only && !flag_trapping_math && flag_reciprocal_math)
2369 if (RS6000_RECIP_HAVE_RE_P (SFmode)
2370 && (rs6000_recip_control & RECIP_SF_DIV) != 0)
2371 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2373 if (RS6000_RECIP_HAVE_RE_P (DFmode)
2374 && (rs6000_recip_control & RECIP_DF_DIV) != 0)
2375 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2377 if (RS6000_RECIP_HAVE_RE_P (V4SFmode)
2378 && (rs6000_recip_control & RECIP_V4SF_DIV) != 0)
2379 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2381 if (RS6000_RECIP_HAVE_RE_P (V2DFmode)
2382 && (rs6000_recip_control & RECIP_V2DF_DIV) != 0)
2383 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2385 if (RS6000_RECIP_HAVE_RSQRTE_P (SFmode)
2386 && (rs6000_recip_control & RECIP_SF_RSQRT) != 0)
2387 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2389 if (RS6000_RECIP_HAVE_RSQRTE_P (DFmode)
2390 && (rs6000_recip_control & RECIP_DF_RSQRT) != 0)
2391 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2393 if (RS6000_RECIP_HAVE_RSQRTE_P (V4SFmode)
2394 && (rs6000_recip_control & RECIP_V4SF_RSQRT) != 0)
2395 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2397 if (RS6000_RECIP_HAVE_RSQRTE_P (V2DFmode)
2398 && (rs6000_recip_control & RECIP_V2DF_RSQRT) != 0)
2399 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2403 if (global_init_p || TARGET_DEBUG_TARGET)
2405 if (TARGET_DEBUG_REG)
2406 rs6000_debug_reg_global ();
2408 if (TARGET_DEBUG_COST || TARGET_DEBUG_REG)
2410 "SImode variable mult cost = %d\n"
2411 "SImode constant mult cost = %d\n"
2412 "SImode short constant mult cost = %d\n"
2413 "DImode multipliciation cost = %d\n"
2414 "SImode division cost = %d\n"
2415 "DImode division cost = %d\n"
2416 "Simple fp operation cost = %d\n"
2417 "DFmode multiplication cost = %d\n"
2418 "SFmode division cost = %d\n"
2419 "DFmode division cost = %d\n"
2420 "cache line size = %d\n"
2421 "l1 cache size = %d\n"
2422 "l2 cache size = %d\n"
2423 "simultaneous prefetches = %d\n"
2426 rs6000_cost->mulsi_const,
2427 rs6000_cost->mulsi_const9,
2435 rs6000_cost->cache_line_size,
2436 rs6000_cost->l1_cache_size,
2437 rs6000_cost->l2_cache_size,
2438 rs6000_cost->simultaneous_prefetches);
2443 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2446 darwin_rs6000_override_options (void)
2448 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2450 rs6000_altivec_abi = 1;
2451 TARGET_ALTIVEC_VRSAVE = 1;
2453 if (DEFAULT_ABI == ABI_DARWIN
2455 darwin_one_byte_bool = 1;
2457 if (TARGET_64BIT && ! TARGET_POWERPC64)
2459 target_flags |= MASK_POWERPC64;
2460 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2464 rs6000_default_long_calls = 1;
2465 target_flags |= MASK_SOFT_FLOAT;
2468 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2470 if (!flag_mkernel && !flag_apple_kext
2472 && ! (target_flags_explicit & MASK_ALTIVEC))
2473 target_flags |= MASK_ALTIVEC;
2475 /* Unless the user (not the configurer) has explicitly overridden
2476 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2477 G4 unless targetting the kernel. */
2480 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2481 && ! (target_flags_explicit & MASK_ALTIVEC)
2482 && ! global_options_set.x_rs6000_cpu_index)
2484 target_flags |= MASK_ALTIVEC;
2489 /* If not otherwise specified by a target, make 'long double' equivalent to
2492 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2493 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2496 /* Override command line options. Mostly we process the processor type and
2497 sometimes adjust other TARGET_ options. */
2500 rs6000_option_override_internal (bool global_init_p)
2503 const char *default_cpu = OPTION_TARGET_CPU_DEFAULT;
2507 struct cl_target_option *main_target_opt
2508 = ((global_init_p || target_option_default_node == NULL)
2509 ? NULL : TREE_TARGET_OPTION (target_option_default_node));
2511 /* On 64-bit Darwin, power alignment is ABI-incompatible with some C
2512 library functions, so warn about it. The flag may be useful for
2513 performance studies from time to time though, so don't disable it
2515 if (global_options_set.x_rs6000_alignment_flags
2516 && rs6000_alignment_flags == MASK_ALIGN_POWER
2517 && DEFAULT_ABI == ABI_DARWIN
2519 warning (0, "-malign-power is not supported for 64-bit Darwin;"
2520 " it is incompatible with the installed C and C++ libraries");
2522 if (global_options_set.x_rs6000_spe_abi
2525 error ("not configured for SPE ABI");
2527 /* Numerous experiment shows that IRA based loop pressure
2528 calculation works better for RTL loop invariant motion on targets
2529 with enough (>= 32) registers. It is an expensive optimization.
2530 So it is on only for peak performance. */
2531 if (optimize >= 3 && global_init_p)
2532 flag_ira_loop_pressure = 1;
2534 /* Set the pointer size. */
2537 rs6000_pmode = (int)DImode;
2538 rs6000_pointer_size = 64;
2542 rs6000_pmode = (int)SImode;
2543 rs6000_pointer_size = 32;
2546 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2547 #ifdef OS_MISSING_POWERPC64
2548 if (OS_MISSING_POWERPC64)
2549 set_masks &= ~MASK_POWERPC64;
2551 #ifdef OS_MISSING_ALTIVEC
2552 if (OS_MISSING_ALTIVEC)
2553 set_masks &= ~MASK_ALTIVEC;
2556 /* Don't override by the processor default if given explicitly. */
2557 set_masks &= ~target_flags_explicit;
2559 /* Identify the processor type. */
2562 if (TARGET_POWERPC64)
2563 default_cpu = "powerpc64";
2564 else if (TARGET_POWERPC)
2565 default_cpu = "powerpc";
2568 /* Process the -mcpu=<xxx> and -mtune=<xxx> argument. If the user changed
2569 the cpu in a target attribute or pragma, but did not specify a tuning
2570 option, use the cpu for the tuning option rather than the option specified
2571 with -mtune on the command line. */
2572 if (rs6000_cpu_index > 0)
2573 cpu_index = rs6000_cpu_index;
2574 else if (main_target_opt != NULL && main_target_opt->x_rs6000_cpu_index > 0)
2575 rs6000_cpu_index = cpu_index = main_target_opt->x_rs6000_cpu_index;
2577 rs6000_cpu_index = cpu_index = rs6000_cpu_name_lookup (default_cpu);
2579 if (rs6000_tune_index > 0)
2580 tune_index = rs6000_tune_index;
2582 rs6000_tune_index = tune_index = cpu_index;
2586 target_flags &= ~set_masks;
2587 target_flags |= (processor_target_table[cpu_index].target_enable
2591 rs6000_cpu = ((tune_index >= 0)
2592 ? processor_target_table[tune_index].processor
2594 ? PROCESSOR_DEFAULT64
2595 : PROCESSOR_DEFAULT));
2597 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2598 || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64)
2601 error ("AltiVec not supported in this target");
2603 error ("SPE not supported in this target");
2606 /* Disable Cell microcode if we are optimizing for the Cell
2607 and not optimizing for size. */
2608 if (rs6000_gen_cell_microcode == -1)
2609 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2612 /* If we are optimizing big endian systems for space and it's OK to
2613 use instructions that would be microcoded on the Cell, use the
2614 load/store multiple and string instructions. */
2615 if (BYTES_BIG_ENDIAN && optimize_size && rs6000_gen_cell_microcode)
2616 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2618 /* Don't allow -mmultiple or -mstring on little endian systems
2619 unless the cpu is a 750, because the hardware doesn't support the
2620 instructions used in little endian mode, and causes an alignment
2621 trap. The 750 does not cause an alignment trap (except when the
2622 target is unaligned). */
2624 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2626 if (TARGET_MULTIPLE)
2628 target_flags &= ~MASK_MULTIPLE;
2629 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2630 warning (0, "-mmultiple is not supported on little endian systems");
2635 target_flags &= ~MASK_STRING;
2636 if ((target_flags_explicit & MASK_STRING) != 0)
2637 warning (0, "-mstring is not supported on little endian systems");
2641 /* Add some warnings for VSX. */
2644 const char *msg = NULL;
2645 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2646 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2648 if (target_flags_explicit & MASK_VSX)
2649 msg = N_("-mvsx requires hardware floating point");
2651 target_flags &= ~ MASK_VSX;
2653 else if (TARGET_PAIRED_FLOAT)
2654 msg = N_("-mvsx and -mpaired are incompatible");
2655 /* The hardware will allow VSX and little endian, but until we make sure
2656 things like vector select, etc. work don't allow VSX on little endian
2657 systems at this point. */
2658 else if (!BYTES_BIG_ENDIAN)
2659 msg = N_("-mvsx used with little endian code");
2660 else if (TARGET_AVOID_XFORM > 0)
2661 msg = N_("-mvsx needs indexed addressing");
2662 else if (!TARGET_ALTIVEC && (target_flags_explicit & MASK_ALTIVEC))
2664 if (target_flags_explicit & MASK_VSX)
2665 msg = N_("-mvsx and -mno-altivec are incompatible");
2667 msg = N_("-mno-altivec disables vsx");
2673 target_flags &= ~ MASK_VSX;
2674 target_flags_explicit |= MASK_VSX;
2678 /* For the newer switches (vsx, dfp, etc.) set some of the older options,
2679 unless the user explicitly used the -mno-<option> to disable the code. */
2681 target_flags |= (ISA_2_6_MASKS_SERVER & ~target_flags_explicit);
2682 else if (TARGET_POPCNTD)
2683 target_flags |= (ISA_2_6_MASKS_EMBEDDED & ~target_flags_explicit);
2684 else if (TARGET_DFP)
2685 target_flags |= (ISA_2_5_MASKS_SERVER & ~target_flags_explicit);
2686 else if (TARGET_CMPB)
2687 target_flags |= (ISA_2_5_MASKS_EMBEDDED & ~target_flags_explicit);
2688 else if (TARGET_FPRND)
2689 target_flags |= (ISA_2_4_MASKS & ~target_flags_explicit);
2690 else if (TARGET_POPCNTB)
2691 target_flags |= (ISA_2_2_MASKS & ~target_flags_explicit);
2692 else if (TARGET_ALTIVEC)
2693 target_flags |= (MASK_PPC_GFXOPT & ~target_flags_explicit);
2695 /* E500mc does "better" if we inline more aggressively. Respect the
2696 user's opinion, though. */
2697 if (rs6000_block_move_inline_limit == 0
2698 && (rs6000_cpu == PROCESSOR_PPCE500MC
2699 || rs6000_cpu == PROCESSOR_PPCE500MC64))
2700 rs6000_block_move_inline_limit = 128;
2702 /* store_one_arg depends on expand_block_move to handle at least the
2703 size of reg_parm_stack_space. */
2704 if (rs6000_block_move_inline_limit < (TARGET_POWERPC64 ? 64 : 32))
2705 rs6000_block_move_inline_limit = (TARGET_POWERPC64 ? 64 : 32);
2709 /* If the appropriate debug option is enabled, replace the target hooks
2710 with debug versions that call the real version and then prints
2711 debugging information. */
2712 if (TARGET_DEBUG_COST)
2714 targetm.rtx_costs = rs6000_debug_rtx_costs;
2715 targetm.address_cost = rs6000_debug_address_cost;
2716 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2719 if (TARGET_DEBUG_ADDR)
2721 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2722 targetm.legitimize_address = rs6000_debug_legitimize_address;
2723 rs6000_secondary_reload_class_ptr
2724 = rs6000_debug_secondary_reload_class;
2725 rs6000_secondary_memory_needed_ptr
2726 = rs6000_debug_secondary_memory_needed;
2727 rs6000_cannot_change_mode_class_ptr
2728 = rs6000_debug_cannot_change_mode_class;
2729 rs6000_preferred_reload_class_ptr
2730 = rs6000_debug_preferred_reload_class;
2731 rs6000_legitimize_reload_address_ptr
2732 = rs6000_debug_legitimize_reload_address;
2733 rs6000_mode_dependent_address_ptr
2734 = rs6000_debug_mode_dependent_address;
2737 if (rs6000_veclibabi_name)
2739 if (strcmp (rs6000_veclibabi_name, "mass") == 0)
2740 rs6000_veclib_handler = rs6000_builtin_vectorized_libmass;
2743 error ("unknown vectorization library ABI type (%s) for "
2744 "-mveclibabi= switch", rs6000_veclibabi_name);
2750 if (!global_options_set.x_rs6000_long_double_type_size)
2752 if (main_target_opt != NULL
2753 && (main_target_opt->x_rs6000_long_double_type_size
2754 != RS6000_DEFAULT_LONG_DOUBLE_SIZE))
2755 error ("target attribute or pragma changes long double size");
2757 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2760 #ifndef POWERPC_LINUX
2761 if (!global_options_set.x_rs6000_ieeequad)
2762 rs6000_ieeequad = 1;
2765 /* Disable VSX and Altivec silently if the user switched cpus to power7 in a
2766 target attribute or pragma which automatically enables both options,
2767 unless the altivec ABI was set. This is set by default for 64-bit, but
2769 if (main_target_opt != NULL && !main_target_opt->x_rs6000_altivec_abi)
2770 target_flags &= ~((MASK_VSX | MASK_ALTIVEC) & ~target_flags_explicit);
2772 /* Enable Altivec ABI for AIX -maltivec. */
2773 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2775 if (main_target_opt != NULL && !main_target_opt->x_rs6000_altivec_abi)
2776 error ("target attribute or pragma changes AltiVec ABI");
2778 rs6000_altivec_abi = 1;
2781 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2782 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2783 be explicitly overridden in either case. */
2786 if (!global_options_set.x_rs6000_altivec_abi
2787 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2789 if (main_target_opt != NULL &&
2790 !main_target_opt->x_rs6000_altivec_abi)
2791 error ("target attribute or pragma changes AltiVec ABI");
2793 rs6000_altivec_abi = 1;
2796 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2797 if (!global_options_set.x_TARGET_ALTIVEC_VRSAVE)
2798 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2801 /* Set the Darwin64 ABI as default for 64-bit Darwin.
2802 So far, the only darwin64 targets are also MACH-O. */
2804 && DEFAULT_ABI == ABI_DARWIN
2807 if (main_target_opt != NULL && !main_target_opt->x_rs6000_darwin64_abi)
2808 error ("target attribute or pragma changes darwin64 ABI");
2811 rs6000_darwin64_abi = 1;
2812 /* Default to natural alignment, for better performance. */
2813 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2817 /* Place FP constants in the constant pool instead of TOC
2818 if section anchors enabled. */
2819 if (flag_section_anchors)
2820 TARGET_NO_FP_IN_TOC = 1;
2822 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2823 SUBTARGET_OVERRIDE_OPTIONS;
2825 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2826 SUBSUBTARGET_OVERRIDE_OPTIONS;
2828 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2829 SUB3TARGET_OVERRIDE_OPTIONS;
2832 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC
2833 || rs6000_cpu == PROCESSOR_PPCE500MC64)
2835 /* The e500 and e500mc do not have string instructions, and we set
2836 MASK_STRING above when optimizing for size. */
2837 if ((target_flags & MASK_STRING) != 0)
2838 target_flags = target_flags & ~MASK_STRING;
2840 else if (global_options_set.x_rs6000_cpu_index)
2842 /* For the powerpc-eabispe configuration, we set all these by
2843 default, so let's unset them if we manually set another
2844 CPU that is not the E500. */
2845 if (main_target_opt != NULL
2846 && ((main_target_opt->x_rs6000_spe_abi != rs6000_spe_abi)
2847 || (main_target_opt->x_rs6000_spe != rs6000_spe)
2848 || (main_target_opt->x_rs6000_float_gprs != rs6000_float_gprs)))
2849 error ("target attribute or pragma changes SPE ABI");
2852 if (!global_options_set.x_rs6000_spe_abi)
2854 if (!global_options_set.x_rs6000_spe)
2856 if (!global_options_set.x_rs6000_float_gprs)
2857 rs6000_float_gprs = 0;
2859 if (!(target_flags_explicit & MASK_ISEL))
2860 target_flags &= ~MASK_ISEL;
2863 /* Detect invalid option combinations with E500. */
2866 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
2867 && rs6000_cpu != PROCESSOR_POWER5
2868 && rs6000_cpu != PROCESSOR_POWER6
2869 && rs6000_cpu != PROCESSOR_POWER7
2870 && rs6000_cpu != PROCESSOR_PPCA2
2871 && rs6000_cpu != PROCESSOR_CELL);
2872 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
2873 || rs6000_cpu == PROCESSOR_POWER5
2874 || rs6000_cpu == PROCESSOR_POWER7);
2875 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
2876 || rs6000_cpu == PROCESSOR_POWER5
2877 || rs6000_cpu == PROCESSOR_POWER6
2878 || rs6000_cpu == PROCESSOR_POWER7
2879 || rs6000_cpu == PROCESSOR_PPCE500MC
2880 || rs6000_cpu == PROCESSOR_PPCE500MC64);
2882 /* Allow debug switches to override the above settings. These are set to -1
2883 in rs6000.opt to indicate the user hasn't directly set the switch. */
2884 if (TARGET_ALWAYS_HINT >= 0)
2885 rs6000_always_hint = TARGET_ALWAYS_HINT;
2887 if (TARGET_SCHED_GROUPS >= 0)
2888 rs6000_sched_groups = TARGET_SCHED_GROUPS;
2890 if (TARGET_ALIGN_BRANCH_TARGETS >= 0)
2891 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
2893 rs6000_sched_restricted_insns_priority
2894 = (rs6000_sched_groups ? 1 : 0);
2896 /* Handle -msched-costly-dep option. */
2897 rs6000_sched_costly_dep
2898 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
2900 if (rs6000_sched_costly_dep_str)
2902 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
2903 rs6000_sched_costly_dep = no_dep_costly;
2904 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
2905 rs6000_sched_costly_dep = all_deps_costly;
2906 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
2907 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
2908 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
2909 rs6000_sched_costly_dep = store_to_load_dep_costly;
2911 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
2912 atoi (rs6000_sched_costly_dep_str));
2915 /* Handle -minsert-sched-nops option. */
2916 rs6000_sched_insert_nops
2917 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
2919 if (rs6000_sched_insert_nops_str)
2921 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
2922 rs6000_sched_insert_nops = sched_finish_none;
2923 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
2924 rs6000_sched_insert_nops = sched_finish_pad_groups;
2925 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
2926 rs6000_sched_insert_nops = sched_finish_regroup_exact;
2928 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
2929 atoi (rs6000_sched_insert_nops_str));
2934 #ifdef TARGET_REGNAMES
2935 /* If the user desires alternate register names, copy in the
2936 alternate names now. */
2937 if (TARGET_REGNAMES)
2938 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
2941 /* Set aix_struct_return last, after the ABI is determined.
2942 If -maix-struct-return or -msvr4-struct-return was explicitly
2943 used, don't override with the ABI default. */
2944 if (!global_options_set.x_aix_struct_return)
2945 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
2948 /* IBM XL compiler defaults to unsigned bitfields. */
2949 if (TARGET_XL_COMPAT)
2950 flag_signed_bitfields = 0;
2953 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
2954 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
2957 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
2959 /* We can only guarantee the availability of DI pseudo-ops when
2960 assembling for 64-bit targets. */
2963 targetm.asm_out.aligned_op.di = NULL;
2964 targetm.asm_out.unaligned_op.di = NULL;
2968 /* Set branch target alignment, if not optimizing for size. */
2971 /* Cell wants to be aligned 8byte for dual issue. Titan wants to be
2972 aligned 8byte to avoid misprediction by the branch predictor. */
2973 if (rs6000_cpu == PROCESSOR_TITAN
2974 || rs6000_cpu == PROCESSOR_CELL)
2976 if (align_functions <= 0)
2977 align_functions = 8;
2978 if (align_jumps <= 0)
2980 if (align_loops <= 0)
2983 if (rs6000_align_branch_targets)
2985 if (align_functions <= 0)
2986 align_functions = 16;
2987 if (align_jumps <= 0)
2989 if (align_loops <= 0)
2991 can_override_loop_align = 1;
2995 if (align_jumps_max_skip <= 0)
2996 align_jumps_max_skip = 15;
2997 if (align_loops_max_skip <= 0)
2998 align_loops_max_skip = 15;
3001 /* Arrange to save and restore machine status around nested functions. */
3002 init_machine_status = rs6000_init_machine_status;
3004 /* We should always be splitting complex arguments, but we can't break
3005 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
3006 if (DEFAULT_ABI != ABI_AIX)
3007 targetm.calls.split_complex_arg = NULL;
3010 /* Initialize rs6000_cost with the appropriate target costs. */
3012 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
3016 case PROCESSOR_RIOS1:
3017 rs6000_cost = &rios1_cost;
3020 case PROCESSOR_RIOS2:
3021 rs6000_cost = &rios2_cost;
3024 case PROCESSOR_RS64A:
3025 rs6000_cost = &rs64a_cost;
3028 case PROCESSOR_MPCCORE:
3029 rs6000_cost = &mpccore_cost;
3032 case PROCESSOR_PPC403:
3033 rs6000_cost = &ppc403_cost;
3036 case PROCESSOR_PPC405:
3037 rs6000_cost = &ppc405_cost;
3040 case PROCESSOR_PPC440:
3041 rs6000_cost = &ppc440_cost;
3044 case PROCESSOR_PPC476:
3045 rs6000_cost = &ppc476_cost;
3048 case PROCESSOR_PPC601:
3049 rs6000_cost = &ppc601_cost;
3052 case PROCESSOR_PPC603:
3053 rs6000_cost = &ppc603_cost;
3056 case PROCESSOR_PPC604:
3057 rs6000_cost = &ppc604_cost;
3060 case PROCESSOR_PPC604e:
3061 rs6000_cost = &ppc604e_cost;
3064 case PROCESSOR_PPC620:
3065 rs6000_cost = &ppc620_cost;
3068 case PROCESSOR_PPC630:
3069 rs6000_cost = &ppc630_cost;
3072 case PROCESSOR_CELL:
3073 rs6000_cost = &ppccell_cost;
3076 case PROCESSOR_PPC750:
3077 case PROCESSOR_PPC7400:
3078 rs6000_cost = &ppc750_cost;
3081 case PROCESSOR_PPC7450:
3082 rs6000_cost = &ppc7450_cost;
3085 case PROCESSOR_PPC8540:
3086 rs6000_cost = &ppc8540_cost;
3089 case PROCESSOR_PPCE300C2:
3090 case PROCESSOR_PPCE300C3:
3091 rs6000_cost = &ppce300c2c3_cost;
3094 case PROCESSOR_PPCE500MC:
3095 rs6000_cost = &ppce500mc_cost;
3098 case PROCESSOR_PPCE500MC64:
3099 rs6000_cost = &ppce500mc64_cost;
3102 case PROCESSOR_TITAN:
3103 rs6000_cost = &titan_cost;
3106 case PROCESSOR_POWER4:
3107 case PROCESSOR_POWER5:
3108 rs6000_cost = &power4_cost;
3111 case PROCESSOR_POWER6:
3112 rs6000_cost = &power6_cost;
3115 case PROCESSOR_POWER7:
3116 rs6000_cost = &power7_cost;
3119 case PROCESSOR_PPCA2:
3120 rs6000_cost = &ppca2_cost;
3129 maybe_set_param_value (PARAM_SIMULTANEOUS_PREFETCHES,
3130 rs6000_cost->simultaneous_prefetches,
3131 global_options.x_param_values,
3132 global_options_set.x_param_values);
3133 maybe_set_param_value (PARAM_L1_CACHE_SIZE, rs6000_cost->l1_cache_size,
3134 global_options.x_param_values,
3135 global_options_set.x_param_values);
3136 maybe_set_param_value (PARAM_L1_CACHE_LINE_SIZE,
3137 rs6000_cost->cache_line_size,
3138 global_options.x_param_values,
3139 global_options_set.x_param_values);
3140 maybe_set_param_value (PARAM_L2_CACHE_SIZE, rs6000_cost->l2_cache_size,
3141 global_options.x_param_values,
3142 global_options_set.x_param_values);
3144 /* If using typedef char *va_list, signal that
3145 __builtin_va_start (&ap, 0) can be optimized to
3146 ap = __builtin_next_arg (0). */
3147 if (DEFAULT_ABI != ABI_V4)
3148 targetm.expand_builtin_va_start = NULL;
3151 /* Set up single/double float flags.
3152 If TARGET_HARD_FLOAT is set, but neither single or double is set,
3153 then set both flags. */
3154 if (TARGET_HARD_FLOAT && TARGET_FPRS
3155 && rs6000_single_float == 0 && rs6000_double_float == 0)
3156 rs6000_single_float = rs6000_double_float = 1;
3158 /* Reset single and double FP flags if target is E500. */
3161 rs6000_single_float = rs6000_double_float = 0;
3162 if (TARGET_E500_SINGLE)
3163 rs6000_single_float = 1;
3164 if (TARGET_E500_DOUBLE)
3165 rs6000_single_float = rs6000_double_float = 1;
3168 if (main_target_opt)
3170 if (main_target_opt->x_rs6000_single_float != rs6000_single_float)
3171 error ("target attribute or pragma changes single precision floating "
3173 if (main_target_opt->x_rs6000_double_float != rs6000_double_float)
3174 error ("target attribute or pragma changes double precision floating "
3178 /* If not explicitly specified via option, decide whether to generate indexed
3179 load/store instructions. */
3180 if (TARGET_AVOID_XFORM == -1)
3181 /* Avoid indexed addressing when targeting Power6 in order to avoid the
3182 DERAT mispredict penalty. However the LVE and STVE altivec instructions
3183 need indexed accesses and the type used is the scalar type of the element
3184 being loaded or stored. */
3185 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB
3186 && !TARGET_ALTIVEC);
3188 /* Set the -mrecip options. */
3189 if (rs6000_recip_name)
3191 char *p = ASTRDUP (rs6000_recip_name);
3193 unsigned int mask, i;
3196 while ((q = strtok (p, ",")) != NULL)
3207 if (!strcmp (q, "default"))
3208 mask = ((TARGET_RECIP_PRECISION)
3209 ? RECIP_HIGH_PRECISION : RECIP_LOW_PRECISION);
3212 for (i = 0; i < ARRAY_SIZE (recip_options); i++)
3213 if (!strcmp (q, recip_options[i].string))
3215 mask = recip_options[i].mask;
3219 if (i == ARRAY_SIZE (recip_options))
3221 error ("unknown option for -mrecip=%s", q);
3229 rs6000_recip_control &= ~mask;
3231 rs6000_recip_control |= mask;
3235 rs6000_init_hard_regno_mode_ok (global_init_p);
3237 /* Save the initial options in case the user does function specific options */
3239 target_option_default_node = target_option_current_node
3240 = build_target_option_node ();
3242 /* If not explicitly specified via option, decide whether to generate the
3243 extra blr's required to preserve the link stack on some cpus (eg, 476). */
3244 if (TARGET_LINK_STACK == -1)
3245 SET_TARGET_LINK_STACK (rs6000_cpu == PROCESSOR_PPC476 && flag_pic);
3250 /* Implement TARGET_OPTION_OVERRIDE. On the RS/6000 this is used to
3251 define the target cpu type. */
3254 rs6000_option_override (void)
3256 (void) rs6000_option_override_internal (true);
3260 /* Implement targetm.vectorize.builtin_mask_for_load. */
3262 rs6000_builtin_mask_for_load (void)
3264 if (TARGET_ALTIVEC || TARGET_VSX)
3265 return altivec_builtin_mask_for_load;
3270 /* Implement LOOP_ALIGN. */
3272 rs6000_loop_align (rtx label)
3277 /* Don't override loop alignment if -falign-loops was specified. */
3278 if (!can_override_loop_align)
3279 return align_loops_log;
3281 bb = BLOCK_FOR_INSN (label);
3282 ninsns = num_loop_insns(bb->loop_father);
3284 /* Align small loops to 32 bytes to fit in an icache sector, otherwise return default. */
3285 if (ninsns > 4 && ninsns <= 8
3286 && (rs6000_cpu == PROCESSOR_POWER4
3287 || rs6000_cpu == PROCESSOR_POWER5
3288 || rs6000_cpu == PROCESSOR_POWER6
3289 || rs6000_cpu == PROCESSOR_POWER7))
3292 return align_loops_log;
3295 /* Implement TARGET_LOOP_ALIGN_MAX_SKIP. */
3297 rs6000_loop_align_max_skip (rtx label)
3299 return (1 << rs6000_loop_align (label)) - 1;
3302 /* Implement targetm.vectorize.builtin_conversion.
3303 Returns a decl of a function that implements conversion of an integer vector
3304 into a floating-point vector, or vice-versa. DEST_TYPE is the
3305 destination type and SRC_TYPE the source type of the conversion.
3306 Return NULL_TREE if it is not available. */
3308 rs6000_builtin_conversion (unsigned int tcode, tree dest_type, tree src_type)
3310 enum tree_code code = (enum tree_code) tcode;
3314 case FIX_TRUNC_EXPR:
3315 switch (TYPE_MODE (dest_type))
3318 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3321 return TYPE_UNSIGNED (dest_type)
3322 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
3323 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
3326 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3329 return TYPE_UNSIGNED (dest_type)
3330 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
3331 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
3338 switch (TYPE_MODE (src_type))
3341 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3344 return TYPE_UNSIGNED (src_type)
3345 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
3346 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
3349 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3352 return TYPE_UNSIGNED (src_type)
3353 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
3354 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
3365 /* Implement targetm.vectorize.builtin_mul_widen_even. */
3367 rs6000_builtin_mul_widen_even (tree type)
3369 if (!TARGET_ALTIVEC)
3372 switch (TYPE_MODE (type))
3375 return TYPE_UNSIGNED (type)
3376 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
3377 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
3380 return TYPE_UNSIGNED (type)
3381 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
3382 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
3388 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
3390 rs6000_builtin_mul_widen_odd (tree type)
3392 if (!TARGET_ALTIVEC)
3395 switch (TYPE_MODE (type))
3398 return TYPE_UNSIGNED (type)
3399 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
3400 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
3403 return TYPE_UNSIGNED (type)
3404 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
3405 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
3412 /* Return true iff, data reference of TYPE can reach vector alignment (16)
3413 after applying N number of iterations. This routine does not determine
3414 how may iterations are required to reach desired alignment. */
3417 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
3424 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
3427 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
3437 /* Assuming that all other types are naturally aligned. CHECKME! */
3442 /* Return true if the vector misalignment factor is supported by the
3445 rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
3452 /* Return if movmisalign pattern is not supported for this mode. */
3453 if (optab_handler (movmisalign_optab, mode) == CODE_FOR_nothing)
3456 if (misalignment == -1)
3458 /* Misalignment factor is unknown at compile time but we know
3459 it's word aligned. */
3460 if (rs6000_vector_alignment_reachable (type, is_packed))
3462 int element_size = TREE_INT_CST_LOW (TYPE_SIZE (type));
3464 if (element_size == 64 || element_size == 32)
3471 /* VSX supports word-aligned vector. */
3472 if (misalignment % 4 == 0)
3478 /* Implement targetm.vectorize.builtin_vectorization_cost. */
3480 rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
3481 tree vectype, int misalign)
3485 switch (type_of_cost)
3495 case cond_branch_not_taken:
3499 case cond_branch_taken:
3502 case unaligned_load:
3503 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3505 elements = TYPE_VECTOR_SUBPARTS (vectype);
3507 /* Double word aligned. */
3515 /* Double word aligned. */
3519 /* Unknown misalignment. */
3532 /* Misaligned loads are not supported. */
3537 case unaligned_store:
3538 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3540 elements = TYPE_VECTOR_SUBPARTS (vectype);
3542 /* Double word aligned. */
3550 /* Double word aligned. */
3554 /* Unknown misalignment. */
3567 /* Misaligned stores are not supported. */
3577 /* Implement targetm.vectorize.preferred_simd_mode. */
3579 static enum machine_mode
3580 rs6000_preferred_simd_mode (enum machine_mode mode)
3589 if (TARGET_ALTIVEC || TARGET_VSX)
3613 if (TARGET_PAIRED_FLOAT
3619 /* Handler for the Mathematical Acceleration Subsystem (mass) interface to a
3620 library with vectorized intrinsics. */
3623 rs6000_builtin_vectorized_libmass (tree fndecl, tree type_out, tree type_in)
3626 const char *suffix = NULL;
3627 tree fntype, new_fndecl, bdecl = NULL_TREE;
3630 enum machine_mode el_mode, in_mode;
3633 /* Libmass is suitable for unsafe math only as it does not correctly support
3634 parts of IEEE with the required precision such as denormals. Only support
3635 it if we have VSX to use the simd d2 or f4 functions.
3636 XXX: Add variable length support. */
3637 if (!flag_unsafe_math_optimizations || !TARGET_VSX)
3640 el_mode = TYPE_MODE (TREE_TYPE (type_out));
3641 n = TYPE_VECTOR_SUBPARTS (type_out);
3642 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3643 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3644 if (el_mode != in_mode
3648 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3650 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3653 case BUILT_IN_ATAN2:
3654 case BUILT_IN_HYPOT:
3660 case BUILT_IN_ACOSH:
3662 case BUILT_IN_ASINH:
3664 case BUILT_IN_ATANH:
3672 case BUILT_IN_EXPM1:
3673 case BUILT_IN_LGAMMA:
3674 case BUILT_IN_LOG10:
3675 case BUILT_IN_LOG1P:
3683 bdecl = builtin_decl_implicit (fn);
3684 suffix = "d2"; /* pow -> powd2 */
3685 if (el_mode != DFmode
3690 case BUILT_IN_ATAN2F:
3691 case BUILT_IN_HYPOTF:
3696 case BUILT_IN_ACOSF:
3697 case BUILT_IN_ACOSHF:
3698 case BUILT_IN_ASINF:
3699 case BUILT_IN_ASINHF:
3700 case BUILT_IN_ATANF:
3701 case BUILT_IN_ATANHF:
3702 case BUILT_IN_CBRTF:
3704 case BUILT_IN_COSHF:
3706 case BUILT_IN_ERFCF:
3707 case BUILT_IN_EXP2F:
3709 case BUILT_IN_EXPM1F:
3710 case BUILT_IN_LGAMMAF:
3711 case BUILT_IN_LOG10F:
3712 case BUILT_IN_LOG1PF:
3713 case BUILT_IN_LOG2F:
3716 case BUILT_IN_SINHF:
3717 case BUILT_IN_SQRTF:
3719 case BUILT_IN_TANHF:
3720 bdecl = builtin_decl_implicit (fn);
3721 suffix = "4"; /* powf -> powf4 */
3722 if (el_mode != SFmode
3734 gcc_assert (suffix != NULL);
3735 bname = IDENTIFIER_POINTER (DECL_NAME (bdecl));
3736 strcpy (name, bname + sizeof ("__builtin_") - 1);
3737 strcat (name, suffix);
3740 fntype = build_function_type_list (type_out, type_in, NULL);
3741 else if (n_args == 2)
3742 fntype = build_function_type_list (type_out, type_in, type_in, NULL);
3746 /* Build a function declaration for the vectorized function. */
3747 new_fndecl = build_decl (BUILTINS_LOCATION,
3748 FUNCTION_DECL, get_identifier (name), fntype);
3749 TREE_PUBLIC (new_fndecl) = 1;
3750 DECL_EXTERNAL (new_fndecl) = 1;
3751 DECL_IS_NOVOPS (new_fndecl) = 1;
3752 TREE_READONLY (new_fndecl) = 1;
3757 /* Returns a function decl for a vectorized version of the builtin function
3758 with builtin function code FN and the result vector type TYPE, or NULL_TREE
3759 if it is not available. */
3762 rs6000_builtin_vectorized_function (tree fndecl, tree type_out,
3765 enum machine_mode in_mode, out_mode;
3768 if (TREE_CODE (type_out) != VECTOR_TYPE
3769 || TREE_CODE (type_in) != VECTOR_TYPE
3770 || !TARGET_VECTORIZE_BUILTINS)
3773 out_mode = TYPE_MODE (TREE_TYPE (type_out));
3774 out_n = TYPE_VECTOR_SUBPARTS (type_out);
3775 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3776 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3778 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3780 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3783 case BUILT_IN_COPYSIGN:
3784 if (VECTOR_UNIT_VSX_P (V2DFmode)
3785 && out_mode == DFmode && out_n == 2
3786 && in_mode == DFmode && in_n == 2)
3787 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
3789 case BUILT_IN_COPYSIGNF:
3790 if (out_mode != SFmode || out_n != 4
3791 || in_mode != SFmode || in_n != 4)
3793 if (VECTOR_UNIT_VSX_P (V4SFmode))
3794 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
3795 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3796 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
3799 if (VECTOR_UNIT_VSX_P (V2DFmode)
3800 && out_mode == DFmode && out_n == 2
3801 && in_mode == DFmode && in_n == 2)
3802 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
3804 case BUILT_IN_SQRTF:
3805 if (VECTOR_UNIT_VSX_P (V4SFmode)
3806 && out_mode == SFmode && out_n == 4
3807 && in_mode == SFmode && in_n == 4)
3808 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
3811 if (VECTOR_UNIT_VSX_P (V2DFmode)
3812 && out_mode == DFmode && out_n == 2
3813 && in_mode == DFmode && in_n == 2)
3814 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
3816 case BUILT_IN_CEILF:
3817 if (out_mode != SFmode || out_n != 4
3818 || in_mode != SFmode || in_n != 4)
3820 if (VECTOR_UNIT_VSX_P (V4SFmode))
3821 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
3822 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3823 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
3825 case BUILT_IN_FLOOR:
3826 if (VECTOR_UNIT_VSX_P (V2DFmode)
3827 && out_mode == DFmode && out_n == 2
3828 && in_mode == DFmode && in_n == 2)
3829 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
3831 case BUILT_IN_FLOORF:
3832 if (out_mode != SFmode || out_n != 4
3833 || in_mode != SFmode || in_n != 4)
3835 if (VECTOR_UNIT_VSX_P (V4SFmode))
3836 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
3837 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3838 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
3841 if (VECTOR_UNIT_VSX_P (V2DFmode)
3842 && out_mode == DFmode && out_n == 2
3843 && in_mode == DFmode && in_n == 2)
3844 return rs6000_builtin_decls[VSX_BUILTIN_XVMADDDP];
3847 if (VECTOR_UNIT_VSX_P (V4SFmode)
3848 && out_mode == SFmode && out_n == 4
3849 && in_mode == SFmode && in_n == 4)
3850 return rs6000_builtin_decls[VSX_BUILTIN_XVMADDSP];
3851 else if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)
3852 && out_mode == SFmode && out_n == 4
3853 && in_mode == SFmode && in_n == 4)
3854 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VMADDFP];
3856 case BUILT_IN_TRUNC:
3857 if (VECTOR_UNIT_VSX_P (V2DFmode)
3858 && out_mode == DFmode && out_n == 2
3859 && in_mode == DFmode && in_n == 2)
3860 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
3862 case BUILT_IN_TRUNCF:
3863 if (out_mode != SFmode || out_n != 4
3864 || in_mode != SFmode || in_n != 4)
3866 if (VECTOR_UNIT_VSX_P (V4SFmode))
3867 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
3868 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3869 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
3871 case BUILT_IN_NEARBYINT:
3872 if (VECTOR_UNIT_VSX_P (V2DFmode)
3873 && flag_unsafe_math_optimizations
3874 && out_mode == DFmode && out_n == 2
3875 && in_mode == DFmode && in_n == 2)
3876 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
3878 case BUILT_IN_NEARBYINTF:
3879 if (VECTOR_UNIT_VSX_P (V4SFmode)
3880 && flag_unsafe_math_optimizations
3881 && out_mode == SFmode && out_n == 4
3882 && in_mode == SFmode && in_n == 4)
3883 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
3886 if (VECTOR_UNIT_VSX_P (V2DFmode)
3887 && !flag_trapping_math
3888 && out_mode == DFmode && out_n == 2
3889 && in_mode == DFmode && in_n == 2)
3890 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
3892 case BUILT_IN_RINTF:
3893 if (VECTOR_UNIT_VSX_P (V4SFmode)
3894 && !flag_trapping_math
3895 && out_mode == SFmode && out_n == 4
3896 && in_mode == SFmode && in_n == 4)
3897 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
3904 else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
3906 enum rs6000_builtins fn
3907 = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl);
3910 case RS6000_BUILTIN_RSQRTF:
3911 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
3912 && out_mode == SFmode && out_n == 4
3913 && in_mode == SFmode && in_n == 4)
3914 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRSQRTFP];
3916 case RS6000_BUILTIN_RSQRT:
3917 if (VECTOR_UNIT_VSX_P (V2DFmode)
3918 && out_mode == DFmode && out_n == 2
3919 && in_mode == DFmode && in_n == 2)
3920 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
3922 case RS6000_BUILTIN_RECIPF:
3923 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
3924 && out_mode == SFmode && out_n == 4
3925 && in_mode == SFmode && in_n == 4)
3926 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRECIPFP];
3928 case RS6000_BUILTIN_RECIP:
3929 if (VECTOR_UNIT_VSX_P (V2DFmode)
3930 && out_mode == DFmode && out_n == 2
3931 && in_mode == DFmode && in_n == 2)
3932 return rs6000_builtin_decls[VSX_BUILTIN_RECIP_V2DF];
3939 /* Generate calls to libmass if appropriate. */
3940 if (rs6000_veclib_handler)
3941 return rs6000_veclib_handler (fndecl, type_out, type_in);
3946 /* Default CPU string for rs6000*_file_start functions. */
3947 static const char *rs6000_default_cpu;
3949 /* Do anything needed at the start of the asm file. */
3952 rs6000_file_start (void)
3955 const char *start = buffer;
3956 FILE *file = asm_out_file;
3958 rs6000_default_cpu = TARGET_CPU_DEFAULT;
3960 default_file_start ();
3962 #ifdef TARGET_BI_ARCH
3963 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
3964 rs6000_default_cpu = 0;
3967 if (flag_verbose_asm)
3969 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
3971 if (rs6000_default_cpu != 0 && rs6000_default_cpu[0] != '\0')
3973 fprintf (file, "%s --with-cpu=%s", start, rs6000_default_cpu);
3977 if (global_options_set.x_rs6000_cpu_index)
3979 fprintf (file, "%s -mcpu=%s", start,
3980 processor_target_table[rs6000_cpu_index].name);
3984 if (global_options_set.x_rs6000_tune_index)
3986 fprintf (file, "%s -mtune=%s", start,
3987 processor_target_table[rs6000_tune_index].name);
3991 if (PPC405_ERRATUM77)
3993 fprintf (file, "%s PPC405CR_ERRATUM77", start);
3997 #ifdef USING_ELFOS_H
3998 switch (rs6000_sdata)
4000 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
4001 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
4002 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
4003 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
4006 if (rs6000_sdata && g_switch_value)
4008 fprintf (file, "%s -G %d", start,
4018 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
4020 switch_to_section (toc_section);
4021 switch_to_section (text_section);
4026 /* Return nonzero if this function is known to have a null epilogue. */
4029 direct_return (void)
4031 if (reload_completed)
4033 rs6000_stack_t *info = rs6000_stack_info ();
4035 if (info->first_gp_reg_save == 32
4036 && info->first_fp_reg_save == 64
4037 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
4038 && ! info->lr_save_p
4039 && ! info->cr_save_p
4040 && info->vrsave_mask == 0
4048 /* Return the number of instructions it takes to form a constant in an
4049 integer register. */
4052 num_insns_constant_wide (HOST_WIDE_INT value)
4054 /* signed constant loadable with {cal|addi} */
4055 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
4058 /* constant loadable with {cau|addis} */
4059 else if ((value & 0xffff) == 0
4060 && (value >> 31 == -1 || value >> 31 == 0))
4063 #if HOST_BITS_PER_WIDE_INT == 64
4064 else if (TARGET_POWERPC64)
4066 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
4067 HOST_WIDE_INT high = value >> 31;
4069 if (high == 0 || high == -1)
4075 return num_insns_constant_wide (high) + 1;
4077 return num_insns_constant_wide (low) + 1;
4079 return (num_insns_constant_wide (high)
4080 + num_insns_constant_wide (low) + 1);
4089 num_insns_constant (rtx op, enum machine_mode mode)
4091 HOST_WIDE_INT low, high;
4093 switch (GET_CODE (op))
4096 #if HOST_BITS_PER_WIDE_INT == 64
4097 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
4098 && mask64_operand (op, mode))
4102 return num_insns_constant_wide (INTVAL (op));
4105 if (mode == SFmode || mode == SDmode)
4110 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4111 if (DECIMAL_FLOAT_MODE_P (mode))
4112 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
4114 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
4115 return num_insns_constant_wide ((HOST_WIDE_INT) l);
4118 if (mode == VOIDmode || mode == DImode)
4120 high = CONST_DOUBLE_HIGH (op);
4121 low = CONST_DOUBLE_LOW (op);
4128 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4129 if (DECIMAL_FLOAT_MODE_P (mode))
4130 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
4132 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
4133 high = l[WORDS_BIG_ENDIAN == 0];
4134 low = l[WORDS_BIG_ENDIAN != 0];
4138 return (num_insns_constant_wide (low)
4139 + num_insns_constant_wide (high));
4142 if ((high == 0 && low >= 0)
4143 || (high == -1 && low < 0))
4144 return num_insns_constant_wide (low);
4146 else if (mask64_operand (op, mode))
4150 return num_insns_constant_wide (high) + 1;
4153 return (num_insns_constant_wide (high)
4154 + num_insns_constant_wide (low) + 1);
4162 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
4163 If the mode of OP is MODE_VECTOR_INT, this simply returns the
4164 corresponding element of the vector, but for V4SFmode and V2SFmode,
4165 the corresponding "float" is interpreted as an SImode integer. */
4168 const_vector_elt_as_int (rtx op, unsigned int elt)
4172 /* We can't handle V2DImode and V2DFmode vector constants here yet. */
4173 gcc_assert (GET_MODE (op) != V2DImode
4174 && GET_MODE (op) != V2DFmode);
4176 tmp = CONST_VECTOR_ELT (op, elt);
4177 if (GET_MODE (op) == V4SFmode
4178 || GET_MODE (op) == V2SFmode)
4179 tmp = gen_lowpart (SImode, tmp);
4180 return INTVAL (tmp);
4183 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
4184 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
4185 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
4186 all items are set to the same value and contain COPIES replicas of the
4187 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
4188 operand and the others are set to the value of the operand's msb. */
4191 vspltis_constant (rtx op, unsigned step, unsigned copies)
4193 enum machine_mode mode = GET_MODE (op);
4194 enum machine_mode inner = GET_MODE_INNER (mode);
4202 HOST_WIDE_INT splat_val;
4203 HOST_WIDE_INT msb_val;
4205 if (mode == V2DImode || mode == V2DFmode)
4208 nunits = GET_MODE_NUNITS (mode);
4209 bitsize = GET_MODE_BITSIZE (inner);
4210 mask = GET_MODE_MASK (inner);
4212 val = const_vector_elt_as_int (op, nunits - 1);
4214 msb_val = val > 0 ? 0 : -1;
4216 /* Construct the value to be splatted, if possible. If not, return 0. */
4217 for (i = 2; i <= copies; i *= 2)
4219 HOST_WIDE_INT small_val;
4221 small_val = splat_val >> bitsize;
4223 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
4225 splat_val = small_val;
4228 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
4229 if (EASY_VECTOR_15 (splat_val))
4232 /* Also check if we can splat, and then add the result to itself. Do so if
4233 the value is positive, of if the splat instruction is using OP's mode;
4234 for splat_val < 0, the splat and the add should use the same mode. */
4235 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
4236 && (splat_val >= 0 || (step == 1 && copies == 1)))
4239 /* Also check if are loading up the most significant bit which can be done by
4240 loading up -1 and shifting the value left by -1. */
4241 else if (EASY_VECTOR_MSB (splat_val, inner))
4247 /* Check if VAL is present in every STEP-th element, and the
4248 other elements are filled with its most significant bit. */
4249 for (i = 0; i < nunits - 1; ++i)
4251 HOST_WIDE_INT desired_val;
4252 if (((i + 1) & (step - 1)) == 0)
4255 desired_val = msb_val;
4257 if (desired_val != const_vector_elt_as_int (op, i))
4265 /* Return true if OP is of the given MODE and can be synthesized
4266 with a vspltisb, vspltish or vspltisw. */
4269 easy_altivec_constant (rtx op, enum machine_mode mode)
4271 unsigned step, copies;
4273 if (mode == VOIDmode)
4274 mode = GET_MODE (op);
4275 else if (mode != GET_MODE (op))
4278 /* V2DI/V2DF was added with VSX. Only allow 0 and all 1's as easy
4280 if (mode == V2DFmode)
4281 return zero_constant (op, mode);
4283 if (mode == V2DImode)
4285 /* In case the compiler is built 32-bit, CONST_DOUBLE constants are not
4287 if (GET_CODE (CONST_VECTOR_ELT (op, 0)) != CONST_INT
4288 || GET_CODE (CONST_VECTOR_ELT (op, 1)) != CONST_INT)
4291 if (zero_constant (op, mode))
4294 if (INTVAL (CONST_VECTOR_ELT (op, 0)) == -1
4295 && INTVAL (CONST_VECTOR_ELT (op, 1)) == -1)
4301 /* Start with a vspltisw. */
4302 step = GET_MODE_NUNITS (mode) / 4;
4305 if (vspltis_constant (op, step, copies))
4308 /* Then try with a vspltish. */
4314 if (vspltis_constant (op, step, copies))
4317 /* And finally a vspltisb. */
4323 if (vspltis_constant (op, step, copies))
4329 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
4330 result is OP. Abort if it is not possible. */
4333 gen_easy_altivec_constant (rtx op)
4335 enum machine_mode mode = GET_MODE (op);
4336 int nunits = GET_MODE_NUNITS (mode);
4337 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
4338 unsigned step = nunits / 4;
4339 unsigned copies = 1;
4341 /* Start with a vspltisw. */
4342 if (vspltis_constant (op, step, copies))
4343 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
4345 /* Then try with a vspltish. */
4351 if (vspltis_constant (op, step, copies))
4352 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
4354 /* And finally a vspltisb. */
4360 if (vspltis_constant (op, step, copies))
4361 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
4367 output_vec_const_move (rtx *operands)
4370 enum machine_mode mode;
4375 mode = GET_MODE (dest);
4379 if (zero_constant (vec, mode))
4380 return "xxlxor %x0,%x0,%x0";
4382 if (mode == V2DImode
4383 && INTVAL (CONST_VECTOR_ELT (vec, 0)) == -1
4384 && INTVAL (CONST_VECTOR_ELT (vec, 1)) == -1)
4385 return "vspltisw %0,-1";
4391 if (zero_constant (vec, mode))
4392 return "vxor %0,%0,%0";
4394 splat_vec = gen_easy_altivec_constant (vec);
4395 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
4396 operands[1] = XEXP (splat_vec, 0);
4397 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
4400 switch (GET_MODE (splat_vec))
4403 return "vspltisw %0,%1";
4406 return "vspltish %0,%1";
4409 return "vspltisb %0,%1";
4416 gcc_assert (TARGET_SPE);
4418 /* Vector constant 0 is handled as a splitter of V2SI, and in the
4419 pattern of V1DI, V4HI, and V2SF.
4421 FIXME: We should probably return # and add post reload
4422 splitters for these, but this way is so easy ;-). */
4423 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
4424 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
4425 operands[1] = CONST_VECTOR_ELT (vec, 0);
4426 operands[2] = CONST_VECTOR_ELT (vec, 1);
4428 return "li %0,%1\n\tevmergelo %0,%0,%0";
4430 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
4433 /* Initialize TARGET of vector PAIRED to VALS. */
4436 paired_expand_vector_init (rtx target, rtx vals)
4438 enum machine_mode mode = GET_MODE (target);
4439 int n_elts = GET_MODE_NUNITS (mode);
4441 rtx x, new_rtx, tmp, constant_op, op1, op2;
4444 for (i = 0; i < n_elts; ++i)
4446 x = XVECEXP (vals, 0, i);
4447 if (!(CONST_INT_P (x)
4448 || GET_CODE (x) == CONST_DOUBLE
4449 || GET_CODE (x) == CONST_FIXED))
4454 /* Load from constant pool. */
4455 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
4461 /* The vector is initialized only with non-constants. */
4462 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
4463 XVECEXP (vals, 0, 1));
4465 emit_move_insn (target, new_rtx);
4469 /* One field is non-constant and the other one is a constant. Load the
4470 constant from the constant pool and use ps_merge instruction to
4471 construct the whole vector. */
4472 op1 = XVECEXP (vals, 0, 0);
4473 op2 = XVECEXP (vals, 0, 1);
4475 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
4477 tmp = gen_reg_rtx (GET_MODE (constant_op));
4478 emit_move_insn (tmp, constant_op);
4480 if (CONSTANT_P (op1))
4481 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
4483 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
4485 emit_move_insn (target, new_rtx);
4489 paired_expand_vector_move (rtx operands[])
4491 rtx op0 = operands[0], op1 = operands[1];
4493 emit_move_insn (op0, op1);
4496 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
4497 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
4498 operands for the relation operation COND. This is a recursive
4502 paired_emit_vector_compare (enum rtx_code rcode,
4503 rtx dest, rtx op0, rtx op1,
4504 rtx cc_op0, rtx cc_op1)
4506 rtx tmp = gen_reg_rtx (V2SFmode);
4509 gcc_assert (TARGET_PAIRED_FLOAT);
4510 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
4516 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4520 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4521 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
4525 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
4528 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4531 tmp1 = gen_reg_rtx (V2SFmode);
4532 max = gen_reg_rtx (V2SFmode);
4533 min = gen_reg_rtx (V2SFmode);
4534 gen_reg_rtx (V2SFmode);
4536 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4537 emit_insn (gen_selv2sf4
4538 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4539 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
4540 emit_insn (gen_selv2sf4
4541 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4542 emit_insn (gen_subv2sf3 (tmp1, min, max));
4543 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
4546 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
4549 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4552 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
4555 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4558 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
4567 /* Emit vector conditional expression.
4568 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
4569 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
4572 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
4573 rtx cond, rtx cc_op0, rtx cc_op1)
4575 enum rtx_code rcode = GET_CODE (cond);
4577 if (!TARGET_PAIRED_FLOAT)
4580 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
4585 /* Initialize vector TARGET to VALS. */
4588 rs6000_expand_vector_init (rtx target, rtx vals)
4590 enum machine_mode mode = GET_MODE (target);
4591 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4592 int n_elts = GET_MODE_NUNITS (mode);
4593 int n_var = 0, one_var = -1;
4594 bool all_same = true, all_const_zero = true;
4598 for (i = 0; i < n_elts; ++i)
4600 x = XVECEXP (vals, 0, i);
4601 if (!(CONST_INT_P (x)
4602 || GET_CODE (x) == CONST_DOUBLE
4603 || GET_CODE (x) == CONST_FIXED))
4604 ++n_var, one_var = i;
4605 else if (x != CONST0_RTX (inner_mode))
4606 all_const_zero = false;
4608 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
4614 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
4615 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
4616 if ((int_vector_p || TARGET_VSX) && all_const_zero)
4618 /* Zero register. */
4619 emit_insn (gen_rtx_SET (VOIDmode, target,
4620 gen_rtx_XOR (mode, target, target)));
4623 else if (int_vector_p && easy_vector_constant (const_vec, mode))
4625 /* Splat immediate. */
4626 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
4631 /* Load from constant pool. */
4632 emit_move_insn (target, const_vec);
4637 /* Double word values on VSX can use xxpermdi or lxvdsx. */
4638 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4642 rtx element = XVECEXP (vals, 0, 0);
4643 if (mode == V2DFmode)
4644 emit_insn (gen_vsx_splat_v2df (target, element));
4646 emit_insn (gen_vsx_splat_v2di (target, element));
4650 if (mode == V2DFmode)
4652 rtx op0 = copy_to_mode_reg (DFmode, XVECEXP (vals, 0, 0));
4653 rtx op1 = copy_to_mode_reg (DFmode, XVECEXP (vals, 0, 1));
4654 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
4658 rtx op0 = copy_to_mode_reg (DImode, XVECEXP (vals, 0, 0));
4659 rtx op1 = copy_to_mode_reg (DImode, XVECEXP (vals, 0, 1));
4660 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
4666 /* With single precision floating point on VSX, know that internally single
4667 precision is actually represented as a double, and either make 2 V2DF
4668 vectors, and convert these vectors to single precision, or do one
4669 conversion, and splat the result to the other elements. */
4670 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
4674 rtx freg = gen_reg_rtx (V4SFmode);
4675 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
4677 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
4678 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
4682 rtx dbl_even = gen_reg_rtx (V2DFmode);
4683 rtx dbl_odd = gen_reg_rtx (V2DFmode);
4684 rtx flt_even = gen_reg_rtx (V4SFmode);
4685 rtx flt_odd = gen_reg_rtx (V4SFmode);
4687 emit_insn (gen_vsx_concat_v2sf (dbl_even,
4688 copy_to_reg (XVECEXP (vals, 0, 0)),
4689 copy_to_reg (XVECEXP (vals, 0, 1))));
4690 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
4691 copy_to_reg (XVECEXP (vals, 0, 2)),
4692 copy_to_reg (XVECEXP (vals, 0, 3))));
4693 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
4694 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
4695 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
4700 /* Store value to stack temp. Load vector element. Splat. However, splat
4701 of 64-bit items is not supported on Altivec. */
4702 if (all_same && GET_MODE_SIZE (inner_mode) <= 4)
4704 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4705 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
4706 XVECEXP (vals, 0, 0));
4707 x = gen_rtx_UNSPEC (VOIDmode,
4708 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4709 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4711 gen_rtx_SET (VOIDmode,
4714 x = gen_rtx_VEC_SELECT (inner_mode, target,
4715 gen_rtx_PARALLEL (VOIDmode,
4716 gen_rtvec (1, const0_rtx)));
4717 emit_insn (gen_rtx_SET (VOIDmode, target,
4718 gen_rtx_VEC_DUPLICATE (mode, x)));
4722 /* One field is non-constant. Load constant then overwrite
4726 rtx copy = copy_rtx (vals);
4728 /* Load constant part of vector, substitute neighboring value for
4730 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
4731 rs6000_expand_vector_init (target, copy);
4733 /* Insert variable. */
4734 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
4738 /* Construct the vector in memory one field at a time
4739 and load the whole vector. */
4740 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4741 for (i = 0; i < n_elts; i++)
4742 emit_move_insn (adjust_address_nv (mem, inner_mode,
4743 i * GET_MODE_SIZE (inner_mode)),
4744 XVECEXP (vals, 0, i));
4745 emit_move_insn (target, mem);
4748 /* Set field ELT of TARGET to VAL. */
4751 rs6000_expand_vector_set (rtx target, rtx val, int elt)
4753 enum machine_mode mode = GET_MODE (target);
4754 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4755 rtx reg = gen_reg_rtx (mode);
4757 int width = GET_MODE_SIZE (inner_mode);
4760 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4762 rtx (*set_func) (rtx, rtx, rtx, rtx)
4763 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
4764 emit_insn (set_func (target, target, val, GEN_INT (elt)));
4768 /* Load single variable value. */
4769 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4770 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
4771 x = gen_rtx_UNSPEC (VOIDmode,
4772 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4773 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4775 gen_rtx_SET (VOIDmode,
4779 /* Linear sequence. */
4780 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
4781 for (i = 0; i < 16; ++i)
4782 XVECEXP (mask, 0, i) = GEN_INT (i);
4784 /* Set permute mask to insert element into target. */
4785 for (i = 0; i < width; ++i)
4786 XVECEXP (mask, 0, elt*width + i)
4787 = GEN_INT (i + 0x10);
4788 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
4789 x = gen_rtx_UNSPEC (mode,
4790 gen_rtvec (3, target, reg,
4791 force_reg (V16QImode, x)),
4793 emit_insn (gen_rtx_SET (VOIDmode, target, x));
4796 /* Extract field ELT from VEC into TARGET. */
4799 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
4801 enum machine_mode mode = GET_MODE (vec);
4802 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4805 if (VECTOR_MEM_VSX_P (mode))
4812 emit_insn (gen_vsx_extract_v2df (target, vec, GEN_INT (elt)));
4815 emit_insn (gen_vsx_extract_v2di (target, vec, GEN_INT (elt)));
4818 emit_insn (gen_vsx_extract_v4sf (target, vec, GEN_INT (elt)));
4823 /* Allocate mode-sized buffer. */
4824 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4826 emit_move_insn (mem, vec);
4828 /* Add offset to field within buffer matching vector element. */
4829 mem = adjust_address_nv (mem, inner_mode, elt * GET_MODE_SIZE (inner_mode));
4831 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
4834 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
4835 implement ANDing by the mask IN. */
4837 build_mask64_2_operands (rtx in, rtx *out)
4839 #if HOST_BITS_PER_WIDE_INT >= 64
4840 unsigned HOST_WIDE_INT c, lsb, m1, m2;
4843 gcc_assert (GET_CODE (in) == CONST_INT);
4848 /* Assume c initially something like 0x00fff000000fffff. The idea
4849 is to rotate the word so that the middle ^^^^^^ group of zeros
4850 is at the MS end and can be cleared with an rldicl mask. We then
4851 rotate back and clear off the MS ^^ group of zeros with a
4853 c = ~c; /* c == 0xff000ffffff00000 */
4854 lsb = c & -c; /* lsb == 0x0000000000100000 */
4855 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
4856 c = ~c; /* c == 0x00fff000000fffff */
4857 c &= -lsb; /* c == 0x00fff00000000000 */
4858 lsb = c & -c; /* lsb == 0x0000100000000000 */
4859 c = ~c; /* c == 0xff000fffffffffff */
4860 c &= -lsb; /* c == 0xff00000000000000 */
4862 while ((lsb >>= 1) != 0)
4863 shift++; /* shift == 44 on exit from loop */
4864 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
4865 m1 = ~m1; /* m1 == 0x000000ffffffffff */
4866 m2 = ~c; /* m2 == 0x00ffffffffffffff */
4870 /* Assume c initially something like 0xff000f0000000000. The idea
4871 is to rotate the word so that the ^^^ middle group of zeros
4872 is at the LS end and can be cleared with an rldicr mask. We then
4873 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
4875 lsb = c & -c; /* lsb == 0x0000010000000000 */
4876 m2 = -lsb; /* m2 == 0xffffff0000000000 */
4877 c = ~c; /* c == 0x00fff0ffffffffff */
4878 c &= -lsb; /* c == 0x00fff00000000000 */
4879 lsb = c & -c; /* lsb == 0x0000100000000000 */
4880 c = ~c; /* c == 0xff000fffffffffff */
4881 c &= -lsb; /* c == 0xff00000000000000 */
4883 while ((lsb >>= 1) != 0)
4884 shift++; /* shift == 44 on exit from loop */
4885 m1 = ~c; /* m1 == 0x00ffffffffffffff */
4886 m1 >>= shift; /* m1 == 0x0000000000000fff */
4887 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
4890 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
4891 masks will be all 1's. We are guaranteed more than one transition. */
4892 out[0] = GEN_INT (64 - shift);
4893 out[1] = GEN_INT (m1);
4894 out[2] = GEN_INT (shift);
4895 out[3] = GEN_INT (m2);
4903 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
4906 invalid_e500_subreg (rtx op, enum machine_mode mode)
4908 if (TARGET_E500_DOUBLE)
4910 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
4911 subreg:TI and reg:TF. Decimal float modes are like integer
4912 modes (only low part of each register used) for this
4914 if (GET_CODE (op) == SUBREG
4915 && (mode == SImode || mode == DImode || mode == TImode
4916 || mode == DDmode || mode == TDmode)
4917 && REG_P (SUBREG_REG (op))
4918 && (GET_MODE (SUBREG_REG (op)) == DFmode
4919 || GET_MODE (SUBREG_REG (op)) == TFmode))
4922 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
4924 if (GET_CODE (op) == SUBREG
4925 && (mode == DFmode || mode == TFmode)
4926 && REG_P (SUBREG_REG (op))
4927 && (GET_MODE (SUBREG_REG (op)) == DImode
4928 || GET_MODE (SUBREG_REG (op)) == TImode
4929 || GET_MODE (SUBREG_REG (op)) == DDmode
4930 || GET_MODE (SUBREG_REG (op)) == TDmode))
4935 && GET_CODE (op) == SUBREG
4937 && REG_P (SUBREG_REG (op))
4938 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
4944 /* AIX increases natural record alignment to doubleword if the first
4945 field is an FP double while the FP fields remain word aligned. */
4948 rs6000_special_round_type_align (tree type, unsigned int computed,
4949 unsigned int specified)
4951 unsigned int align = MAX (computed, specified);
4952 tree field = TYPE_FIELDS (type);
4954 /* Skip all non field decls */
4955 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4956 field = DECL_CHAIN (field);
4958 if (field != NULL && field != type)
4960 type = TREE_TYPE (field);
4961 while (TREE_CODE (type) == ARRAY_TYPE)
4962 type = TREE_TYPE (type);
4964 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
4965 align = MAX (align, 64);
4971 /* Darwin increases record alignment to the natural alignment of
4975 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
4976 unsigned int specified)
4978 unsigned int align = MAX (computed, specified);
4980 if (TYPE_PACKED (type))
4983 /* Find the first field, looking down into aggregates. */
4985 tree field = TYPE_FIELDS (type);
4986 /* Skip all non field decls */
4987 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4988 field = DECL_CHAIN (field);
4991 /* A packed field does not contribute any extra alignment. */
4992 if (DECL_PACKED (field))
4994 type = TREE_TYPE (field);
4995 while (TREE_CODE (type) == ARRAY_TYPE)
4996 type = TREE_TYPE (type);
4997 } while (AGGREGATE_TYPE_P (type));
4999 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
5000 align = MAX (align, TYPE_ALIGN (type));
5005 /* Return 1 for an operand in small memory on V.4/eabi. */
5008 small_data_operand (rtx op ATTRIBUTE_UNUSED,
5009 enum machine_mode mode ATTRIBUTE_UNUSED)
5014 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
5017 if (DEFAULT_ABI != ABI_V4)
5020 /* Vector and float memory instructions have a limited offset on the
5021 SPE, so using a vector or float variable directly as an operand is
5024 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
5027 if (GET_CODE (op) == SYMBOL_REF)
5030 else if (GET_CODE (op) != CONST
5031 || GET_CODE (XEXP (op, 0)) != PLUS
5032 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
5033 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
5038 rtx sum = XEXP (op, 0);
5039 HOST_WIDE_INT summand;
5041 /* We have to be careful here, because it is the referenced address
5042 that must be 32k from _SDA_BASE_, not just the symbol. */
5043 summand = INTVAL (XEXP (sum, 1));
5044 if (summand < 0 || summand > g_switch_value)
5047 sym_ref = XEXP (sum, 0);
5050 return SYMBOL_REF_SMALL_P (sym_ref);
5056 /* Return true if either operand is a general purpose register. */
5059 gpr_or_gpr_p (rtx op0, rtx op1)
5061 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
5062 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
5066 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
5069 reg_offset_addressing_ok_p (enum machine_mode mode)
5079 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
5080 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
5088 /* Paired vector modes. Only reg+reg addressing is valid. */
5089 if (TARGET_PAIRED_FLOAT)
5101 virtual_stack_registers_memory_p (rtx op)
5105 if (GET_CODE (op) == REG)
5106 regnum = REGNO (op);
5108 else if (GET_CODE (op) == PLUS
5109 && GET_CODE (XEXP (op, 0)) == REG
5110 && GET_CODE (XEXP (op, 1)) == CONST_INT)
5111 regnum = REGNO (XEXP (op, 0));
5116 return (regnum >= FIRST_VIRTUAL_REGISTER
5117 && regnum <= LAST_VIRTUAL_POINTER_REGISTER);
5120 /* Return true if memory accesses to OP are known to never straddle
5124 offsettable_ok_by_alignment (rtx op, HOST_WIDE_INT offset,
5125 enum machine_mode mode)
5128 unsigned HOST_WIDE_INT dsize, dalign;
5130 if (GET_CODE (op) != SYMBOL_REF)
5133 decl = SYMBOL_REF_DECL (op);
5136 if (GET_MODE_SIZE (mode) == 0)
5139 /* -fsection-anchors loses the original SYMBOL_REF_DECL when
5140 replacing memory addresses with an anchor plus offset. We
5141 could find the decl by rummaging around in the block->objects
5142 VEC for the given offset but that seems like too much work. */
5144 if (SYMBOL_REF_HAS_BLOCK_INFO_P (op)
5145 && SYMBOL_REF_ANCHOR_P (op)
5146 && SYMBOL_REF_BLOCK (op) != NULL)
5148 struct object_block *block = SYMBOL_REF_BLOCK (op);
5149 HOST_WIDE_INT lsb, mask;
5151 /* Given the alignment of the block.. */
5152 dalign = block->alignment;
5153 mask = dalign / BITS_PER_UNIT - 1;
5155 /* ..and the combined offset of the anchor and any offset
5156 to this block object.. */
5157 offset += SYMBOL_REF_BLOCK_OFFSET (op);
5158 lsb = offset & -offset;
5160 /* ..find how many bits of the alignment we know for the
5165 return dalign >= GET_MODE_SIZE (mode);
5170 if (TREE_CODE (decl) == FUNCTION_DECL)
5173 if (!DECL_SIZE_UNIT (decl))
5176 if (!host_integerp (DECL_SIZE_UNIT (decl), 1))
5179 dsize = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
5183 dalign = DECL_ALIGN_UNIT (decl);
5184 return dalign >= dsize;
5187 type = TREE_TYPE (decl);
5189 if (TREE_CODE (decl) == STRING_CST)
5190 dsize = TREE_STRING_LENGTH (decl);
5191 else if (TYPE_SIZE_UNIT (type)
5192 && host_integerp (TYPE_SIZE_UNIT (type), 1))
5193 dsize = tree_low_cst (TYPE_SIZE_UNIT (type), 1);
5199 dalign = TYPE_ALIGN (type);
5200 if (CONSTANT_CLASS_P (decl))
5201 dalign = CONSTANT_ALIGNMENT (decl, dalign);
5203 dalign = DATA_ALIGNMENT (decl, dalign);
5204 dalign /= BITS_PER_UNIT;
5205 return dalign >= dsize;
5209 constant_pool_expr_p (rtx op)
5213 split_const (op, &base, &offset);
5214 return (GET_CODE (base) == SYMBOL_REF
5215 && CONSTANT_POOL_ADDRESS_P (base)
5216 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
5219 static rtx tocrel_base, tocrel_offset;
5222 toc_relative_expr_p (rtx op)
5224 if (GET_CODE (op) != CONST)
5227 split_const (op, &tocrel_base, &tocrel_offset);
5228 return (GET_CODE (tocrel_base) == UNSPEC
5229 && XINT (tocrel_base, 1) == UNSPEC_TOCREL);
5232 /* Return true if X is a constant pool address, and also for cmodel=medium
5233 if X is a toc-relative address known to be offsettable within MODE. */
5236 legitimate_constant_pool_address_p (const_rtx x, enum machine_mode mode,
5240 && (GET_CODE (x) == PLUS || GET_CODE (x) == LO_SUM)
5241 && GET_CODE (XEXP (x, 0)) == REG
5242 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5243 || ((TARGET_MINIMAL_TOC
5244 || TARGET_CMODEL != CMODEL_SMALL)
5245 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict)))
5246 && toc_relative_expr_p (XEXP (x, 1))
5247 && (TARGET_CMODEL != CMODEL_MEDIUM
5248 || constant_pool_expr_p (XVECEXP (tocrel_base, 0, 0))
5250 || offsettable_ok_by_alignment (XVECEXP (tocrel_base, 0, 0),
5251 INTVAL (tocrel_offset), mode)));
5255 legitimate_small_data_p (enum machine_mode mode, rtx x)
5257 return (DEFAULT_ABI == ABI_V4
5258 && !flag_pic && !TARGET_TOC
5259 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
5260 && small_data_operand (x, mode));
5263 /* SPE offset addressing is limited to 5-bits worth of double words. */
5264 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
5267 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
5269 unsigned HOST_WIDE_INT offset, extra;
5271 if (GET_CODE (x) != PLUS)
5273 if (GET_CODE (XEXP (x, 0)) != REG)
5275 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5277 if (!reg_offset_addressing_ok_p (mode))
5278 return virtual_stack_registers_memory_p (x);
5279 if (legitimate_constant_pool_address_p (x, mode, strict))
5281 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5284 offset = INTVAL (XEXP (x, 1));
5292 /* SPE vector modes. */
5293 return SPE_CONST_OFFSET_OK (offset);
5296 if (TARGET_E500_DOUBLE)
5297 return SPE_CONST_OFFSET_OK (offset);
5299 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
5301 if (VECTOR_MEM_VSX_P (DFmode))
5306 /* On e500v2, we may have:
5308 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
5310 Which gets addressed with evldd instructions. */
5311 if (TARGET_E500_DOUBLE)
5312 return SPE_CONST_OFFSET_OK (offset);
5314 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
5316 else if (offset & 3)
5321 if (TARGET_E500_DOUBLE)
5322 return (SPE_CONST_OFFSET_OK (offset)
5323 && SPE_CONST_OFFSET_OK (offset + 8));
5327 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
5329 else if (offset & 3)
5340 return offset < 0x10000 - extra;
5344 legitimate_indexed_address_p (rtx x, int strict)
5348 if (GET_CODE (x) != PLUS)
5354 /* Recognize the rtl generated by reload which we know will later be
5355 replaced with proper base and index regs. */
5357 && reload_in_progress
5358 && (REG_P (op0) || GET_CODE (op0) == PLUS)
5362 return (REG_P (op0) && REG_P (op1)
5363 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
5364 && INT_REG_OK_FOR_INDEX_P (op1, strict))
5365 || (INT_REG_OK_FOR_BASE_P (op1, strict)
5366 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
5370 avoiding_indexed_address_p (enum machine_mode mode)
5372 /* Avoid indexed addressing for modes that have non-indexed
5373 load/store instruction forms. */
5374 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
5378 legitimate_indirect_address_p (rtx x, int strict)
5380 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
5384 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
5386 if (!TARGET_MACHO || !flag_pic
5387 || mode != SImode || GET_CODE (x) != MEM)
5391 if (GET_CODE (x) != LO_SUM)
5393 if (GET_CODE (XEXP (x, 0)) != REG)
5395 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
5399 return CONSTANT_P (x);
5403 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
5405 if (GET_CODE (x) != LO_SUM)
5407 if (GET_CODE (XEXP (x, 0)) != REG)
5409 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5411 /* Restrict addressing for DI because of our SUBREG hackery. */
5412 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5413 || mode == DDmode || mode == TDmode
5418 if (TARGET_ELF || TARGET_MACHO)
5420 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
5424 if (GET_MODE_NUNITS (mode) != 1)
5426 if (GET_MODE_BITSIZE (mode) > 64
5427 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
5428 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5429 && (mode == DFmode || mode == DDmode))))
5432 return CONSTANT_P (x);
5439 /* Try machine-dependent ways of modifying an illegitimate address
5440 to be legitimate. If we find one, return the new, valid address.
5441 This is used from only one place: `memory_address' in explow.c.
5443 OLDX is the address as it was before break_out_memory_refs was
5444 called. In some cases it is useful to look at this to decide what
5447 It is always safe for this function to do nothing. It exists to
5448 recognize opportunities to optimize the output.
5450 On RS/6000, first check for the sum of a register with a constant
5451 integer that is out of range. If so, generate code to add the
5452 constant with the low-order 16 bits masked to the register and force
5453 this result into another register (this can be done with `cau').
5454 Then generate an address of REG+(CONST&0xffff), allowing for the
5455 possibility of bit 16 being a one.
5457 Then check for the sum of a register and something not constant, try to
5458 load the other things into a register and return the sum. */
5461 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
5462 enum machine_mode mode)
5464 unsigned int extra = 0;
5466 if (!reg_offset_addressing_ok_p (mode))
5468 if (virtual_stack_registers_memory_p (x))
5471 /* In theory we should not be seeing addresses of the form reg+0,
5472 but just in case it is generated, optimize it away. */
5473 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
5474 return force_reg (Pmode, XEXP (x, 0));
5476 /* Make sure both operands are registers. */
5477 else if (GET_CODE (x) == PLUS)
5478 return gen_rtx_PLUS (Pmode,
5479 force_reg (Pmode, XEXP (x, 0)),
5480 force_reg (Pmode, XEXP (x, 1)));
5482 return force_reg (Pmode, x);
5484 if (GET_CODE (x) == SYMBOL_REF)
5486 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
5488 return rs6000_legitimize_tls_address (x, model);
5498 if (!TARGET_POWERPC64)
5506 extra = TARGET_POWERPC64 ? 8 : 12;
5512 if (GET_CODE (x) == PLUS
5513 && GET_CODE (XEXP (x, 0)) == REG
5514 && GET_CODE (XEXP (x, 1)) == CONST_INT
5515 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
5517 && !((TARGET_POWERPC64
5518 && (mode == DImode || mode == TImode)
5519 && (INTVAL (XEXP (x, 1)) & 3) != 0)
5520 || SPE_VECTOR_MODE (mode)
5521 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5522 || mode == DImode || mode == DDmode
5523 || mode == TDmode))))
5525 HOST_WIDE_INT high_int, low_int;
5527 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
5528 if (low_int >= 0x8000 - extra)
5530 high_int = INTVAL (XEXP (x, 1)) - low_int;
5531 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
5532 GEN_INT (high_int)), 0);
5533 return plus_constant (sum, low_int);
5535 else if (GET_CODE (x) == PLUS
5536 && GET_CODE (XEXP (x, 0)) == REG
5537 && GET_CODE (XEXP (x, 1)) != CONST_INT
5538 && GET_MODE_NUNITS (mode) == 1
5539 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5541 || ((mode != DImode && mode != DFmode && mode != DDmode)
5542 || (TARGET_E500_DOUBLE && mode != DDmode)))
5543 && (TARGET_POWERPC64 || mode != DImode)
5544 && !avoiding_indexed_address_p (mode)
5549 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
5550 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
5552 else if (SPE_VECTOR_MODE (mode)
5553 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5554 || mode == DDmode || mode == TDmode
5555 || mode == DImode)))
5559 /* We accept [reg + reg] and [reg + OFFSET]. */
5561 if (GET_CODE (x) == PLUS)
5563 rtx op1 = XEXP (x, 0);
5564 rtx op2 = XEXP (x, 1);
5567 op1 = force_reg (Pmode, op1);
5569 if (GET_CODE (op2) != REG
5570 && (GET_CODE (op2) != CONST_INT
5571 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
5572 || (GET_MODE_SIZE (mode) > 8
5573 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
5574 op2 = force_reg (Pmode, op2);
5576 /* We can't always do [reg + reg] for these, because [reg +
5577 reg + offset] is not a legitimate addressing mode. */
5578 y = gen_rtx_PLUS (Pmode, op1, op2);
5580 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
5581 return force_reg (Pmode, y);
5586 return force_reg (Pmode, x);
5592 && GET_CODE (x) != CONST_INT
5593 && GET_CODE (x) != CONST_DOUBLE
5595 && GET_MODE_NUNITS (mode) == 1
5596 && (GET_MODE_BITSIZE (mode) <= 32
5597 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5598 && (mode == DFmode || mode == DDmode))))
5600 rtx reg = gen_reg_rtx (Pmode);
5601 emit_insn (gen_elf_high (reg, x));
5602 return gen_rtx_LO_SUM (Pmode, reg, x);
5604 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
5607 && ! MACHO_DYNAMIC_NO_PIC_P
5609 && GET_CODE (x) != CONST_INT
5610 && GET_CODE (x) != CONST_DOUBLE
5612 && GET_MODE_NUNITS (mode) == 1
5613 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5614 || (mode != DFmode && mode != DDmode))
5618 rtx reg = gen_reg_rtx (Pmode);
5619 emit_insn (gen_macho_high (reg, x));
5620 return gen_rtx_LO_SUM (Pmode, reg, x);
5623 && GET_CODE (x) == SYMBOL_REF
5624 && constant_pool_expr_p (x)
5625 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
5627 rtx reg = TARGET_CMODEL != CMODEL_SMALL ? gen_reg_rtx (Pmode) : NULL_RTX;
5628 return create_TOC_reference (x, reg);
5634 /* Debug version of rs6000_legitimize_address. */
5636 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
5642 ret = rs6000_legitimize_address (x, oldx, mode);
5643 insns = get_insns ();
5649 "\nrs6000_legitimize_address: mode %s, old code %s, "
5650 "new code %s, modified\n",
5651 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
5652 GET_RTX_NAME (GET_CODE (ret)));
5654 fprintf (stderr, "Original address:\n");
5657 fprintf (stderr, "oldx:\n");
5660 fprintf (stderr, "New address:\n");
5665 fprintf (stderr, "Insns added:\n");
5666 debug_rtx_list (insns, 20);
5672 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
5673 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
5684 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
5685 We need to emit DTP-relative relocations. */
5688 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
5693 fputs ("\t.long\t", file);
5696 fputs (DOUBLE_INT_ASM_OP, file);
5701 output_addr_const (file, x);
5702 fputs ("@dtprel+0x8000", file);
5705 /* In the name of slightly smaller debug output, and to cater to
5706 general assembler lossage, recognize various UNSPEC sequences
5707 and turn them back into a direct symbol reference. */
5710 rs6000_delegitimize_address (rtx orig_x)
5714 orig_x = delegitimize_mem_from_attrs (orig_x);
5719 if (GET_CODE (x) == (TARGET_CMODEL != CMODEL_SMALL ? LO_SUM : PLUS)
5720 && GET_CODE (XEXP (x, 1)) == CONST)
5722 rtx offset = NULL_RTX;
5724 y = XEXP (XEXP (x, 1), 0);
5725 if (GET_CODE (y) == PLUS
5726 && GET_MODE (y) == Pmode
5727 && CONST_INT_P (XEXP (y, 1)))
5729 offset = XEXP (y, 1);
5732 if (GET_CODE (y) == UNSPEC
5733 && XINT (y, 1) == UNSPEC_TOCREL
5734 && ((GET_CODE (XEXP (x, 0)) == REG
5735 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5736 || TARGET_MINIMAL_TOC
5737 || TARGET_CMODEL != CMODEL_SMALL))
5738 || (TARGET_CMODEL != CMODEL_SMALL
5739 && GET_CODE (XEXP (x, 0)) == CONST
5740 && GET_CODE (XEXP (XEXP (x, 0), 0)) == PLUS
5741 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == REG
5742 && REGNO (XEXP (XEXP (XEXP (x, 0), 0), 0)) == TOC_REGISTER
5743 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == HIGH
5744 && rtx_equal_p (XEXP (x, 1),
5745 XEXP (XEXP (XEXP (XEXP (x, 0), 0), 1), 0)))))
5747 y = XVECEXP (y, 0, 0);
5748 if (offset != NULL_RTX)
5749 y = gen_rtx_PLUS (Pmode, y, offset);
5750 if (!MEM_P (orig_x))
5753 return replace_equiv_address_nv (orig_x, y);
5758 && GET_CODE (orig_x) == LO_SUM
5759 && GET_CODE (XEXP (orig_x, 1)) == CONST)
5761 y = XEXP (XEXP (orig_x, 1), 0);
5762 if (GET_CODE (y) == UNSPEC
5763 && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET)
5764 return XVECEXP (y, 0, 0);
5770 /* Construct the SYMBOL_REF for the tls_get_addr function. */
5772 static GTY(()) rtx rs6000_tls_symbol;
5774 rs6000_tls_get_addr (void)
5776 if (!rs6000_tls_symbol)
5777 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
5779 return rs6000_tls_symbol;
5782 /* Construct the SYMBOL_REF for TLS GOT references. */
5784 static GTY(()) rtx rs6000_got_symbol;
5786 rs6000_got_sym (void)
5788 if (!rs6000_got_symbol)
5790 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
5791 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
5792 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
5795 return rs6000_got_symbol;
5798 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
5799 this (thread-local) address. */
5802 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
5806 dest = gen_reg_rtx (Pmode);
5807 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
5813 tlsreg = gen_rtx_REG (Pmode, 13);
5814 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
5818 tlsreg = gen_rtx_REG (Pmode, 2);
5819 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
5823 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
5827 tmp = gen_reg_rtx (Pmode);
5830 tlsreg = gen_rtx_REG (Pmode, 13);
5831 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
5835 tlsreg = gen_rtx_REG (Pmode, 2);
5836 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
5840 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
5842 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
5847 rtx r3, got, tga, tmp1, tmp2, call_insn;
5849 /* We currently use relocations like @got@tlsgd for tls, which
5850 means the linker will handle allocation of tls entries, placing
5851 them in the .got section. So use a pointer to the .got section,
5852 not one to secondary TOC sections used by 64-bit -mminimal-toc,
5853 or to secondary GOT sections used by 32-bit -fPIC. */
5855 got = gen_rtx_REG (Pmode, 2);
5859 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
5862 rtx gsym = rs6000_got_sym ();
5863 got = gen_reg_rtx (Pmode);
5865 rs6000_emit_move (got, gsym, Pmode);
5870 tmp1 = gen_reg_rtx (Pmode);
5871 tmp2 = gen_reg_rtx (Pmode);
5872 mem = gen_const_mem (Pmode, tmp1);
5873 lab = gen_label_rtx ();
5874 emit_insn (gen_load_toc_v4_PIC_1b (gsym, lab));
5875 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
5876 if (TARGET_LINK_STACK)
5877 emit_insn (gen_addsi3 (tmp1, tmp1, GEN_INT (4)));
5878 emit_move_insn (tmp2, mem);
5879 last = emit_insn (gen_addsi3 (got, tmp1, tmp2));
5880 set_unique_reg_note (last, REG_EQUAL, gsym);
5885 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
5887 tga = rs6000_tls_get_addr ();
5888 emit_library_call_value (tga, dest, LCT_CONST, Pmode,
5889 1, const0_rtx, Pmode);
5891 r3 = gen_rtx_REG (Pmode, 3);
5892 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5893 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
5894 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5895 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
5896 else if (DEFAULT_ABI == ABI_V4)
5897 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
5900 call_insn = last_call_insn ();
5901 PATTERN (call_insn) = insn;
5902 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5903 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
5904 pic_offset_table_rtx);
5906 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
5908 tga = rs6000_tls_get_addr ();
5909 tmp1 = gen_reg_rtx (Pmode);
5910 emit_library_call_value (tga, tmp1, LCT_CONST, Pmode,
5911 1, const0_rtx, Pmode);
5913 r3 = gen_rtx_REG (Pmode, 3);
5914 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5915 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
5916 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5917 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
5918 else if (DEFAULT_ABI == ABI_V4)
5919 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
5922 call_insn = last_call_insn ();
5923 PATTERN (call_insn) = insn;
5924 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5925 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
5926 pic_offset_table_rtx);
5928 if (rs6000_tls_size == 16)
5931 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
5933 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
5935 else if (rs6000_tls_size == 32)
5937 tmp2 = gen_reg_rtx (Pmode);
5939 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
5941 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
5944 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
5946 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
5950 tmp2 = gen_reg_rtx (Pmode);
5952 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
5954 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
5956 insn = gen_rtx_SET (Pmode, dest,
5957 gen_rtx_PLUS (Pmode, tmp2, tmp1));
5963 /* IE, or 64-bit offset LE. */
5964 tmp2 = gen_reg_rtx (Pmode);
5966 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
5968 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
5971 insn = gen_tls_tls_64 (dest, tmp2, addr);
5973 insn = gen_tls_tls_32 (dest, tmp2, addr);
5981 /* Return 1 if X contains a thread-local symbol. */
5984 rs6000_tls_referenced_p (rtx x)
5986 if (! TARGET_HAVE_TLS)
5989 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
5992 /* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
5995 rs6000_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
5997 if (GET_CODE (x) == CONST
5998 && GET_CODE (XEXP (x, 0)) == PLUS
5999 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH)
6002 return rs6000_tls_referenced_p (x);
6005 /* Return 1 if *X is a thread-local symbol. This is the same as
6006 rs6000_tls_symbol_ref except for the type of the unused argument. */
6009 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
6011 return RS6000_SYMBOL_REF_TLS_P (*x);
6014 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
6015 replace the input X, or the original X if no replacement is called for.
6016 The output parameter *WIN is 1 if the calling macro should goto WIN,
6019 For RS/6000, we wish to handle large displacements off a base
6020 register by splitting the addend across an addiu/addis and the mem insn.
6021 This cuts number of extra insns needed from 3 to 1.
6023 On Darwin, we use this to generate code for floating point constants.
6024 A movsf_low is generated so we wind up with 2 instructions rather than 3.
6025 The Darwin code is inside #if TARGET_MACHO because only then are the
6026 machopic_* functions defined. */
6028 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
6029 int opnum, int type,
6030 int ind_levels ATTRIBUTE_UNUSED, int *win)
6032 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6034 /* Nasty hack for vsx_splat_V2DF/V2DI load from mem, which takes a
6035 DFmode/DImode MEM. */
6038 && ((mode == DFmode && recog_data.operand_mode[0] == V2DFmode)
6039 || (mode == DImode && recog_data.operand_mode[0] == V2DImode)))
6040 reg_offset_p = false;
6042 /* We must recognize output that we have already generated ourselves. */
6043 if (GET_CODE (x) == PLUS
6044 && GET_CODE (XEXP (x, 0)) == PLUS
6045 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6046 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6047 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6049 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6050 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6051 opnum, (enum reload_type)type);
6056 /* Likewise for (lo_sum (high ...) ...) output we have generated. */
6057 if (GET_CODE (x) == LO_SUM
6058 && GET_CODE (XEXP (x, 0)) == HIGH)
6060 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6061 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6062 opnum, (enum reload_type)type);
6068 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
6069 && GET_CODE (x) == LO_SUM
6070 && GET_CODE (XEXP (x, 0)) == PLUS
6071 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
6072 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6073 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
6074 && machopic_operand_p (XEXP (x, 1)))
6076 /* Result of previous invocation of this function on Darwin
6077 floating point constant. */
6078 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6079 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6080 opnum, (enum reload_type)type);
6086 if (TARGET_CMODEL != CMODEL_SMALL
6087 && GET_CODE (x) == LO_SUM
6088 && GET_CODE (XEXP (x, 0)) == PLUS
6089 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6090 && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER
6091 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST
6092 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 0)) == HIGH
6093 && GET_CODE (XEXP (x, 1)) == CONST
6094 && GET_CODE (XEXP (XEXP (x, 1), 0)) == UNSPEC
6095 && XINT (XEXP (XEXP (x, 1), 0), 1) == UNSPEC_TOCREL
6096 && rtx_equal_p (XEXP (XEXP (XEXP (XEXP (x, 0), 1), 0), 0), XEXP (x, 1)))
6098 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6099 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6100 opnum, (enum reload_type) type);
6105 /* Force ld/std non-word aligned offset into base register by wrapping
6107 if (GET_CODE (x) == PLUS
6108 && GET_CODE (XEXP (x, 0)) == REG
6109 && REGNO (XEXP (x, 0)) < 32
6110 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6111 && GET_CODE (XEXP (x, 1)) == CONST_INT
6113 && (INTVAL (XEXP (x, 1)) & 3) != 0
6114 && VECTOR_MEM_NONE_P (mode)
6115 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
6116 && TARGET_POWERPC64)
6118 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
6119 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6120 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6121 opnum, (enum reload_type) type);
6126 if (GET_CODE (x) == PLUS
6127 && GET_CODE (XEXP (x, 0)) == REG
6128 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
6129 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6130 && GET_CODE (XEXP (x, 1)) == CONST_INT
6132 && !SPE_VECTOR_MODE (mode)
6133 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6134 || mode == DDmode || mode == TDmode
6136 && VECTOR_MEM_NONE_P (mode))
6138 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
6139 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
6141 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
6143 /* Check for 32-bit overflow. */
6144 if (high + low != val)
6150 /* Reload the high part into a base reg; leave the low part
6151 in the mem directly. */
6153 x = gen_rtx_PLUS (GET_MODE (x),
6154 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
6158 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6159 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6160 opnum, (enum reload_type)type);
6165 if (GET_CODE (x) == SYMBOL_REF
6167 && VECTOR_MEM_NONE_P (mode)
6168 && !SPE_VECTOR_MODE (mode)
6170 && DEFAULT_ABI == ABI_DARWIN
6171 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
6173 && DEFAULT_ABI == ABI_V4
6176 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
6177 The same goes for DImode without 64-bit gprs and DFmode and DDmode
6181 && (mode != DImode || TARGET_POWERPC64)
6182 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
6183 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
6188 rtx offset = machopic_gen_offset (x);
6189 x = gen_rtx_LO_SUM (GET_MODE (x),
6190 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
6191 gen_rtx_HIGH (Pmode, offset)), offset);
6195 x = gen_rtx_LO_SUM (GET_MODE (x),
6196 gen_rtx_HIGH (Pmode, x), x);
6198 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6199 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6200 opnum, (enum reload_type)type);
6205 /* Reload an offset address wrapped by an AND that represents the
6206 masking of the lower bits. Strip the outer AND and let reload
6207 convert the offset address into an indirect address. For VSX,
6208 force reload to create the address with an AND in a separate
6209 register, because we can't guarantee an altivec register will
6211 if (VECTOR_MEM_ALTIVEC_P (mode)
6212 && GET_CODE (x) == AND
6213 && GET_CODE (XEXP (x, 0)) == PLUS
6214 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6215 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6216 && GET_CODE (XEXP (x, 1)) == CONST_INT
6217 && INTVAL (XEXP (x, 1)) == -16)
6226 && GET_CODE (x) == SYMBOL_REF
6227 && constant_pool_expr_p (x)
6228 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
6230 x = create_TOC_reference (x, NULL_RTX);
6231 if (TARGET_CMODEL != CMODEL_SMALL)
6232 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6233 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6234 opnum, (enum reload_type) type);
6242 /* Debug version of rs6000_legitimize_reload_address. */
6244 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
6245 int opnum, int type,
6246 int ind_levels, int *win)
6248 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
6251 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
6252 "type = %d, ind_levels = %d, win = %d, original addr:\n",
6253 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
6257 fprintf (stderr, "Same address returned\n");
6259 fprintf (stderr, "NULL returned\n");
6262 fprintf (stderr, "New address:\n");
6269 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
6270 that is a valid memory address for an instruction.
6271 The MODE argument is the machine mode for the MEM expression
6272 that wants to use this address.
6274 On the RS/6000, there are four valid address: a SYMBOL_REF that
6275 refers to a constant pool entry of an address (or the sum of it
6276 plus a constant), a short (16-bit signed) constant plus a register,
6277 the sum of two registers, or a register indirect, possibly with an
6278 auto-increment. For DFmode, DDmode and DImode with a constant plus
6279 register, we must ensure that both words are addressable or PowerPC64
6280 with offset word aligned.
6282 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
6283 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
6284 because adjacent memory cells are accessed by adding word-sized offsets
6285 during assembly output. */
6287 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
6289 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6291 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
6292 if (VECTOR_MEM_ALTIVEC_P (mode)
6293 && GET_CODE (x) == AND
6294 && GET_CODE (XEXP (x, 1)) == CONST_INT
6295 && INTVAL (XEXP (x, 1)) == -16)
6298 if (RS6000_SYMBOL_REF_TLS_P (x))
6300 if (legitimate_indirect_address_p (x, reg_ok_strict))
6302 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
6303 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6304 && !SPE_VECTOR_MODE (mode)
6307 /* Restrict addressing for DI because of our SUBREG hackery. */
6308 && !(TARGET_E500_DOUBLE
6309 && (mode == DFmode || mode == DDmode || mode == DImode))
6311 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
6313 if (virtual_stack_registers_memory_p (x))
6315 if (reg_offset_p && legitimate_small_data_p (mode, x))
6318 && legitimate_constant_pool_address_p (x, mode, reg_ok_strict))
6320 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
6323 && GET_CODE (x) == PLUS
6324 && GET_CODE (XEXP (x, 0)) == REG
6325 && (XEXP (x, 0) == virtual_stack_vars_rtx
6326 || XEXP (x, 0) == arg_pointer_rtx)
6327 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6329 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
6334 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6336 || (mode != DFmode && mode != DDmode)
6337 || (TARGET_E500_DOUBLE && mode != DDmode))
6338 && (TARGET_POWERPC64 || mode != DImode)
6339 && !avoiding_indexed_address_p (mode)
6340 && legitimate_indexed_address_p (x, reg_ok_strict))
6342 if (GET_CODE (x) == PRE_MODIFY
6346 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6348 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
6349 && (TARGET_POWERPC64 || mode != DImode)
6350 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6351 && !SPE_VECTOR_MODE (mode)
6352 /* Restrict addressing for DI because of our SUBREG hackery. */
6353 && !(TARGET_E500_DOUBLE
6354 && (mode == DFmode || mode == DDmode || mode == DImode))
6356 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
6357 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
6358 || (!avoiding_indexed_address_p (mode)
6359 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
6360 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
6362 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
6367 /* Debug version of rs6000_legitimate_address_p. */
6369 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
6372 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
6374 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
6375 "strict = %d, code = %s\n",
6376 ret ? "true" : "false",
6377 GET_MODE_NAME (mode),
6379 GET_RTX_NAME (GET_CODE (x)));
6385 /* Implement TARGET_MODE_DEPENDENT_ADDRESS_P. */
6388 rs6000_mode_dependent_address_p (const_rtx addr)
6390 return rs6000_mode_dependent_address_ptr (addr);
6393 /* Go to LABEL if ADDR (a legitimate address expression)
6394 has an effect that depends on the machine mode it is used for.
6396 On the RS/6000 this is true of all integral offsets (since AltiVec
6397 and VSX modes don't allow them) or is a pre-increment or decrement.
6399 ??? Except that due to conceptual problems in offsettable_address_p
6400 we can't really report the problems of integral offsets. So leave
6401 this assuming that the adjustable offset must be valid for the
6402 sub-words of a TFmode operand, which is what we had before. */
6405 rs6000_mode_dependent_address (const_rtx addr)
6407 switch (GET_CODE (addr))
6410 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
6411 is considered a legitimate address before reload, so there
6412 are no offset restrictions in that case. Note that this
6413 condition is safe in strict mode because any address involving
6414 virtual_stack_vars_rtx or arg_pointer_rtx would already have
6415 been rejected as illegitimate. */
6416 if (XEXP (addr, 0) != virtual_stack_vars_rtx
6417 && XEXP (addr, 0) != arg_pointer_rtx
6418 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
6420 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
6421 return val + 12 + 0x8000 >= 0x10000;
6426 /* Anything in the constant pool is sufficiently aligned that
6427 all bytes have the same high part address. */
6428 return !legitimate_constant_pool_address_p (addr, QImode, false);
6430 /* Auto-increment cases are now treated generically in recog.c. */
6432 return TARGET_UPDATE;
6434 /* AND is only allowed in Altivec loads. */
6445 /* Debug version of rs6000_mode_dependent_address. */
6447 rs6000_debug_mode_dependent_address (const_rtx addr)
6449 bool ret = rs6000_mode_dependent_address (addr);
6451 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
6452 ret ? "true" : "false");
6458 /* Implement FIND_BASE_TERM. */
6461 rs6000_find_base_term (rtx op)
6465 split_const (op, &base, &offset);
6466 if (GET_CODE (base) == UNSPEC)
6467 switch (XINT (base, 1))
6470 case UNSPEC_MACHOPIC_OFFSET:
6471 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
6472 for aliasing purposes. */
6473 return XVECEXP (base, 0, 0);
6479 /* More elaborate version of recog's offsettable_memref_p predicate
6480 that works around the ??? note of rs6000_mode_dependent_address.
6481 In particular it accepts
6483 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
6485 in 32-bit mode, that the recog predicate rejects. */
6488 rs6000_offsettable_memref_p (rtx op)
6493 /* First mimic offsettable_memref_p. */
6494 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
6497 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
6498 the latter predicate knows nothing about the mode of the memory
6499 reference and, therefore, assumes that it is the largest supported
6500 mode (TFmode). As a consequence, legitimate offsettable memory
6501 references are rejected. rs6000_legitimate_offset_address_p contains
6502 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
6503 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
6506 /* Change register usage conditional on target flags. */
6508 rs6000_conditional_register_usage (void)
6512 if (TARGET_DEBUG_TARGET)
6513 fprintf (stderr, "rs6000_conditional_register_usage called\n");
6515 /* Set MQ register fixed (already call_used) if not POWER
6516 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
6521 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
6523 fixed_regs[13] = call_used_regs[13]
6524 = call_really_used_regs[13] = 1;
6526 /* Conditionally disable FPRs. */
6527 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6528 for (i = 32; i < 64; i++)
6529 fixed_regs[i] = call_used_regs[i]
6530 = call_really_used_regs[i] = 1;
6532 /* The TOC register is not killed across calls in a way that is
6533 visible to the compiler. */
6534 if (DEFAULT_ABI == ABI_AIX)
6535 call_really_used_regs[2] = 0;
6537 if (DEFAULT_ABI == ABI_V4
6538 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6540 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6542 if (DEFAULT_ABI == ABI_V4
6543 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6545 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6546 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6547 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6549 if (DEFAULT_ABI == ABI_DARWIN
6550 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
6551 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6552 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6553 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6555 if (TARGET_TOC && TARGET_MINIMAL_TOC)
6556 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6557 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6561 global_regs[SPEFSCR_REGNO] = 1;
6562 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
6563 registers in prologues and epilogues. We no longer use r14
6564 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
6565 pool for link-compatibility with older versions of GCC. Once
6566 "old" code has died out, we can return r14 to the allocation
6569 = call_used_regs[14]
6570 = call_really_used_regs[14] = 1;
6573 if (!TARGET_ALTIVEC && !TARGET_VSX)
6575 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
6576 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6577 call_really_used_regs[VRSAVE_REGNO] = 1;
6580 if (TARGET_ALTIVEC || TARGET_VSX)
6581 global_regs[VSCR_REGNO] = 1;
6583 if (TARGET_ALTIVEC_ABI)
6585 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
6586 call_used_regs[i] = call_really_used_regs[i] = 1;
6588 /* AIX reserves VR20:31 in non-extended ABI mode. */
6590 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
6591 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6595 /* Try to output insns to set TARGET equal to the constant C if it can
6596 be done in less than N insns. Do all computations in MODE.
6597 Returns the place where the output has been placed if it can be
6598 done and the insns have been emitted. If it would take more than N
6599 insns, zero is returned and no insns and emitted. */
6602 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
6603 rtx source, int n ATTRIBUTE_UNUSED)
6605 rtx result, insn, set;
6606 HOST_WIDE_INT c0, c1;
6613 dest = gen_reg_rtx (mode);
6614 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
6618 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
6620 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
6621 GEN_INT (INTVAL (source)
6622 & (~ (HOST_WIDE_INT) 0xffff))));
6623 emit_insn (gen_rtx_SET (VOIDmode, dest,
6624 gen_rtx_IOR (SImode, copy_rtx (result),
6625 GEN_INT (INTVAL (source) & 0xffff))));
6630 switch (GET_CODE (source))
6633 c0 = INTVAL (source);
6638 #if HOST_BITS_PER_WIDE_INT >= 64
6639 c0 = CONST_DOUBLE_LOW (source);
6642 c0 = CONST_DOUBLE_LOW (source);
6643 c1 = CONST_DOUBLE_HIGH (source);
6651 result = rs6000_emit_set_long_const (dest, c0, c1);
6658 insn = get_last_insn ();
6659 set = single_set (insn);
6660 if (! CONSTANT_P (SET_SRC (set)))
6661 set_unique_reg_note (insn, REG_EQUAL, source);
6666 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
6667 fall back to a straight forward decomposition. We do this to avoid
6668 exponential run times encountered when looking for longer sequences
6669 with rs6000_emit_set_const. */
6671 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
6673 if (!TARGET_POWERPC64)
6675 rtx operand1, operand2;
6677 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
6679 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
6681 emit_move_insn (operand1, GEN_INT (c1));
6682 emit_move_insn (operand2, GEN_INT (c2));
6686 HOST_WIDE_INT ud1, ud2, ud3, ud4;
6689 ud2 = (c1 & 0xffff0000) >> 16;
6690 #if HOST_BITS_PER_WIDE_INT >= 64
6694 ud4 = (c2 & 0xffff0000) >> 16;
6696 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
6697 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
6700 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
6702 emit_move_insn (dest, GEN_INT (ud1));
6705 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
6706 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
6709 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6712 emit_move_insn (dest, GEN_INT (ud2 << 16));
6714 emit_move_insn (copy_rtx (dest),
6715 gen_rtx_IOR (DImode, copy_rtx (dest),
6718 else if (ud3 == 0 && ud4 == 0)
6720 gcc_assert (ud2 & 0x8000);
6721 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6724 emit_move_insn (copy_rtx (dest),
6725 gen_rtx_IOR (DImode, copy_rtx (dest),
6727 emit_move_insn (copy_rtx (dest),
6728 gen_rtx_ZERO_EXTEND (DImode,
6729 gen_lowpart (SImode,
6732 else if ((ud4 == 0xffff && (ud3 & 0x8000))
6733 || (ud4 == 0 && ! (ud3 & 0x8000)))
6736 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
6739 emit_move_insn (dest, GEN_INT (ud3 << 16));
6742 emit_move_insn (copy_rtx (dest),
6743 gen_rtx_IOR (DImode, copy_rtx (dest),
6745 emit_move_insn (copy_rtx (dest),
6746 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6749 emit_move_insn (copy_rtx (dest),
6750 gen_rtx_IOR (DImode, copy_rtx (dest),
6756 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
6759 emit_move_insn (dest, GEN_INT (ud4 << 16));
6762 emit_move_insn (copy_rtx (dest),
6763 gen_rtx_IOR (DImode, copy_rtx (dest),
6766 emit_move_insn (copy_rtx (dest),
6767 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6770 emit_move_insn (copy_rtx (dest),
6771 gen_rtx_IOR (DImode, copy_rtx (dest),
6772 GEN_INT (ud2 << 16)));
6774 emit_move_insn (copy_rtx (dest),
6775 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
6781 /* Helper for the following. Get rid of [r+r] memory refs
6782 in cases where it won't work (TImode, TFmode, TDmode). */
6785 rs6000_eliminate_indexed_memrefs (rtx operands[2])
6787 if (reload_in_progress)
6790 if (GET_CODE (operands[0]) == MEM
6791 && GET_CODE (XEXP (operands[0], 0)) != REG
6792 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0),
6793 GET_MODE (operands[0]), false))
6795 = replace_equiv_address (operands[0],
6796 copy_addr_to_reg (XEXP (operands[0], 0)));
6798 if (GET_CODE (operands[1]) == MEM
6799 && GET_CODE (XEXP (operands[1], 0)) != REG
6800 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0),
6801 GET_MODE (operands[1]), false))
6803 = replace_equiv_address (operands[1],
6804 copy_addr_to_reg (XEXP (operands[1], 0)));
6807 /* Emit a move from SOURCE to DEST in mode MODE. */
6809 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
6813 operands[1] = source;
6815 if (TARGET_DEBUG_ADDR)
6818 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
6819 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
6820 GET_MODE_NAME (mode),
6823 can_create_pseudo_p ());
6825 fprintf (stderr, "source:\n");
6829 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
6830 if (GET_CODE (operands[1]) == CONST_DOUBLE
6831 && ! FLOAT_MODE_P (mode)
6832 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
6834 /* FIXME. This should never happen. */
6835 /* Since it seems that it does, do the safe thing and convert
6837 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
6839 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
6840 || FLOAT_MODE_P (mode)
6841 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
6842 || CONST_DOUBLE_LOW (operands[1]) < 0)
6843 && (CONST_DOUBLE_HIGH (operands[1]) != -1
6844 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
6846 /* Check if GCC is setting up a block move that will end up using FP
6847 registers as temporaries. We must make sure this is acceptable. */
6848 if (GET_CODE (operands[0]) == MEM
6849 && GET_CODE (operands[1]) == MEM
6851 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
6852 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
6853 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
6854 ? 32 : MEM_ALIGN (operands[0])))
6855 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
6857 : MEM_ALIGN (operands[1]))))
6858 && ! MEM_VOLATILE_P (operands [0])
6859 && ! MEM_VOLATILE_P (operands [1]))
6861 emit_move_insn (adjust_address (operands[0], SImode, 0),
6862 adjust_address (operands[1], SImode, 0));
6863 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
6864 adjust_address (copy_rtx (operands[1]), SImode, 4));
6868 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
6869 && !gpc_reg_operand (operands[1], mode))
6870 operands[1] = force_reg (mode, operands[1]);
6872 if (mode == SFmode && ! TARGET_POWERPC
6873 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6874 && GET_CODE (operands[0]) == MEM)
6878 if (reload_in_progress || reload_completed)
6879 regnum = true_regnum (operands[1]);
6880 else if (GET_CODE (operands[1]) == REG)
6881 regnum = REGNO (operands[1]);
6885 /* If operands[1] is a register, on POWER it may have
6886 double-precision data in it, so truncate it to single
6888 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
6891 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
6892 : gen_reg_rtx (mode));
6893 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
6894 operands[1] = newreg;
6898 /* Recognize the case where operand[1] is a reference to thread-local
6899 data and load its address to a register. */
6900 if (rs6000_tls_referenced_p (operands[1]))
6902 enum tls_model model;
6903 rtx tmp = operands[1];
6906 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6908 addend = XEXP (XEXP (tmp, 0), 1);
6909 tmp = XEXP (XEXP (tmp, 0), 0);
6912 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6913 model = SYMBOL_REF_TLS_MODEL (tmp);
6914 gcc_assert (model != 0);
6916 tmp = rs6000_legitimize_tls_address (tmp, model);
6919 tmp = gen_rtx_PLUS (mode, tmp, addend);
6920 tmp = force_operand (tmp, operands[0]);
6925 /* Handle the case where reload calls us with an invalid address. */
6926 if (reload_in_progress && mode == Pmode
6927 && (! general_operand (operands[1], mode)
6928 || ! nonimmediate_operand (operands[0], mode)))
6931 /* 128-bit constant floating-point values on Darwin should really be
6932 loaded as two parts. */
6933 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
6934 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
6936 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
6937 know how to get a DFmode SUBREG of a TFmode. */
6938 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
6939 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
6940 simplify_gen_subreg (imode, operands[1], mode, 0),
6942 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
6943 GET_MODE_SIZE (imode)),
6944 simplify_gen_subreg (imode, operands[1], mode,
6945 GET_MODE_SIZE (imode)),
6950 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
6951 cfun->machine->sdmode_stack_slot =
6952 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
6954 if (reload_in_progress
6956 && MEM_P (operands[0])
6957 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
6958 && REG_P (operands[1]))
6960 if (FP_REGNO_P (REGNO (operands[1])))
6962 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
6963 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6964 emit_insn (gen_movsd_store (mem, operands[1]));
6966 else if (INT_REGNO_P (REGNO (operands[1])))
6968 rtx mem = adjust_address_nv (operands[0], mode, 4);
6969 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6970 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
6976 if (reload_in_progress
6978 && REG_P (operands[0])
6979 && MEM_P (operands[1])
6980 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
6982 if (FP_REGNO_P (REGNO (operands[0])))
6984 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
6985 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6986 emit_insn (gen_movsd_load (operands[0], mem));
6988 else if (INT_REGNO_P (REGNO (operands[0])))
6990 rtx mem = adjust_address_nv (operands[1], mode, 4);
6991 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6992 emit_insn (gen_movsd_hardfloat (operands[0], mem));
6999 /* FIXME: In the long term, this switch statement should go away
7000 and be replaced by a sequence of tests based on things like
7006 if (CONSTANT_P (operands[1])
7007 && GET_CODE (operands[1]) != CONST_INT)
7008 operands[1] = force_const_mem (mode, operands[1]);
7013 rs6000_eliminate_indexed_memrefs (operands);
7020 if (CONSTANT_P (operands[1])
7021 && ! easy_fp_constant (operands[1], mode))
7022 operands[1] = force_const_mem (mode, operands[1]);
7035 if (CONSTANT_P (operands[1])
7036 && !easy_vector_constant (operands[1], mode))
7037 operands[1] = force_const_mem (mode, operands[1]);
7042 /* Use default pattern for address of ELF small data */
7045 && DEFAULT_ABI == ABI_V4
7046 && (GET_CODE (operands[1]) == SYMBOL_REF
7047 || GET_CODE (operands[1]) == CONST)
7048 && small_data_operand (operands[1], mode))
7050 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7054 if (DEFAULT_ABI == ABI_V4
7055 && mode == Pmode && mode == SImode
7056 && flag_pic == 1 && got_operand (operands[1], mode))
7058 emit_insn (gen_movsi_got (operands[0], operands[1]));
7062 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
7066 && CONSTANT_P (operands[1])
7067 && GET_CODE (operands[1]) != HIGH
7068 && GET_CODE (operands[1]) != CONST_INT)
7070 rtx target = (!can_create_pseudo_p ()
7072 : gen_reg_rtx (mode));
7074 /* If this is a function address on -mcall-aixdesc,
7075 convert it to the address of the descriptor. */
7076 if (DEFAULT_ABI == ABI_AIX
7077 && GET_CODE (operands[1]) == SYMBOL_REF
7078 && XSTR (operands[1], 0)[0] == '.')
7080 const char *name = XSTR (operands[1], 0);
7082 while (*name == '.')
7084 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
7085 CONSTANT_POOL_ADDRESS_P (new_ref)
7086 = CONSTANT_POOL_ADDRESS_P (operands[1]);
7087 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
7088 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
7089 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
7090 operands[1] = new_ref;
7093 if (DEFAULT_ABI == ABI_DARWIN)
7096 if (MACHO_DYNAMIC_NO_PIC_P)
7098 /* Take care of any required data indirection. */
7099 operands[1] = rs6000_machopic_legitimize_pic_address (
7100 operands[1], mode, operands[0]);
7101 if (operands[0] != operands[1])
7102 emit_insn (gen_rtx_SET (VOIDmode,
7103 operands[0], operands[1]));
7107 emit_insn (gen_macho_high (target, operands[1]));
7108 emit_insn (gen_macho_low (operands[0], target, operands[1]));
7112 emit_insn (gen_elf_high (target, operands[1]));
7113 emit_insn (gen_elf_low (operands[0], target, operands[1]));
7117 /* If this is a SYMBOL_REF that refers to a constant pool entry,
7118 and we have put it in the TOC, we just need to make a TOC-relative
7121 && GET_CODE (operands[1]) == SYMBOL_REF
7122 && constant_pool_expr_p (operands[1])
7123 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
7124 get_pool_mode (operands[1])))
7125 || (TARGET_CMODEL == CMODEL_MEDIUM
7126 && GET_CODE (operands[1]) == SYMBOL_REF
7127 && !CONSTANT_POOL_ADDRESS_P (operands[1])
7128 && SYMBOL_REF_LOCAL_P (operands[1])))
7131 if (TARGET_CMODEL != CMODEL_SMALL)
7133 if (can_create_pseudo_p ())
7134 reg = gen_reg_rtx (Pmode);
7138 operands[1] = create_TOC_reference (operands[1], reg);
7140 else if (mode == Pmode
7141 && CONSTANT_P (operands[1])
7142 && GET_CODE (operands[1]) != HIGH
7143 && !(TARGET_CMODEL != CMODEL_SMALL
7144 && GET_CODE (operands[1]) == CONST
7145 && GET_CODE (XEXP (operands[1], 0)) == PLUS
7146 && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == HIGH)
7147 && ((GET_CODE (operands[1]) != CONST_INT
7148 && ! easy_fp_constant (operands[1], mode))
7149 || (GET_CODE (operands[1]) == CONST_INT
7150 && (num_insns_constant (operands[1], mode)
7151 > (TARGET_CMODEL != CMODEL_SMALL ? 3 : 2)))
7152 || (GET_CODE (operands[0]) == REG
7153 && FP_REGNO_P (REGNO (operands[0]))))
7154 && ! legitimate_constant_pool_address_p (operands[1], mode,
7156 && ! toc_relative_expr_p (operands[1])
7157 && (TARGET_CMODEL == CMODEL_SMALL
7158 || can_create_pseudo_p ()
7159 || (REG_P (operands[0])
7160 && INT_REG_OK_FOR_BASE_P (operands[0], true))))
7164 /* Darwin uses a special PIC legitimizer. */
7165 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
7168 rs6000_machopic_legitimize_pic_address (operands[1], mode,
7170 if (operands[0] != operands[1])
7171 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7176 /* If we are to limit the number of things we put in the TOC and
7177 this is a symbol plus a constant we can add in one insn,
7178 just put the symbol in the TOC and add the constant. Don't do
7179 this if reload is in progress. */
7180 if (GET_CODE (operands[1]) == CONST
7181 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
7182 && GET_CODE (XEXP (operands[1], 0)) == PLUS
7183 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
7184 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
7185 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
7186 && ! side_effects_p (operands[0]))
7189 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
7190 rtx other = XEXP (XEXP (operands[1], 0), 1);
7192 sym = force_reg (mode, sym);
7193 emit_insn (gen_add3_insn (operands[0], sym, other));
7197 operands[1] = force_const_mem (mode, operands[1]);
7200 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7201 && constant_pool_expr_p (XEXP (operands[1], 0))
7202 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
7203 get_pool_constant (XEXP (operands[1], 0)),
7204 get_pool_mode (XEXP (operands[1], 0))))
7208 if (TARGET_CMODEL != CMODEL_SMALL)
7210 if (can_create_pseudo_p ())
7211 reg = gen_reg_rtx (Pmode);
7215 tocref = create_TOC_reference (XEXP (operands[1], 0), reg);
7216 operands[1] = gen_const_mem (mode, tocref);
7217 set_mem_alias_set (operands[1], get_TOC_alias_set ());
7223 rs6000_eliminate_indexed_memrefs (operands);
7227 emit_insn (gen_rtx_PARALLEL (VOIDmode,
7229 gen_rtx_SET (VOIDmode,
7230 operands[0], operands[1]),
7231 gen_rtx_CLOBBER (VOIDmode,
7232 gen_rtx_SCRATCH (SImode)))));
7238 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
7241 /* Above, we may have called force_const_mem which may have returned
7242 an invalid address. If we can, fix this up; otherwise, reload will
7243 have to deal with it. */
7244 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
7245 operands[1] = validize_mem (operands[1]);
7248 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7251 /* Nonzero if we can use a floating-point register to pass this arg. */
7252 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
7253 (SCALAR_FLOAT_MODE_P (MODE) \
7254 && (CUM)->fregno <= FP_ARG_MAX_REG \
7255 && TARGET_HARD_FLOAT && TARGET_FPRS)
7257 /* Nonzero if we can use an AltiVec register to pass this arg. */
7258 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
7259 (ALTIVEC_OR_VSX_VECTOR_MODE (MODE) \
7260 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
7261 && TARGET_ALTIVEC_ABI \
7264 /* Return a nonzero value to say to return the function value in
7265 memory, just as large structures are always returned. TYPE will be
7266 the data type of the value, and FNTYPE will be the type of the
7267 function doing the returning, or @code{NULL} for libcalls.
7269 The AIX ABI for the RS/6000 specifies that all structures are
7270 returned in memory. The Darwin ABI does the same.
7272 For the Darwin 64 Bit ABI, a function result can be returned in
7273 registers or in memory, depending on the size of the return data
7274 type. If it is returned in registers, the value occupies the same
7275 registers as it would if it were the first and only function
7276 argument. Otherwise, the function places its result in memory at
7277 the location pointed to by GPR3.
7279 The SVR4 ABI specifies that structures <= 8 bytes are returned in r3/r4,
7280 but a draft put them in memory, and GCC used to implement the draft
7281 instead of the final standard. Therefore, aix_struct_return
7282 controls this instead of DEFAULT_ABI; V.4 targets needing backward
7283 compatibility can change DRAFT_V4_STRUCT_RET to override the
7284 default, and -m switches get the final word. See
7285 rs6000_option_override_internal for more details.
7287 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
7288 long double support is enabled. These values are returned in memory.
7290 int_size_in_bytes returns -1 for variable size objects, which go in
7291 memory always. The cast to unsigned makes -1 > 8. */
7294 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
7296 /* For the Darwin64 ABI, test if we can fit the return value in regs. */
7298 && rs6000_darwin64_abi
7299 && TREE_CODE (type) == RECORD_TYPE
7300 && int_size_in_bytes (type) > 0)
7302 CUMULATIVE_ARGS valcum;
7306 valcum.fregno = FP_ARG_MIN_REG;
7307 valcum.vregno = ALTIVEC_ARG_MIN_REG;
7308 /* Do a trial code generation as if this were going to be passed
7309 as an argument; if any part goes in memory, we return NULL. */
7310 valret = rs6000_darwin64_record_arg (&valcum, type, true, true);
7313 /* Otherwise fall through to more conventional ABI rules. */
7316 if (AGGREGATE_TYPE_P (type)
7317 && (aix_struct_return
7318 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
7321 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7322 modes only exist for GCC vector types if -maltivec. */
7323 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
7324 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
7327 /* Return synthetic vectors in memory. */
7328 if (TREE_CODE (type) == VECTOR_TYPE
7329 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
7331 static bool warned_for_return_big_vectors = false;
7332 if (!warned_for_return_big_vectors)
7334 warning (0, "GCC vector returned by reference: "
7335 "non-standard ABI extension with no compatibility guarantee");
7336 warned_for_return_big_vectors = true;
7341 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
7347 #ifdef HAVE_AS_GNU_ATTRIBUTE
7348 /* Return TRUE if a call to function FNDECL may be one that
7349 potentially affects the function calling ABI of the object file. */
7352 call_ABI_of_interest (tree fndecl)
7354 if (cgraph_state == CGRAPH_STATE_EXPANSION)
7356 struct cgraph_node *c_node;
7358 /* Libcalls are always interesting. */
7359 if (fndecl == NULL_TREE)
7362 /* Any call to an external function is interesting. */
7363 if (DECL_EXTERNAL (fndecl))
7366 /* Interesting functions that we are emitting in this object file. */
7367 c_node = cgraph_get_node (fndecl);
7368 c_node = cgraph_function_or_thunk_node (c_node, NULL);
7369 return !cgraph_only_called_directly_p (c_node);
7375 /* Initialize a variable CUM of type CUMULATIVE_ARGS
7376 for a call to a function whose data type is FNTYPE.
7377 For a library call, FNTYPE is 0 and RETURN_MODE the return value mode.
7379 For incoming args we set the number of arguments in the prototype large
7380 so we never return a PARALLEL. */
7383 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
7384 rtx libname ATTRIBUTE_UNUSED, int incoming,
7385 int libcall, int n_named_args,
7386 tree fndecl ATTRIBUTE_UNUSED,
7387 enum machine_mode return_mode ATTRIBUTE_UNUSED)
7389 static CUMULATIVE_ARGS zero_cumulative;
7391 *cum = zero_cumulative;
7393 cum->fregno = FP_ARG_MIN_REG;
7394 cum->vregno = ALTIVEC_ARG_MIN_REG;
7395 cum->prototype = (fntype && prototype_p (fntype));
7396 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
7397 ? CALL_LIBCALL : CALL_NORMAL);
7398 cum->sysv_gregno = GP_ARG_MIN_REG;
7399 cum->stdarg = stdarg_p (fntype);
7401 cum->nargs_prototype = 0;
7402 if (incoming || cum->prototype)
7403 cum->nargs_prototype = n_named_args;
7405 /* Check for a longcall attribute. */
7406 if ((!fntype && rs6000_default_long_calls)
7408 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
7409 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
7410 cum->call_cookie |= CALL_LONG;
7412 if (TARGET_DEBUG_ARG)
7414 fprintf (stderr, "\ninit_cumulative_args:");
7417 tree ret_type = TREE_TYPE (fntype);
7418 fprintf (stderr, " ret code = %s,",
7419 tree_code_name[ (int)TREE_CODE (ret_type) ]);
7422 if (cum->call_cookie & CALL_LONG)
7423 fprintf (stderr, " longcall,");
7425 fprintf (stderr, " proto = %d, nargs = %d\n",
7426 cum->prototype, cum->nargs_prototype);
7429 #ifdef HAVE_AS_GNU_ATTRIBUTE
7430 if (DEFAULT_ABI == ABI_V4)
7432 cum->escapes = call_ABI_of_interest (fndecl);
7439 return_type = TREE_TYPE (fntype);
7440 return_mode = TYPE_MODE (return_type);
7443 return_type = lang_hooks.types.type_for_mode (return_mode, 0);
7445 if (return_type != NULL)
7447 if (TREE_CODE (return_type) == RECORD_TYPE
7448 && TYPE_TRANSPARENT_AGGR (return_type))
7450 return_type = TREE_TYPE (first_field (return_type));
7451 return_mode = TYPE_MODE (return_type);
7453 if (AGGREGATE_TYPE_P (return_type)
7454 && ((unsigned HOST_WIDE_INT) int_size_in_bytes (return_type)
7456 rs6000_returns_struct = true;
7458 if (SCALAR_FLOAT_MODE_P (return_mode))
7459 rs6000_passes_float = true;
7460 else if (ALTIVEC_OR_VSX_VECTOR_MODE (return_mode)
7461 || SPE_VECTOR_MODE (return_mode))
7462 rs6000_passes_vector = true;
7469 && TARGET_ALTIVEC_ABI
7470 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
7472 error ("cannot return value in vector register because"
7473 " altivec instructions are disabled, use -maltivec"
7478 /* Return true if TYPE must be passed on the stack and not in registers. */
7481 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
7483 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
7484 return must_pass_in_stack_var_size (mode, type);
7486 return must_pass_in_stack_var_size_or_pad (mode, type);
7489 /* If defined, a C expression which determines whether, and in which
7490 direction, to pad out an argument with extra space. The value
7491 should be of type `enum direction': either `upward' to pad above
7492 the argument, `downward' to pad below, or `none' to inhibit
7495 For the AIX ABI structs are always stored left shifted in their
7499 function_arg_padding (enum machine_mode mode, const_tree type)
7501 #ifndef AGGREGATE_PADDING_FIXED
7502 #define AGGREGATE_PADDING_FIXED 0
7504 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
7505 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
7508 if (!AGGREGATE_PADDING_FIXED)
7510 /* GCC used to pass structures of the same size as integer types as
7511 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
7512 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
7513 passed padded downward, except that -mstrict-align further
7514 muddied the water in that multi-component structures of 2 and 4
7515 bytes in size were passed padded upward.
7517 The following arranges for best compatibility with previous
7518 versions of gcc, but removes the -mstrict-align dependency. */
7519 if (BYTES_BIG_ENDIAN)
7521 HOST_WIDE_INT size = 0;
7523 if (mode == BLKmode)
7525 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
7526 size = int_size_in_bytes (type);
7529 size = GET_MODE_SIZE (mode);
7531 if (size == 1 || size == 2 || size == 4)
7537 if (AGGREGATES_PAD_UPWARD_ALWAYS)
7539 if (type != 0 && AGGREGATE_TYPE_P (type))
7543 /* Fall back to the default. */
7544 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
7547 /* If defined, a C expression that gives the alignment boundary, in bits,
7548 of an argument with the specified mode and type. If it is not defined,
7549 PARM_BOUNDARY is used for all arguments.
7551 V.4 wants long longs and doubles to be double word aligned. Just
7552 testing the mode size is a boneheaded way to do this as it means
7553 that other types such as complex int are also double word aligned.
7554 However, we're stuck with this because changing the ABI might break
7555 existing library interfaces.
7557 Doubleword align SPE vectors.
7558 Quadword align Altivec/VSX vectors.
7559 Quadword align large synthetic vector types. */
7562 rs6000_function_arg_boundary (enum machine_mode mode, const_tree type)
7564 if (DEFAULT_ABI == ABI_V4
7565 && (GET_MODE_SIZE (mode) == 8
7566 || (TARGET_HARD_FLOAT
7568 && (mode == TFmode || mode == TDmode))))
7570 else if (SPE_VECTOR_MODE (mode)
7571 || (type && TREE_CODE (type) == VECTOR_TYPE
7572 && int_size_in_bytes (type) >= 8
7573 && int_size_in_bytes (type) < 16))
7575 else if (ALTIVEC_OR_VSX_VECTOR_MODE (mode)
7576 || (type && TREE_CODE (type) == VECTOR_TYPE
7577 && int_size_in_bytes (type) >= 16))
7579 else if (TARGET_MACHO
7580 && rs6000_darwin64_abi
7582 && type && TYPE_ALIGN (type) > 64)
7585 return PARM_BOUNDARY;
7588 /* For a function parm of MODE and TYPE, return the starting word in
7589 the parameter area. NWORDS of the parameter area are already used. */
7592 rs6000_parm_start (enum machine_mode mode, const_tree type,
7593 unsigned int nwords)
7596 unsigned int parm_offset;
7598 align = rs6000_function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
7599 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
7600 return nwords + (-(parm_offset + nwords) & align);
7603 /* Compute the size (in words) of a function argument. */
7605 static unsigned long
7606 rs6000_arg_size (enum machine_mode mode, const_tree type)
7610 if (mode != BLKmode)
7611 size = GET_MODE_SIZE (mode);
7613 size = int_size_in_bytes (type);
7616 return (size + 3) >> 2;
7618 return (size + 7) >> 3;
7621 /* Use this to flush pending int fields. */
7624 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
7625 HOST_WIDE_INT bitpos, int final)
7627 unsigned int startbit, endbit;
7628 int intregs, intoffset;
7629 enum machine_mode mode;
7631 /* Handle the situations where a float is taking up the first half
7632 of the GPR, and the other half is empty (typically due to
7633 alignment restrictions). We can detect this by a 8-byte-aligned
7634 int field, or by seeing that this is the final flush for this
7635 argument. Count the word and continue on. */
7636 if (cum->floats_in_gpr == 1
7637 && (cum->intoffset % 64 == 0
7638 || (cum->intoffset == -1 && final)))
7641 cum->floats_in_gpr = 0;
7644 if (cum->intoffset == -1)
7647 intoffset = cum->intoffset;
7648 cum->intoffset = -1;
7649 cum->floats_in_gpr = 0;
7651 if (intoffset % BITS_PER_WORD != 0)
7653 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7655 if (mode == BLKmode)
7657 /* We couldn't find an appropriate mode, which happens,
7658 e.g., in packed structs when there are 3 bytes to load.
7659 Back intoffset back to the beginning of the word in this
7661 intoffset = intoffset & -BITS_PER_WORD;
7665 startbit = intoffset & -BITS_PER_WORD;
7666 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7667 intregs = (endbit - startbit) / BITS_PER_WORD;
7668 cum->words += intregs;
7669 /* words should be unsigned. */
7670 if ((unsigned)cum->words < (endbit/BITS_PER_WORD))
7672 int pad = (endbit/BITS_PER_WORD) - cum->words;
7677 /* The darwin64 ABI calls for us to recurse down through structs,
7678 looking for elements passed in registers. Unfortunately, we have
7679 to track int register count here also because of misalignments
7680 in powerpc alignment mode. */
7683 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
7685 HOST_WIDE_INT startbitpos)
7689 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
7690 if (TREE_CODE (f) == FIELD_DECL)
7692 HOST_WIDE_INT bitpos = startbitpos;
7693 tree ftype = TREE_TYPE (f);
7694 enum machine_mode mode;
7695 if (ftype == error_mark_node)
7697 mode = TYPE_MODE (ftype);
7699 if (DECL_SIZE (f) != 0
7700 && host_integerp (bit_position (f), 1))
7701 bitpos += int_bit_position (f);
7703 /* ??? FIXME: else assume zero offset. */
7705 if (TREE_CODE (ftype) == RECORD_TYPE)
7706 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
7707 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
7709 unsigned n_fpregs = (GET_MODE_SIZE (mode) + 7) >> 3;
7710 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
7711 cum->fregno += n_fpregs;
7712 /* Single-precision floats present a special problem for
7713 us, because they are smaller than an 8-byte GPR, and so
7714 the structure-packing rules combined with the standard
7715 varargs behavior mean that we want to pack float/float
7716 and float/int combinations into a single register's
7717 space. This is complicated by the arg advance flushing,
7718 which works on arbitrarily large groups of int-type
7722 if (cum->floats_in_gpr == 1)
7724 /* Two floats in a word; count the word and reset
7727 cum->floats_in_gpr = 0;
7729 else if (bitpos % 64 == 0)
7731 /* A float at the beginning of an 8-byte word;
7732 count it and put off adjusting cum->words until
7733 we see if a arg advance flush is going to do it
7735 cum->floats_in_gpr++;
7739 /* The float is at the end of a word, preceded
7740 by integer fields, so the arg advance flush
7741 just above has already set cum->words and
7742 everything is taken care of. */
7746 cum->words += n_fpregs;
7748 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
7750 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
7754 else if (cum->intoffset == -1)
7755 cum->intoffset = bitpos;
7759 /* Check for an item that needs to be considered specially under the darwin 64
7760 bit ABI. These are record types where the mode is BLK or the structure is
7763 rs6000_darwin64_struct_check_p (enum machine_mode mode, const_tree type)
7765 return rs6000_darwin64_abi
7766 && ((mode == BLKmode
7767 && TREE_CODE (type) == RECORD_TYPE
7768 && int_size_in_bytes (type) > 0)
7769 || (type && TREE_CODE (type) == RECORD_TYPE
7770 && int_size_in_bytes (type) == 8)) ? 1 : 0;
7773 /* Update the data in CUM to advance over an argument
7774 of mode MODE and data type TYPE.
7775 (TYPE is null for libcalls where that information may not be available.)
7777 Note that for args passed by reference, function_arg will be called
7778 with MODE and TYPE set to that of the pointer to the arg, not the arg
7782 rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7783 const_tree type, bool named, int depth)
7785 /* Only tick off an argument if we're not recursing. */
7787 cum->nargs_prototype--;
7789 #ifdef HAVE_AS_GNU_ATTRIBUTE
7790 if (DEFAULT_ABI == ABI_V4
7793 if (SCALAR_FLOAT_MODE_P (mode))
7794 rs6000_passes_float = true;
7795 else if (named && ALTIVEC_OR_VSX_VECTOR_MODE (mode))
7796 rs6000_passes_vector = true;
7797 else if (SPE_VECTOR_MODE (mode)
7799 && cum->sysv_gregno <= GP_ARG_MAX_REG)
7800 rs6000_passes_vector = true;
7804 if (TARGET_ALTIVEC_ABI
7805 && (ALTIVEC_OR_VSX_VECTOR_MODE (mode)
7806 || (type && TREE_CODE (type) == VECTOR_TYPE
7807 && int_size_in_bytes (type) == 16)))
7811 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
7814 if (!TARGET_ALTIVEC)
7815 error ("cannot pass argument in vector register because"
7816 " altivec instructions are disabled, use -maltivec"
7819 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
7820 even if it is going to be passed in a vector register.
7821 Darwin does the same for variable-argument functions. */
7822 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
7823 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
7833 /* Vector parameters must be 16-byte aligned. This places
7834 them at 2 mod 4 in terms of words in 32-bit mode, since
7835 the parameter save area starts at offset 24 from the
7836 stack. In 64-bit mode, they just have to start on an
7837 even word, since the parameter save area is 16-byte
7838 aligned. Space for GPRs is reserved even if the argument
7839 will be passed in memory. */
7841 align = (2 - cum->words) & 3;
7843 align = cum->words & 1;
7844 cum->words += align + rs6000_arg_size (mode, type);
7846 if (TARGET_DEBUG_ARG)
7848 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
7850 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
7851 cum->nargs_prototype, cum->prototype,
7852 GET_MODE_NAME (mode));
7856 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
7858 && cum->sysv_gregno <= GP_ARG_MAX_REG)
7861 else if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
7863 int size = int_size_in_bytes (type);
7864 /* Variable sized types have size == -1 and are
7865 treated as if consisting entirely of ints.
7866 Pad to 16 byte boundary if needed. */
7867 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7868 && (cum->words % 2) != 0)
7870 /* For varargs, we can just go up by the size of the struct. */
7872 cum->words += (size + 7) / 8;
7875 /* It is tempting to say int register count just goes up by
7876 sizeof(type)/8, but this is wrong in a case such as
7877 { int; double; int; } [powerpc alignment]. We have to
7878 grovel through the fields for these too. */
7880 cum->floats_in_gpr = 0;
7881 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
7882 rs6000_darwin64_record_arg_advance_flush (cum,
7883 size * BITS_PER_UNIT, 1);
7885 if (TARGET_DEBUG_ARG)
7887 fprintf (stderr, "function_adv: words = %2d, align=%d, size=%d",
7888 cum->words, TYPE_ALIGN (type), size);
7890 "nargs = %4d, proto = %d, mode = %4s (darwin64 abi)\n",
7891 cum->nargs_prototype, cum->prototype,
7892 GET_MODE_NAME (mode));
7895 else if (DEFAULT_ABI == ABI_V4)
7897 if (TARGET_HARD_FLOAT && TARGET_FPRS
7898 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
7899 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
7900 || (mode == TFmode && !TARGET_IEEEQUAD)
7901 || mode == SDmode || mode == DDmode || mode == TDmode))
7903 /* _Decimal128 must use an even/odd register pair. This assumes
7904 that the register number is odd when fregno is odd. */
7905 if (mode == TDmode && (cum->fregno % 2) == 1)
7908 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7909 <= FP_ARG_V4_MAX_REG)
7910 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7913 cum->fregno = FP_ARG_V4_MAX_REG + 1;
7914 if (mode == DFmode || mode == TFmode
7915 || mode == DDmode || mode == TDmode)
7916 cum->words += cum->words & 1;
7917 cum->words += rs6000_arg_size (mode, type);
7922 int n_words = rs6000_arg_size (mode, type);
7923 int gregno = cum->sysv_gregno;
7925 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7926 (r7,r8) or (r9,r10). As does any other 2 word item such
7927 as complex int due to a historical mistake. */
7929 gregno += (1 - gregno) & 1;
7931 /* Multi-reg args are not split between registers and stack. */
7932 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7934 /* Long long and SPE vectors are aligned on the stack.
7935 So are other 2 word items such as complex int due to
7936 a historical mistake. */
7938 cum->words += cum->words & 1;
7939 cum->words += n_words;
7942 /* Note: continuing to accumulate gregno past when we've started
7943 spilling to the stack indicates the fact that we've started
7944 spilling to the stack to expand_builtin_saveregs. */
7945 cum->sysv_gregno = gregno + n_words;
7948 if (TARGET_DEBUG_ARG)
7950 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7951 cum->words, cum->fregno);
7952 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
7953 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
7954 fprintf (stderr, "mode = %4s, named = %d\n",
7955 GET_MODE_NAME (mode), named);
7960 int n_words = rs6000_arg_size (mode, type);
7961 int start_words = cum->words;
7962 int align_words = rs6000_parm_start (mode, type, start_words);
7964 cum->words = align_words + n_words;
7966 if (SCALAR_FLOAT_MODE_P (mode)
7967 && TARGET_HARD_FLOAT && TARGET_FPRS)
7969 /* _Decimal128 must be passed in an even/odd float register pair.
7970 This assumes that the register number is odd when fregno is
7972 if (mode == TDmode && (cum->fregno % 2) == 1)
7974 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7977 if (TARGET_DEBUG_ARG)
7979 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7980 cum->words, cum->fregno);
7981 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
7982 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
7983 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
7984 named, align_words - start_words, depth);
7990 rs6000_function_arg_advance (cumulative_args_t cum, enum machine_mode mode,
7991 const_tree type, bool named)
7993 rs6000_function_arg_advance_1 (get_cumulative_args (cum), mode, type, named,
7998 spe_build_register_parallel (enum machine_mode mode, int gregno)
8005 r1 = gen_rtx_REG (DImode, gregno);
8006 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8007 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
8011 r1 = gen_rtx_REG (DImode, gregno);
8012 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8013 r3 = gen_rtx_REG (DImode, gregno + 2);
8014 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8015 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
8018 r1 = gen_rtx_REG (DImode, gregno);
8019 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8020 r3 = gen_rtx_REG (DImode, gregno + 2);
8021 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8022 r5 = gen_rtx_REG (DImode, gregno + 4);
8023 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
8024 r7 = gen_rtx_REG (DImode, gregno + 6);
8025 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
8026 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
8033 /* Determine where to put a SIMD argument on the SPE. */
8035 rs6000_spe_function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
8038 int gregno = cum->sysv_gregno;
8040 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
8041 are passed and returned in a pair of GPRs for ABI compatibility. */
8042 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
8043 || mode == DCmode || mode == TCmode))
8045 int n_words = rs6000_arg_size (mode, type);
8047 /* Doubles go in an odd/even register pair (r5/r6, etc). */
8049 gregno += (1 - gregno) & 1;
8051 /* Multi-reg args are not split between registers and stack. */
8052 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8055 return spe_build_register_parallel (mode, gregno);
8059 int n_words = rs6000_arg_size (mode, type);
8061 /* SPE vectors are put in odd registers. */
8062 if (n_words == 2 && (gregno & 1) == 0)
8065 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
8068 enum machine_mode m = SImode;
8070 r1 = gen_rtx_REG (m, gregno);
8071 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
8072 r2 = gen_rtx_REG (m, gregno + 1);
8073 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
8074 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
8081 if (gregno <= GP_ARG_MAX_REG)
8082 return gen_rtx_REG (mode, gregno);
8088 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
8089 structure between cum->intoffset and bitpos to integer registers. */
8092 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
8093 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
8095 enum machine_mode mode;
8097 unsigned int startbit, endbit;
8098 int this_regno, intregs, intoffset;
8101 if (cum->intoffset == -1)
8104 intoffset = cum->intoffset;
8105 cum->intoffset = -1;
8107 /* If this is the trailing part of a word, try to only load that
8108 much into the register. Otherwise load the whole register. Note
8109 that in the latter case we may pick up unwanted bits. It's not a
8110 problem at the moment but may wish to revisit. */
8112 if (intoffset % BITS_PER_WORD != 0)
8114 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
8116 if (mode == BLKmode)
8118 /* We couldn't find an appropriate mode, which happens,
8119 e.g., in packed structs when there are 3 bytes to load.
8120 Back intoffset back to the beginning of the word in this
8122 intoffset = intoffset & -BITS_PER_WORD;
8129 startbit = intoffset & -BITS_PER_WORD;
8130 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
8131 intregs = (endbit - startbit) / BITS_PER_WORD;
8132 this_regno = cum->words + intoffset / BITS_PER_WORD;
8134 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
8137 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
8141 intoffset /= BITS_PER_UNIT;
8144 regno = GP_ARG_MIN_REG + this_regno;
8145 reg = gen_rtx_REG (mode, regno);
8147 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
8150 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
8154 while (intregs > 0);
8157 /* Recursive workhorse for the following. */
8160 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
8161 HOST_WIDE_INT startbitpos, rtx rvec[],
8166 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
8167 if (TREE_CODE (f) == FIELD_DECL)
8169 HOST_WIDE_INT bitpos = startbitpos;
8170 tree ftype = TREE_TYPE (f);
8171 enum machine_mode mode;
8172 if (ftype == error_mark_node)
8174 mode = TYPE_MODE (ftype);
8176 if (DECL_SIZE (f) != 0
8177 && host_integerp (bit_position (f), 1))
8178 bitpos += int_bit_position (f);
8180 /* ??? FIXME: else assume zero offset. */
8182 if (TREE_CODE (ftype) == RECORD_TYPE)
8183 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
8184 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
8186 unsigned n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
8190 case SCmode: mode = SFmode; break;
8191 case DCmode: mode = DFmode; break;
8192 case TCmode: mode = TFmode; break;
8196 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8197 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
8199 gcc_assert (cum->fregno == FP_ARG_MAX_REG
8200 && (mode == TFmode || mode == TDmode));
8201 /* Long double or _Decimal128 split over regs and memory. */
8202 mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : DFmode;
8206 = gen_rtx_EXPR_LIST (VOIDmode,
8207 gen_rtx_REG (mode, cum->fregno++),
8208 GEN_INT (bitpos / BITS_PER_UNIT));
8209 if (mode == TFmode || mode == TDmode)
8212 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
8214 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8216 = gen_rtx_EXPR_LIST (VOIDmode,
8217 gen_rtx_REG (mode, cum->vregno++),
8218 GEN_INT (bitpos / BITS_PER_UNIT));
8220 else if (cum->intoffset == -1)
8221 cum->intoffset = bitpos;
8225 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
8226 the register(s) to be used for each field and subfield of a struct
8227 being passed by value, along with the offset of where the
8228 register's value may be found in the block. FP fields go in FP
8229 register, vector fields go in vector registers, and everything
8230 else goes in int registers, packed as in memory.
8232 This code is also used for function return values. RETVAL indicates
8233 whether this is the case.
8235 Much of this is taken from the SPARC V9 port, which has a similar
8236 calling convention. */
8239 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
8240 bool named, bool retval)
8242 rtx rvec[FIRST_PSEUDO_REGISTER];
8243 int k = 1, kbase = 1;
8244 HOST_WIDE_INT typesize = int_size_in_bytes (type);
8245 /* This is a copy; modifications are not visible to our caller. */
8246 CUMULATIVE_ARGS copy_cum = *orig_cum;
8247 CUMULATIVE_ARGS *cum = ©_cum;
8249 /* Pad to 16 byte boundary if needed. */
8250 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8251 && (cum->words % 2) != 0)
8258 /* Put entries into rvec[] for individual FP and vector fields, and
8259 for the chunks of memory that go in int regs. Note we start at
8260 element 1; 0 is reserved for an indication of using memory, and
8261 may or may not be filled in below. */
8262 rs6000_darwin64_record_arg_recurse (cum, type, /* startbit pos= */ 0, rvec, &k);
8263 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
8265 /* If any part of the struct went on the stack put all of it there.
8266 This hack is because the generic code for
8267 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
8268 parts of the struct are not at the beginning. */
8272 return NULL_RTX; /* doesn't go in registers at all */
8274 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8276 if (k > 1 || cum->use_stack)
8277 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
8282 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
8285 rs6000_mixed_function_arg (enum machine_mode mode, const_tree type,
8290 rtx rvec[GP_ARG_NUM_REG + 1];
8292 if (align_words >= GP_ARG_NUM_REG)
8295 n_units = rs6000_arg_size (mode, type);
8297 /* Optimize the simple case where the arg fits in one gpr, except in
8298 the case of BLKmode due to assign_parms assuming that registers are
8299 BITS_PER_WORD wide. */
8301 || (n_units == 1 && mode != BLKmode))
8302 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8305 if (align_words + n_units > GP_ARG_NUM_REG)
8306 /* Not all of the arg fits in gprs. Say that it goes in memory too,
8307 using a magic NULL_RTX component.
8308 This is not strictly correct. Only some of the arg belongs in
8309 memory, not all of it. However, the normal scheme using
8310 function_arg_partial_nregs can result in unusual subregs, eg.
8311 (subreg:SI (reg:DF) 4), which are not handled well. The code to
8312 store the whole arg to memory is often more efficient than code
8313 to store pieces, and we know that space is available in the right
8314 place for the whole arg. */
8315 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8320 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
8321 rtx off = GEN_INT (i++ * 4);
8322 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8324 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
8326 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8329 /* Determine where to put an argument to a function.
8330 Value is zero to push the argument on the stack,
8331 or a hard register in which to store the argument.
8333 MODE is the argument's machine mode.
8334 TYPE is the data type of the argument (as a tree).
8335 This is null for libcalls where that information may
8337 CUM is a variable of type CUMULATIVE_ARGS which gives info about
8338 the preceding args and about the function being called. It is
8339 not modified in this routine.
8340 NAMED is nonzero if this argument is a named parameter
8341 (otherwise it is an extra parameter matching an ellipsis).
8343 On RS/6000 the first eight words of non-FP are normally in registers
8344 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
8345 Under V.4, the first 8 FP args are in registers.
8347 If this is floating-point and no prototype is specified, we use
8348 both an FP and integer register (or possibly FP reg and stack). Library
8349 functions (when CALL_LIBCALL is set) always have the proper types for args,
8350 so we can pass the FP value just in one register. emit_library_function
8351 doesn't support PARALLEL anyway.
8353 Note that for args passed by reference, function_arg will be called
8354 with MODE and TYPE set to that of the pointer to the arg, not the arg
8358 rs6000_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
8359 const_tree type, bool named)
8361 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
8362 enum rs6000_abi abi = DEFAULT_ABI;
8364 /* Return a marker to indicate whether CR1 needs to set or clear the
8365 bit that V.4 uses to say fp args were passed in registers.
8366 Assume that we don't need the marker for software floating point,
8367 or compiler generated library calls. */
8368 if (mode == VOIDmode)
8371 && (cum->call_cookie & CALL_LIBCALL) == 0
8373 || (cum->nargs_prototype < 0
8374 && (cum->prototype || TARGET_NO_PROTOTYPE))))
8376 /* For the SPE, we need to crxor CR6 always. */
8378 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
8379 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
8380 return GEN_INT (cum->call_cookie
8381 | ((cum->fregno == FP_ARG_MIN_REG)
8382 ? CALL_V4_SET_FP_ARGS
8383 : CALL_V4_CLEAR_FP_ARGS));
8386 return GEN_INT (cum->call_cookie & ~CALL_LIBCALL);
8389 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8391 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, /*retval= */false);
8392 if (rslt != NULL_RTX)
8394 /* Else fall through to usual handling. */
8397 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
8398 if (TARGET_64BIT && ! cum->prototype)
8400 /* Vector parameters get passed in vector register
8401 and also in GPRs or memory, in absence of prototype. */
8404 align_words = (cum->words + 1) & ~1;
8406 if (align_words >= GP_ARG_NUM_REG)
8412 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8414 return gen_rtx_PARALLEL (mode,
8416 gen_rtx_EXPR_LIST (VOIDmode,
8418 gen_rtx_EXPR_LIST (VOIDmode,
8419 gen_rtx_REG (mode, cum->vregno),
8423 return gen_rtx_REG (mode, cum->vregno);
8424 else if (TARGET_ALTIVEC_ABI
8425 && (ALTIVEC_OR_VSX_VECTOR_MODE (mode)
8426 || (type && TREE_CODE (type) == VECTOR_TYPE
8427 && int_size_in_bytes (type) == 16)))
8429 if (named || abi == ABI_V4)
8433 /* Vector parameters to varargs functions under AIX or Darwin
8434 get passed in memory and possibly also in GPRs. */
8435 int align, align_words, n_words;
8436 enum machine_mode part_mode;
8438 /* Vector parameters must be 16-byte aligned. This places them at
8439 2 mod 4 in terms of words in 32-bit mode, since the parameter
8440 save area starts at offset 24 from the stack. In 64-bit mode,
8441 they just have to start on an even word, since the parameter
8442 save area is 16-byte aligned. */
8444 align = (2 - cum->words) & 3;
8446 align = cum->words & 1;
8447 align_words = cum->words + align;
8449 /* Out of registers? Memory, then. */
8450 if (align_words >= GP_ARG_NUM_REG)
8453 if (TARGET_32BIT && TARGET_POWERPC64)
8454 return rs6000_mixed_function_arg (mode, type, align_words);
8456 /* The vector value goes in GPRs. Only the part of the
8457 value in GPRs is reported here. */
8459 n_words = rs6000_arg_size (mode, type);
8460 if (align_words + n_words > GP_ARG_NUM_REG)
8461 /* Fortunately, there are only two possibilities, the value
8462 is either wholly in GPRs or half in GPRs and half not. */
8465 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
8468 else if (TARGET_SPE_ABI && TARGET_SPE
8469 && (SPE_VECTOR_MODE (mode)
8470 || (TARGET_E500_DOUBLE && (mode == DFmode
8473 || mode == TCmode))))
8474 return rs6000_spe_function_arg (cum, mode, type);
8476 else if (abi == ABI_V4)
8478 if (TARGET_HARD_FLOAT && TARGET_FPRS
8479 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8480 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8481 || (mode == TFmode && !TARGET_IEEEQUAD)
8482 || mode == SDmode || mode == DDmode || mode == TDmode))
8484 /* _Decimal128 must use an even/odd register pair. This assumes
8485 that the register number is odd when fregno is odd. */
8486 if (mode == TDmode && (cum->fregno % 2) == 1)
8489 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8490 <= FP_ARG_V4_MAX_REG)
8491 return gen_rtx_REG (mode, cum->fregno);
8497 int n_words = rs6000_arg_size (mode, type);
8498 int gregno = cum->sysv_gregno;
8500 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8501 (r7,r8) or (r9,r10). As does any other 2 word item such
8502 as complex int due to a historical mistake. */
8504 gregno += (1 - gregno) & 1;
8506 /* Multi-reg args are not split between registers and stack. */
8507 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8510 if (TARGET_32BIT && TARGET_POWERPC64)
8511 return rs6000_mixed_function_arg (mode, type,
8512 gregno - GP_ARG_MIN_REG);
8513 return gen_rtx_REG (mode, gregno);
8518 int align_words = rs6000_parm_start (mode, type, cum->words);
8520 /* _Decimal128 must be passed in an even/odd float register pair.
8521 This assumes that the register number is odd when fregno is odd. */
8522 if (mode == TDmode && (cum->fregno % 2) == 1)
8525 if (USE_FP_FOR_ARG_P (cum, mode, type))
8527 rtx rvec[GP_ARG_NUM_REG + 1];
8531 enum machine_mode fmode = mode;
8532 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
8534 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
8536 /* Currently, we only ever need one reg here because complex
8537 doubles are split. */
8538 gcc_assert (cum->fregno == FP_ARG_MAX_REG
8539 && (fmode == TFmode || fmode == TDmode));
8541 /* Long double or _Decimal128 split over regs and memory. */
8542 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
8545 /* Do we also need to pass this arg in the parameter save
8548 && (cum->nargs_prototype <= 0
8549 || (DEFAULT_ABI == ABI_AIX
8551 && align_words >= GP_ARG_NUM_REG)));
8553 if (!needs_psave && mode == fmode)
8554 return gen_rtx_REG (fmode, cum->fregno);
8559 /* Describe the part that goes in gprs or the stack.
8560 This piece must come first, before the fprs. */
8561 if (align_words < GP_ARG_NUM_REG)
8563 unsigned long n_words = rs6000_arg_size (mode, type);
8565 if (align_words + n_words > GP_ARG_NUM_REG
8566 || (TARGET_32BIT && TARGET_POWERPC64))
8568 /* If this is partially on the stack, then we only
8569 include the portion actually in registers here. */
8570 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
8573 if (align_words + n_words > GP_ARG_NUM_REG)
8574 /* Not all of the arg fits in gprs. Say that it
8575 goes in memory too, using a magic NULL_RTX
8576 component. Also see comment in
8577 rs6000_mixed_function_arg for why the normal
8578 function_arg_partial_nregs scheme doesn't work
8580 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
8584 r = gen_rtx_REG (rmode,
8585 GP_ARG_MIN_REG + align_words);
8586 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
8587 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8589 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
8593 /* The whole arg fits in gprs. */
8594 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8595 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8599 /* It's entirely in memory. */
8600 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8603 /* Describe where this piece goes in the fprs. */
8604 r = gen_rtx_REG (fmode, cum->fregno);
8605 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8607 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8609 else if (align_words < GP_ARG_NUM_REG)
8611 if (TARGET_32BIT && TARGET_POWERPC64)
8612 return rs6000_mixed_function_arg (mode, type, align_words);
8614 if (mode == BLKmode)
8617 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8624 /* For an arg passed partly in registers and partly in memory, this is
8625 the number of bytes passed in registers. For args passed entirely in
8626 registers or entirely in memory, zero. When an arg is described by a
8627 PARALLEL, perhaps using more than one register type, this function
8628 returns the number of bytes used by the first element of the PARALLEL. */
8631 rs6000_arg_partial_bytes (cumulative_args_t cum_v, enum machine_mode mode,
8632 tree type, bool named)
8634 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
8638 if (DEFAULT_ABI == ABI_V4)
8641 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
8642 && cum->nargs_prototype >= 0)
8645 /* In this complicated case we just disable the partial_nregs code. */
8646 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8649 align_words = rs6000_parm_start (mode, type, cum->words);
8651 if (USE_FP_FOR_ARG_P (cum, mode, type))
8653 /* If we are passing this arg in the fixed parameter save area
8654 (gprs or memory) as well as fprs, then this function should
8655 return the number of partial bytes passed in the parameter
8656 save area rather than partial bytes passed in fprs. */
8658 && (cum->nargs_prototype <= 0
8659 || (DEFAULT_ABI == ABI_AIX
8661 && align_words >= GP_ARG_NUM_REG)))
8663 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
8664 > FP_ARG_MAX_REG + 1)
8665 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
8666 else if (cum->nargs_prototype >= 0)
8670 if (align_words < GP_ARG_NUM_REG
8671 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
8672 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
8674 if (ret != 0 && TARGET_DEBUG_ARG)
8675 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
8680 /* A C expression that indicates when an argument must be passed by
8681 reference. If nonzero for an argument, a copy of that argument is
8682 made in memory and a pointer to the argument is passed instead of
8683 the argument itself. The pointer is passed in whatever way is
8684 appropriate for passing a pointer to that type.
8686 Under V.4, aggregates and long double are passed by reference.
8688 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
8689 reference unless the AltiVec vector extension ABI is in force.
8691 As an extension to all ABIs, variable sized types are passed by
8695 rs6000_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED,
8696 enum machine_mode mode, const_tree type,
8697 bool named ATTRIBUTE_UNUSED)
8699 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
8701 if (TARGET_DEBUG_ARG)
8702 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
8709 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
8711 if (TARGET_DEBUG_ARG)
8712 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
8716 if (int_size_in_bytes (type) < 0)
8718 if (TARGET_DEBUG_ARG)
8719 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
8723 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
8724 modes only exist for GCC vector types if -maltivec. */
8725 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
8727 if (TARGET_DEBUG_ARG)
8728 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
8732 /* Pass synthetic vectors in memory. */
8733 if (TREE_CODE (type) == VECTOR_TYPE
8734 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
8736 static bool warned_for_pass_big_vectors = false;
8737 if (TARGET_DEBUG_ARG)
8738 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
8739 if (!warned_for_pass_big_vectors)
8741 warning (0, "GCC vector passed by reference: "
8742 "non-standard ABI extension with no compatibility guarantee");
8743 warned_for_pass_big_vectors = true;
8752 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
8755 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
8760 for (i = 0; i < nregs; i++)
8762 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
8763 if (reload_completed)
8765 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
8768 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
8769 i * GET_MODE_SIZE (reg_mode));
8772 tem = replace_equiv_address (tem, XEXP (tem, 0));
8776 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
8780 /* Perform any needed actions needed for a function that is receiving a
8781 variable number of arguments.
8785 MODE and TYPE are the mode and type of the current parameter.
8787 PRETEND_SIZE is a variable that should be set to the amount of stack
8788 that must be pushed by the prolog to pretend that our caller pushed
8791 Normally, this macro will push all remaining incoming registers on the
8792 stack and set PRETEND_SIZE to the length of the registers pushed. */
8795 setup_incoming_varargs (cumulative_args_t cum, enum machine_mode mode,
8796 tree type, int *pretend_size ATTRIBUTE_UNUSED,
8799 CUMULATIVE_ARGS next_cum;
8800 int reg_size = TARGET_32BIT ? 4 : 8;
8801 rtx save_area = NULL_RTX, mem;
8802 int first_reg_offset;
8805 /* Skip the last named argument. */
8806 next_cum = *get_cumulative_args (cum);
8807 rs6000_function_arg_advance_1 (&next_cum, mode, type, true, 0);
8809 if (DEFAULT_ABI == ABI_V4)
8811 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
8815 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
8816 HOST_WIDE_INT offset = 0;
8818 /* Try to optimize the size of the varargs save area.
8819 The ABI requires that ap.reg_save_area is doubleword
8820 aligned, but we don't need to allocate space for all
8821 the bytes, only those to which we actually will save
8823 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
8824 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
8825 if (TARGET_HARD_FLOAT && TARGET_FPRS
8826 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8827 && cfun->va_list_fpr_size)
8830 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
8831 * UNITS_PER_FP_WORD;
8832 if (cfun->va_list_fpr_size
8833 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8834 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
8836 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8837 * UNITS_PER_FP_WORD;
8841 offset = -((first_reg_offset * reg_size) & ~7);
8842 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
8844 gpr_reg_num = cfun->va_list_gpr_size;
8845 if (reg_size == 4 && (first_reg_offset & 1))
8848 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
8851 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
8853 - (int) (GP_ARG_NUM_REG * reg_size);
8855 if (gpr_size + fpr_size)
8858 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
8859 gcc_assert (GET_CODE (reg_save_area) == MEM);
8860 reg_save_area = XEXP (reg_save_area, 0);
8861 if (GET_CODE (reg_save_area) == PLUS)
8863 gcc_assert (XEXP (reg_save_area, 0)
8864 == virtual_stack_vars_rtx);
8865 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
8866 offset += INTVAL (XEXP (reg_save_area, 1));
8869 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
8872 cfun->machine->varargs_save_offset = offset;
8873 save_area = plus_constant (virtual_stack_vars_rtx, offset);
8878 first_reg_offset = next_cum.words;
8879 save_area = virtual_incoming_args_rtx;
8881 if (targetm.calls.must_pass_in_stack (mode, type))
8882 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
8885 set = get_varargs_alias_set ();
8886 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
8887 && cfun->va_list_gpr_size)
8889 int nregs = GP_ARG_NUM_REG - first_reg_offset;
8891 if (va_list_gpr_counter_field)
8893 /* V4 va_list_gpr_size counts number of registers needed. */
8894 if (nregs > cfun->va_list_gpr_size)
8895 nregs = cfun->va_list_gpr_size;
8899 /* char * va_list instead counts number of bytes needed. */
8900 if (nregs > cfun->va_list_gpr_size / reg_size)
8901 nregs = cfun->va_list_gpr_size / reg_size;
8904 mem = gen_rtx_MEM (BLKmode,
8905 plus_constant (save_area,
8906 first_reg_offset * reg_size));
8907 MEM_NOTRAP_P (mem) = 1;
8908 set_mem_alias_set (mem, set);
8909 set_mem_align (mem, BITS_PER_WORD);
8911 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
8915 /* Save FP registers if needed. */
8916 if (DEFAULT_ABI == ABI_V4
8917 && TARGET_HARD_FLOAT && TARGET_FPRS
8919 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8920 && cfun->va_list_fpr_size)
8922 int fregno = next_cum.fregno, nregs;
8923 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
8924 rtx lab = gen_label_rtx ();
8925 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
8926 * UNITS_PER_FP_WORD);
8929 (gen_rtx_SET (VOIDmode,
8931 gen_rtx_IF_THEN_ELSE (VOIDmode,
8932 gen_rtx_NE (VOIDmode, cr1,
8934 gen_rtx_LABEL_REF (VOIDmode, lab),
8938 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
8939 fregno++, off += UNITS_PER_FP_WORD, nregs++)
8941 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8943 plus_constant (save_area, off));
8944 MEM_NOTRAP_P (mem) = 1;
8945 set_mem_alias_set (mem, set);
8946 set_mem_align (mem, GET_MODE_ALIGNMENT (
8947 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8948 ? DFmode : SFmode));
8949 emit_move_insn (mem, gen_rtx_REG (
8950 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8951 ? DFmode : SFmode, fregno));
8958 /* Create the va_list data type. */
8961 rs6000_build_builtin_va_list (void)
8963 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
8965 /* For AIX, prefer 'char *' because that's what the system
8966 header files like. */
8967 if (DEFAULT_ABI != ABI_V4)
8968 return build_pointer_type (char_type_node);
8970 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
8971 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
8972 get_identifier ("__va_list_tag"), record);
8974 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
8975 unsigned_char_type_node);
8976 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
8977 unsigned_char_type_node);
8978 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
8980 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8981 get_identifier ("reserved"), short_unsigned_type_node);
8982 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8983 get_identifier ("overflow_arg_area"),
8985 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8986 get_identifier ("reg_save_area"),
8989 va_list_gpr_counter_field = f_gpr;
8990 va_list_fpr_counter_field = f_fpr;
8992 DECL_FIELD_CONTEXT (f_gpr) = record;
8993 DECL_FIELD_CONTEXT (f_fpr) = record;
8994 DECL_FIELD_CONTEXT (f_res) = record;
8995 DECL_FIELD_CONTEXT (f_ovf) = record;
8996 DECL_FIELD_CONTEXT (f_sav) = record;
8998 TYPE_STUB_DECL (record) = type_decl;
8999 TYPE_NAME (record) = type_decl;
9000 TYPE_FIELDS (record) = f_gpr;
9001 DECL_CHAIN (f_gpr) = f_fpr;
9002 DECL_CHAIN (f_fpr) = f_res;
9003 DECL_CHAIN (f_res) = f_ovf;
9004 DECL_CHAIN (f_ovf) = f_sav;
9006 layout_type (record);
9008 /* The correct type is an array type of one element. */
9009 return build_array_type (record, build_index_type (size_zero_node));
9012 /* Implement va_start. */
9015 rs6000_va_start (tree valist, rtx nextarg)
9017 HOST_WIDE_INT words, n_gpr, n_fpr;
9018 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9019 tree gpr, fpr, ovf, sav, t;
9021 /* Only SVR4 needs something special. */
9022 if (DEFAULT_ABI != ABI_V4)
9024 std_expand_builtin_va_start (valist, nextarg);
9028 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9029 f_fpr = DECL_CHAIN (f_gpr);
9030 f_res = DECL_CHAIN (f_fpr);
9031 f_ovf = DECL_CHAIN (f_res);
9032 f_sav = DECL_CHAIN (f_ovf);
9034 valist = build_simple_mem_ref (valist);
9035 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9036 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9038 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9040 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9043 /* Count number of gp and fp argument registers used. */
9044 words = crtl->args.info.words;
9045 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
9047 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
9050 if (TARGET_DEBUG_ARG)
9051 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
9052 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
9053 words, n_gpr, n_fpr);
9055 if (cfun->va_list_gpr_size)
9057 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
9058 build_int_cst (NULL_TREE, n_gpr));
9059 TREE_SIDE_EFFECTS (t) = 1;
9060 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9063 if (cfun->va_list_fpr_size)
9065 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
9066 build_int_cst (NULL_TREE, n_fpr));
9067 TREE_SIDE_EFFECTS (t) = 1;
9068 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9070 #ifdef HAVE_AS_GNU_ATTRIBUTE
9071 if (call_ABI_of_interest (cfun->decl))
9072 rs6000_passes_float = true;
9076 /* Find the overflow area. */
9077 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
9079 t = fold_build_pointer_plus_hwi (t, words * UNITS_PER_WORD);
9080 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
9081 TREE_SIDE_EFFECTS (t) = 1;
9082 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9084 /* If there were no va_arg invocations, don't set up the register
9086 if (!cfun->va_list_gpr_size
9087 && !cfun->va_list_fpr_size
9088 && n_gpr < GP_ARG_NUM_REG
9089 && n_fpr < FP_ARG_V4_MAX_REG)
9092 /* Find the register save area. */
9093 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
9094 if (cfun->machine->varargs_save_offset)
9095 t = fold_build_pointer_plus_hwi (t, cfun->machine->varargs_save_offset);
9096 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
9097 TREE_SIDE_EFFECTS (t) = 1;
9098 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9101 /* Implement va_arg. */
9104 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
9107 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9108 tree gpr, fpr, ovf, sav, reg, t, u;
9109 int size, rsize, n_reg, sav_ofs, sav_scale;
9110 tree lab_false, lab_over, addr;
9112 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
9116 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
9118 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
9119 return build_va_arg_indirect_ref (t);
9122 /* We need to deal with the fact that the darwin ppc64 ABI is defined by an
9123 earlier version of gcc, with the property that it always applied alignment
9124 adjustments to the va-args (even for zero-sized types). The cheapest way
9125 to deal with this is to replicate the effect of the part of
9126 std_gimplify_va_arg_expr that carries out the align adjust, for the case
9128 We don't need to check for pass-by-reference because of the test above.
9129 We can return a simplifed answer, since we know there's no offset to add. */
9132 && rs6000_darwin64_abi
9133 && integer_zerop (TYPE_SIZE (type)))
9135 unsigned HOST_WIDE_INT align, boundary;
9136 tree valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
9137 align = PARM_BOUNDARY / BITS_PER_UNIT;
9138 boundary = rs6000_function_arg_boundary (TYPE_MODE (type), type);
9139 if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
9140 boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
9141 boundary /= BITS_PER_UNIT;
9142 if (boundary > align)
9145 /* This updates arg ptr by the amount that would be necessary
9146 to align the zero-sized (but not zero-alignment) item. */
9147 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9148 fold_build_pointer_plus_hwi (valist_tmp, boundary - 1));
9149 gimplify_and_add (t, pre_p);
9151 t = fold_convert (sizetype, valist_tmp);
9152 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9153 fold_convert (TREE_TYPE (valist),
9154 fold_build2 (BIT_AND_EXPR, sizetype, t,
9155 size_int (-boundary))));
9156 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
9157 gimplify_and_add (t, pre_p);
9159 /* Since it is zero-sized there's no increment for the item itself. */
9160 valist_tmp = fold_convert (build_pointer_type (type), valist_tmp);
9161 return build_va_arg_indirect_ref (valist_tmp);
9164 if (DEFAULT_ABI != ABI_V4)
9166 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
9168 tree elem_type = TREE_TYPE (type);
9169 enum machine_mode elem_mode = TYPE_MODE (elem_type);
9170 int elem_size = GET_MODE_SIZE (elem_mode);
9172 if (elem_size < UNITS_PER_WORD)
9174 tree real_part, imag_part;
9175 gimple_seq post = NULL;
9177 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9179 /* Copy the value into a temporary, lest the formal temporary
9180 be reused out from under us. */
9181 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
9182 gimple_seq_add_seq (pre_p, post);
9184 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9187 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
9191 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
9194 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9195 f_fpr = DECL_CHAIN (f_gpr);
9196 f_res = DECL_CHAIN (f_fpr);
9197 f_ovf = DECL_CHAIN (f_res);
9198 f_sav = DECL_CHAIN (f_ovf);
9200 valist = build_va_arg_indirect_ref (valist);
9201 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9202 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9204 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9206 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9209 size = int_size_in_bytes (type);
9210 rsize = (size + 3) / 4;
9213 if (TARGET_HARD_FLOAT && TARGET_FPRS
9214 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
9215 || (TARGET_DOUBLE_FLOAT
9216 && (TYPE_MODE (type) == DFmode
9217 || TYPE_MODE (type) == TFmode
9218 || TYPE_MODE (type) == SDmode
9219 || TYPE_MODE (type) == DDmode
9220 || TYPE_MODE (type) == TDmode))))
9222 /* FP args go in FP registers, if present. */
9224 n_reg = (size + 7) / 8;
9225 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
9226 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
9227 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
9232 /* Otherwise into GP registers. */
9241 /* Pull the value out of the saved registers.... */
9244 addr = create_tmp_var (ptr_type_node, "addr");
9246 /* AltiVec vectors never go in registers when -mabi=altivec. */
9247 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
9251 lab_false = create_artificial_label (input_location);
9252 lab_over = create_artificial_label (input_location);
9254 /* Long long and SPE vectors are aligned in the registers.
9255 As are any other 2 gpr item such as complex int due to a
9256 historical mistake. */
9258 if (n_reg == 2 && reg == gpr)
9261 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9262 build_int_cst (TREE_TYPE (reg), n_reg - 1));
9263 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
9264 unshare_expr (reg), u);
9266 /* _Decimal128 is passed in even/odd fpr pairs; the stored
9267 reg number is 0 for f1, so we want to make it odd. */
9268 else if (reg == fpr && TYPE_MODE (type) == TDmode)
9270 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9271 build_int_cst (TREE_TYPE (reg), 1));
9272 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
9275 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
9276 t = build2 (GE_EXPR, boolean_type_node, u, t);
9277 u = build1 (GOTO_EXPR, void_type_node, lab_false);
9278 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
9279 gimplify_and_add (t, pre_p);
9283 t = fold_build_pointer_plus_hwi (sav, sav_ofs);
9285 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9286 build_int_cst (TREE_TYPE (reg), n_reg));
9287 u = fold_convert (sizetype, u);
9288 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
9289 t = fold_build_pointer_plus (t, u);
9291 /* _Decimal32 varargs are located in the second word of the 64-bit
9292 FP register for 32-bit binaries. */
9293 if (!TARGET_POWERPC64
9294 && TARGET_HARD_FLOAT && TARGET_FPRS
9295 && TYPE_MODE (type) == SDmode)
9296 t = fold_build_pointer_plus_hwi (t, size);
9298 gimplify_assign (addr, t, pre_p);
9300 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
9302 stmt = gimple_build_label (lab_false);
9303 gimple_seq_add_stmt (pre_p, stmt);
9305 if ((n_reg == 2 && !regalign) || n_reg > 2)
9307 /* Ensure that we don't find any more args in regs.
9308 Alignment has taken care of for special cases. */
9309 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
9313 /* ... otherwise out of the overflow area. */
9315 /* Care for on-stack alignment if needed. */
9319 t = fold_build_pointer_plus_hwi (t, align - 1);
9320 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
9321 build_int_cst (TREE_TYPE (t), -align));
9323 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
9325 gimplify_assign (unshare_expr (addr), t, pre_p);
9327 t = fold_build_pointer_plus_hwi (t, size);
9328 gimplify_assign (unshare_expr (ovf), t, pre_p);
9332 stmt = gimple_build_label (lab_over);
9333 gimple_seq_add_stmt (pre_p, stmt);
9336 if (STRICT_ALIGNMENT
9337 && (TYPE_ALIGN (type)
9338 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
9340 /* The value (of type complex double, for example) may not be
9341 aligned in memory in the saved registers, so copy via a
9342 temporary. (This is the same code as used for SPARC.) */
9343 tree tmp = create_tmp_var (type, "va_arg_tmp");
9344 tree dest_addr = build_fold_addr_expr (tmp);
9346 tree copy = build_call_expr (builtin_decl_implicit (BUILT_IN_MEMCPY),
9347 3, dest_addr, addr, size_int (rsize * 4));
9349 gimplify_and_add (copy, pre_p);
9353 addr = fold_convert (ptrtype, addr);
9354 return build_va_arg_indirect_ref (addr);
9360 def_builtin (int mask, const char *name, tree type, int code)
9362 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
9365 if (rs6000_builtin_decls[code])
9366 fatal_error ("internal error: builtin function to %s already processed",
9369 rs6000_builtin_decls[code] = t =
9370 add_builtin_function (name, type, code, BUILT_IN_MD,
9373 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT);
9374 switch (builtin_classify[code])
9379 /* assume builtin can do anything. */
9380 case RS6000_BTC_MISC:
9383 /* const function, function only depends on the inputs. */
9384 case RS6000_BTC_CONST:
9385 TREE_READONLY (t) = 1;
9386 TREE_NOTHROW (t) = 1;
9389 /* pure function, function can read global memory. */
9390 case RS6000_BTC_PURE:
9391 DECL_PURE_P (t) = 1;
9392 TREE_NOTHROW (t) = 1;
9395 /* Function is a math function. If rounding mode is on, then treat
9396 the function as not reading global memory, but it can have
9397 arbitrary side effects. If it is off, then assume the function is
9398 a const function. This mimics the ATTR_MATHFN_FPROUNDING
9399 attribute in builtin-attribute.def that is used for the math
9401 case RS6000_BTC_FP_PURE:
9402 TREE_NOTHROW (t) = 1;
9403 if (flag_rounding_math)
9405 DECL_PURE_P (t) = 1;
9406 DECL_IS_NOVOPS (t) = 1;
9409 TREE_READONLY (t) = 1;
9415 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
9417 static const struct builtin_description bdesc_3arg[] =
9419 { MASK_ALTIVEC, CODE_FOR_fmav4sf4, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
9420 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
9421 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
9422 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
9423 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
9424 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
9425 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
9426 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
9427 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
9428 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
9429 { MASK_ALTIVEC, CODE_FOR_nfmsv4sf4, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
9430 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
9431 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
9432 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
9433 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
9434 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
9435 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
9436 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
9437 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
9438 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
9439 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
9440 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
9441 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
9442 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
9443 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
9444 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
9445 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
9446 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
9447 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
9448 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
9449 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
9450 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
9451 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
9452 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
9453 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
9455 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
9456 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
9457 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
9458 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
9459 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
9460 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
9461 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
9462 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
9463 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
9464 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
9465 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
9466 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
9467 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
9468 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
9469 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
9471 { MASK_VSX, CODE_FOR_fmav2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
9472 { MASK_VSX, CODE_FOR_fmsv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
9473 { MASK_VSX, CODE_FOR_nfmav2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
9474 { MASK_VSX, CODE_FOR_nfmsv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
9476 { MASK_VSX, CODE_FOR_fmav4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
9477 { MASK_VSX, CODE_FOR_fmsv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
9478 { MASK_VSX, CODE_FOR_nfmav4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
9479 { MASK_VSX, CODE_FOR_nfmsv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
9481 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
9482 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
9484 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
9485 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
9486 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
9487 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
9488 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
9489 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
9490 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
9491 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
9492 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
9493 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
9495 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
9496 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
9497 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
9498 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
9499 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
9500 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
9501 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
9502 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
9503 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
9504 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
9506 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
9507 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
9508 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
9509 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
9510 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
9511 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
9512 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
9513 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
9514 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
9516 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
9517 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
9518 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
9519 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
9520 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
9521 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
9522 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
9524 { 0, CODE_FOR_fmsv2sf4, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
9525 { 0, CODE_FOR_fmav2sf4, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
9526 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
9527 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
9528 { 0, CODE_FOR_nfmsv2sf4, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
9529 { 0, CODE_FOR_nfmav2sf4, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
9530 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
9531 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
9532 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
9535 /* DST operations: void foo (void *, const int, const char). */
9537 static const struct builtin_description bdesc_dst[] =
9539 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
9540 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
9541 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
9542 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
9544 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
9545 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
9546 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
9547 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
9550 /* Simple binary operations: VECc = foo (VECa, VECb). */
9552 static struct builtin_description bdesc_2arg[] =
9554 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
9555 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
9556 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
9557 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
9558 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
9559 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
9560 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
9561 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
9562 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
9563 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
9564 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
9565 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
9566 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
9567 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
9568 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
9569 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
9570 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
9571 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
9572 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
9573 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
9574 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
9575 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
9576 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
9577 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
9578 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
9579 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
9580 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
9581 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
9582 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
9583 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
9584 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
9585 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
9586 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
9587 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
9588 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
9589 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
9590 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
9591 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
9592 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
9593 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
9594 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
9595 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
9596 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
9597 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
9598 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
9599 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
9600 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
9601 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
9602 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
9603 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
9604 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
9605 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
9606 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
9607 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
9608 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
9609 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
9610 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
9611 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
9612 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
9613 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
9614 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
9615 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
9616 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
9617 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
9618 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
9619 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
9620 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
9621 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
9622 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
9623 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
9624 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
9625 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
9626 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
9627 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
9628 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
9629 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
9630 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
9631 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
9632 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
9633 { MASK_ALTIVEC, CODE_FOR_recipv4sf3, "__builtin_altivec_vrecipdivfp", ALTIVEC_BUILTIN_VRECIPFP },
9634 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
9635 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
9636 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
9637 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
9638 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
9639 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
9640 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
9641 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
9642 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
9643 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
9644 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
9645 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
9646 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
9647 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
9648 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
9649 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
9650 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
9651 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
9652 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
9653 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
9654 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
9655 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
9656 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
9657 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
9658 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
9659 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
9660 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
9661 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
9662 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
9663 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
9664 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
9665 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
9666 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
9667 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
9668 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
9669 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
9670 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
9672 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
9673 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
9674 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
9675 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
9676 { MASK_VSX, CODE_FOR_recipv2df3, "__builtin_vsx_xvrecipdivdp", VSX_BUILTIN_RECIP_V2DF },
9677 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
9678 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
9679 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
9680 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
9681 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
9682 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
9683 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
9685 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
9686 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
9687 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
9688 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
9689 { MASK_VSX, CODE_FOR_recipv4sf3, "__builtin_vsx_xvrecipdivsp", VSX_BUILTIN_RECIP_V4SF },
9690 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
9691 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
9692 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
9693 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
9694 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
9695 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
9696 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
9698 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
9699 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
9700 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
9701 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
9702 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
9703 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
9705 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
9706 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
9707 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
9708 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
9709 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
9710 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
9711 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
9712 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
9713 { MASK_VSX, CODE_FOR_vec_interleave_lowv2df, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF },
9714 { MASK_VSX, CODE_FOR_vec_interleave_lowv2di, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI },
9715 { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF },
9716 { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI },
9718 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
9719 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
9720 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
9721 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
9722 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
9723 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
9724 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
9725 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
9726 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
9727 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
9728 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
9729 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
9730 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
9731 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
9732 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
9733 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
9734 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
9735 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
9736 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
9737 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
9738 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
9739 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
9740 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
9741 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
9742 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
9743 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
9744 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
9745 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
9746 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
9747 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
9748 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
9749 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
9750 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
9751 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
9752 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
9753 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
9754 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
9755 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
9756 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
9757 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
9758 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
9759 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
9760 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
9761 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
9762 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
9763 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
9764 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
9765 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
9766 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
9767 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
9768 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
9769 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
9770 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
9771 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
9772 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
9773 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
9774 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
9775 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
9776 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
9777 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
9778 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
9779 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
9780 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
9781 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
9782 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
9783 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
9784 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
9785 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
9786 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
9787 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
9788 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
9789 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
9790 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
9791 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
9792 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
9793 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
9794 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
9795 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
9796 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
9797 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
9798 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
9799 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
9800 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
9801 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
9802 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
9803 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
9804 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
9805 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
9806 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_recipdiv", ALTIVEC_BUILTIN_VEC_RECIP },
9807 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
9808 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
9809 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
9810 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
9811 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
9812 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
9813 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
9814 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
9815 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
9816 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
9817 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
9818 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
9819 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
9820 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
9821 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
9822 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
9823 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
9824 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
9825 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
9826 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
9827 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
9828 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
9829 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
9830 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
9831 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
9832 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
9833 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
9834 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
9835 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
9836 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
9837 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
9838 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
9839 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
9840 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
9841 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
9842 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
9843 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
9844 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
9845 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
9846 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
9848 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
9849 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
9851 { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
9852 { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
9853 { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
9854 { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
9855 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
9856 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
9857 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
9858 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
9859 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
9860 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
9862 /* Place holder, leave as first spe builtin. */
9863 { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
9864 { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
9865 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
9866 { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
9867 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
9868 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
9869 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
9870 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
9871 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
9872 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
9873 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
9874 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
9875 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
9876 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
9877 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
9878 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
9879 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
9880 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
9881 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
9882 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
9883 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
9884 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
9885 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
9886 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
9887 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
9888 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
9889 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
9890 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
9891 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
9892 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
9893 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
9894 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
9895 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
9896 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
9897 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
9898 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
9899 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
9900 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
9901 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
9902 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
9903 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
9904 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
9905 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
9906 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
9907 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
9908 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
9909 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
9910 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
9911 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
9912 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
9913 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
9914 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
9915 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
9916 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
9917 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
9918 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
9919 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
9920 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
9921 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
9922 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
9923 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
9924 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
9925 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
9926 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
9927 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
9928 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
9929 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
9930 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
9931 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
9932 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
9933 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
9934 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
9935 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
9936 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
9937 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
9938 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
9939 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
9940 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
9941 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
9942 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
9943 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
9944 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
9945 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
9946 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
9947 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
9948 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
9949 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
9950 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
9951 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
9952 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
9953 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
9954 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
9955 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
9956 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
9957 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
9958 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
9959 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
9960 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
9961 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
9962 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
9963 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
9964 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
9965 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
9966 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
9967 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
9968 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
9969 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
9970 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
9971 { 0, CODE_FOR_subv2si3, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
9973 /* SPE binary operations expecting a 5-bit unsigned literal. */
9974 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
9976 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
9977 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
9978 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
9979 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
9980 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
9981 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
9982 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
9983 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
9984 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
9985 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
9986 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
9987 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
9988 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
9989 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
9990 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
9991 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
9992 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
9993 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
9994 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
9995 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
9996 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
9997 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
9998 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
9999 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
10000 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
10001 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
10003 /* Place-holder. Leave as last binary SPE builtin. */
10004 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
10007 /* AltiVec predicates. */
10009 struct builtin_description_predicates
10011 const unsigned int mask;
10012 const enum insn_code icode;
10013 const char *const name;
10014 const enum rs6000_builtins code;
10017 static const struct builtin_description_predicates bdesc_altivec_preds[] =
10019 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
10020 ALTIVEC_BUILTIN_VCMPBFP_P },
10021 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
10022 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
10023 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
10024 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
10025 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
10026 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
10027 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
10028 ALTIVEC_BUILTIN_VCMPEQUW_P },
10029 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
10030 ALTIVEC_BUILTIN_VCMPGTSW_P },
10031 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
10032 ALTIVEC_BUILTIN_VCMPGTUW_P },
10033 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
10034 ALTIVEC_BUILTIN_VCMPEQUH_P },
10035 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
10036 ALTIVEC_BUILTIN_VCMPGTSH_P },
10037 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
10038 ALTIVEC_BUILTIN_VCMPGTUH_P },
10039 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
10040 ALTIVEC_BUILTIN_VCMPEQUB_P },
10041 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
10042 ALTIVEC_BUILTIN_VCMPGTSB_P },
10043 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
10044 ALTIVEC_BUILTIN_VCMPGTUB_P },
10046 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
10047 VSX_BUILTIN_XVCMPEQSP_P },
10048 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
10049 VSX_BUILTIN_XVCMPGESP_P },
10050 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
10051 VSX_BUILTIN_XVCMPGTSP_P },
10052 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
10053 VSX_BUILTIN_XVCMPEQDP_P },
10054 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
10055 VSX_BUILTIN_XVCMPGEDP_P },
10056 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
10057 VSX_BUILTIN_XVCMPGTDP_P },
10059 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
10060 ALTIVEC_BUILTIN_VCMPEQ_P },
10061 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
10062 ALTIVEC_BUILTIN_VCMPGT_P },
10063 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
10064 ALTIVEC_BUILTIN_VCMPGE_P }
10067 /* SPE predicates. */
10068 static struct builtin_description bdesc_spe_predicates[] =
10070 /* Place-holder. Leave as first. */
10071 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
10072 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
10073 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
10074 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
10075 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
10076 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
10077 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
10078 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
10079 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
10080 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
10081 /* Place-holder. Leave as last. */
10082 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
10085 /* SPE evsel predicates. */
10086 static struct builtin_description bdesc_spe_evsel[] =
10088 /* Place-holder. Leave as first. */
10089 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
10090 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
10091 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
10092 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
10093 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
10094 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
10095 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
10096 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
10097 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
10098 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
10099 /* Place-holder. Leave as last. */
10100 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
10103 /* PAIRED predicates. */
10104 static const struct builtin_description bdesc_paired_preds[] =
10106 /* Place-holder. Leave as first. */
10107 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
10108 /* Place-holder. Leave as last. */
10109 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
10112 /* ABS* operations. */
10114 static const struct builtin_description bdesc_abs[] =
10116 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
10117 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
10118 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
10119 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
10120 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
10121 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
10122 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
10123 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
10124 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
10125 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
10126 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
10129 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
10132 static struct builtin_description bdesc_1arg[] =
10134 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
10135 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
10136 { MASK_ALTIVEC, CODE_FOR_rev4sf2, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
10137 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
10138 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
10139 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
10140 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
10141 { MASK_ALTIVEC, CODE_FOR_rsqrtv4sf2, "__builtin_altivec_vrsqrtfp", ALTIVEC_BUILTIN_VRSQRTFP },
10142 { MASK_ALTIVEC, CODE_FOR_rsqrtev4sf2, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
10143 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
10144 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
10145 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
10146 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
10147 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
10148 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
10149 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
10150 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
10151 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
10153 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
10154 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
10155 { MASK_VSX, CODE_FOR_rsqrtv2df2, "__builtin_vsx_xvrsqrtdp", VSX_BUILTIN_VEC_RSQRT_V2DF },
10156 { MASK_VSX, CODE_FOR_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
10157 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
10158 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
10159 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
10161 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
10162 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
10163 { MASK_VSX, CODE_FOR_rsqrtv4sf2, "__builtin_vsx_xvrsqrtsp", VSX_BUILTIN_VEC_RSQRT_V4SF },
10164 { MASK_VSX, CODE_FOR_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
10165 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
10166 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
10167 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
10169 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
10170 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
10171 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
10172 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
10173 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
10174 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
10176 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
10177 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
10178 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
10179 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
10180 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
10181 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
10183 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
10184 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
10185 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
10186 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
10188 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
10189 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
10190 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
10191 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
10192 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
10193 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
10194 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
10195 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
10196 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
10198 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
10199 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
10200 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
10201 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
10202 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
10203 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
10204 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
10205 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
10206 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
10208 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
10209 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
10210 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
10211 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
10212 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
10214 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
10215 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
10216 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
10217 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
10218 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
10219 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
10220 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
10221 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
10222 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
10223 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrt", ALTIVEC_BUILTIN_VEC_RSQRT },
10224 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
10225 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
10226 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
10227 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
10228 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
10229 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
10230 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
10231 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
10232 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
10233 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
10235 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
10236 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
10237 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
10239 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
10240 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
10241 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
10242 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
10244 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
10245 end with SPE_BUILTIN_EVSUBFUSIAAW. */
10246 { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
10247 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
10248 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
10249 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
10250 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
10251 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
10252 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
10253 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
10254 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
10255 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
10256 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
10257 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
10258 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
10259 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
10260 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
10261 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
10262 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
10263 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
10264 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
10265 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
10266 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
10267 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
10268 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
10269 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
10270 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
10271 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
10272 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
10273 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
10275 /* Place-holder. Leave as last unary SPE builtin. */
10276 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
10278 { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
10279 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
10280 { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
10281 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
10282 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
10286 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
10289 tree arg0 = CALL_EXPR_ARG (exp, 0);
10290 rtx op0 = expand_normal (arg0);
10291 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10292 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10294 if (icode == CODE_FOR_nothing)
10295 /* Builtin not supported on this processor. */
10298 /* If we got invalid arguments bail out before generating bad rtl. */
10299 if (arg0 == error_mark_node)
10302 if (icode == CODE_FOR_altivec_vspltisb
10303 || icode == CODE_FOR_altivec_vspltish
10304 || icode == CODE_FOR_altivec_vspltisw
10305 || icode == CODE_FOR_spe_evsplatfi
10306 || icode == CODE_FOR_spe_evsplati)
10308 /* Only allow 5-bit *signed* literals. */
10309 if (GET_CODE (op0) != CONST_INT
10310 || INTVAL (op0) > 15
10311 || INTVAL (op0) < -16)
10313 error ("argument 1 must be a 5-bit signed literal");
10319 || GET_MODE (target) != tmode
10320 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10321 target = gen_reg_rtx (tmode);
10323 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10324 op0 = copy_to_mode_reg (mode0, op0);
10326 pat = GEN_FCN (icode) (target, op0);
10335 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
10337 rtx pat, scratch1, scratch2;
10338 tree arg0 = CALL_EXPR_ARG (exp, 0);
10339 rtx op0 = expand_normal (arg0);
10340 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10341 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10343 /* If we have invalid arguments, bail out before generating bad rtl. */
10344 if (arg0 == error_mark_node)
10348 || GET_MODE (target) != tmode
10349 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10350 target = gen_reg_rtx (tmode);
10352 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10353 op0 = copy_to_mode_reg (mode0, op0);
10355 scratch1 = gen_reg_rtx (mode0);
10356 scratch2 = gen_reg_rtx (mode0);
10358 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
10367 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
10370 tree arg0 = CALL_EXPR_ARG (exp, 0);
10371 tree arg1 = CALL_EXPR_ARG (exp, 1);
10372 rtx op0 = expand_normal (arg0);
10373 rtx op1 = expand_normal (arg1);
10374 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10375 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10376 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10378 if (icode == CODE_FOR_nothing)
10379 /* Builtin not supported on this processor. */
10382 /* If we got invalid arguments bail out before generating bad rtl. */
10383 if (arg0 == error_mark_node || arg1 == error_mark_node)
10386 if (icode == CODE_FOR_altivec_vcfux
10387 || icode == CODE_FOR_altivec_vcfsx
10388 || icode == CODE_FOR_altivec_vctsxs
10389 || icode == CODE_FOR_altivec_vctuxs
10390 || icode == CODE_FOR_altivec_vspltb
10391 || icode == CODE_FOR_altivec_vsplth
10392 || icode == CODE_FOR_altivec_vspltw
10393 || icode == CODE_FOR_spe_evaddiw
10394 || icode == CODE_FOR_spe_evldd
10395 || icode == CODE_FOR_spe_evldh
10396 || icode == CODE_FOR_spe_evldw
10397 || icode == CODE_FOR_spe_evlhhesplat
10398 || icode == CODE_FOR_spe_evlhhossplat
10399 || icode == CODE_FOR_spe_evlhhousplat
10400 || icode == CODE_FOR_spe_evlwhe
10401 || icode == CODE_FOR_spe_evlwhos
10402 || icode == CODE_FOR_spe_evlwhou
10403 || icode == CODE_FOR_spe_evlwhsplat
10404 || icode == CODE_FOR_spe_evlwwsplat
10405 || icode == CODE_FOR_spe_evrlwi
10406 || icode == CODE_FOR_spe_evslwi
10407 || icode == CODE_FOR_spe_evsrwis
10408 || icode == CODE_FOR_spe_evsubifw
10409 || icode == CODE_FOR_spe_evsrwiu)
10411 /* Only allow 5-bit unsigned literals. */
10413 if (TREE_CODE (arg1) != INTEGER_CST
10414 || TREE_INT_CST_LOW (arg1) & ~0x1f)
10416 error ("argument 2 must be a 5-bit unsigned literal");
10422 || GET_MODE (target) != tmode
10423 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10424 target = gen_reg_rtx (tmode);
10426 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10427 op0 = copy_to_mode_reg (mode0, op0);
10428 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10429 op1 = copy_to_mode_reg (mode1, op1);
10431 pat = GEN_FCN (icode) (target, op0, op1);
10440 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10443 tree cr6_form = CALL_EXPR_ARG (exp, 0);
10444 tree arg0 = CALL_EXPR_ARG (exp, 1);
10445 tree arg1 = CALL_EXPR_ARG (exp, 2);
10446 rtx op0 = expand_normal (arg0);
10447 rtx op1 = expand_normal (arg1);
10448 enum machine_mode tmode = SImode;
10449 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10450 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10453 if (TREE_CODE (cr6_form) != INTEGER_CST)
10455 error ("argument 1 of __builtin_altivec_predicate must be a constant");
10459 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
10461 gcc_assert (mode0 == mode1);
10463 /* If we have invalid arguments, bail out before generating bad rtl. */
10464 if (arg0 == error_mark_node || arg1 == error_mark_node)
10468 || GET_MODE (target) != tmode
10469 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10470 target = gen_reg_rtx (tmode);
10472 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10473 op0 = copy_to_mode_reg (mode0, op0);
10474 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10475 op1 = copy_to_mode_reg (mode1, op1);
10477 scratch = gen_reg_rtx (mode0);
10479 pat = GEN_FCN (icode) (scratch, op0, op1);
10484 /* The vec_any* and vec_all* predicates use the same opcodes for two
10485 different operations, but the bits in CR6 will be different
10486 depending on what information we want. So we have to play tricks
10487 with CR6 to get the right bits out.
10489 If you think this is disgusting, look at the specs for the
10490 AltiVec predicates. */
10492 switch (cr6_form_int)
10495 emit_insn (gen_cr6_test_for_zero (target));
10498 emit_insn (gen_cr6_test_for_zero_reverse (target));
10501 emit_insn (gen_cr6_test_for_lt (target));
10504 emit_insn (gen_cr6_test_for_lt_reverse (target));
10507 error ("argument 1 of __builtin_altivec_predicate is out of range");
10515 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
10518 tree arg0 = CALL_EXPR_ARG (exp, 0);
10519 tree arg1 = CALL_EXPR_ARG (exp, 1);
10520 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10521 enum machine_mode mode0 = Pmode;
10522 enum machine_mode mode1 = Pmode;
10523 rtx op0 = expand_normal (arg0);
10524 rtx op1 = expand_normal (arg1);
10526 if (icode == CODE_FOR_nothing)
10527 /* Builtin not supported on this processor. */
10530 /* If we got invalid arguments bail out before generating bad rtl. */
10531 if (arg0 == error_mark_node || arg1 == error_mark_node)
10535 || GET_MODE (target) != tmode
10536 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10537 target = gen_reg_rtx (tmode);
10539 op1 = copy_to_mode_reg (mode1, op1);
10541 if (op0 == const0_rtx)
10543 addr = gen_rtx_MEM (tmode, op1);
10547 op0 = copy_to_mode_reg (mode0, op0);
10548 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
10551 pat = GEN_FCN (icode) (target, addr);
10561 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
10564 tree arg0 = CALL_EXPR_ARG (exp, 0);
10565 tree arg1 = CALL_EXPR_ARG (exp, 1);
10566 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10567 enum machine_mode mode0 = Pmode;
10568 enum machine_mode mode1 = Pmode;
10569 rtx op0 = expand_normal (arg0);
10570 rtx op1 = expand_normal (arg1);
10572 if (icode == CODE_FOR_nothing)
10573 /* Builtin not supported on this processor. */
10576 /* If we got invalid arguments bail out before generating bad rtl. */
10577 if (arg0 == error_mark_node || arg1 == error_mark_node)
10581 || GET_MODE (target) != tmode
10582 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10583 target = gen_reg_rtx (tmode);
10585 op1 = copy_to_mode_reg (mode1, op1);
10587 if (op0 == const0_rtx)
10589 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
10593 op0 = copy_to_mode_reg (mode0, op0);
10594 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
10597 pat = GEN_FCN (icode) (target, addr);
10607 spe_expand_stv_builtin (enum insn_code icode, tree exp)
10609 tree arg0 = CALL_EXPR_ARG (exp, 0);
10610 tree arg1 = CALL_EXPR_ARG (exp, 1);
10611 tree arg2 = CALL_EXPR_ARG (exp, 2);
10612 rtx op0 = expand_normal (arg0);
10613 rtx op1 = expand_normal (arg1);
10614 rtx op2 = expand_normal (arg2);
10616 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
10617 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
10618 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
10620 /* Invalid arguments. Bail before doing anything stoopid! */
10621 if (arg0 == error_mark_node
10622 || arg1 == error_mark_node
10623 || arg2 == error_mark_node)
10626 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
10627 op0 = copy_to_mode_reg (mode2, op0);
10628 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
10629 op1 = copy_to_mode_reg (mode0, op1);
10630 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
10631 op2 = copy_to_mode_reg (mode1, op2);
10633 pat = GEN_FCN (icode) (op1, op2, op0);
10640 paired_expand_stv_builtin (enum insn_code icode, tree exp)
10642 tree arg0 = CALL_EXPR_ARG (exp, 0);
10643 tree arg1 = CALL_EXPR_ARG (exp, 1);
10644 tree arg2 = CALL_EXPR_ARG (exp, 2);
10645 rtx op0 = expand_normal (arg0);
10646 rtx op1 = expand_normal (arg1);
10647 rtx op2 = expand_normal (arg2);
10649 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10650 enum machine_mode mode1 = Pmode;
10651 enum machine_mode mode2 = Pmode;
10653 /* Invalid arguments. Bail before doing anything stoopid! */
10654 if (arg0 == error_mark_node
10655 || arg1 == error_mark_node
10656 || arg2 == error_mark_node)
10659 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
10660 op0 = copy_to_mode_reg (tmode, op0);
10662 op2 = copy_to_mode_reg (mode2, op2);
10664 if (op1 == const0_rtx)
10666 addr = gen_rtx_MEM (tmode, op2);
10670 op1 = copy_to_mode_reg (mode1, op1);
10671 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
10674 pat = GEN_FCN (icode) (addr, op0);
10681 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
10683 tree arg0 = CALL_EXPR_ARG (exp, 0);
10684 tree arg1 = CALL_EXPR_ARG (exp, 1);
10685 tree arg2 = CALL_EXPR_ARG (exp, 2);
10686 rtx op0 = expand_normal (arg0);
10687 rtx op1 = expand_normal (arg1);
10688 rtx op2 = expand_normal (arg2);
10690 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10691 enum machine_mode smode = insn_data[icode].operand[1].mode;
10692 enum machine_mode mode1 = Pmode;
10693 enum machine_mode mode2 = Pmode;
10695 /* Invalid arguments. Bail before doing anything stoopid! */
10696 if (arg0 == error_mark_node
10697 || arg1 == error_mark_node
10698 || arg2 == error_mark_node)
10701 if (! (*insn_data[icode].operand[1].predicate) (op0, smode))
10702 op0 = copy_to_mode_reg (smode, op0);
10704 op2 = copy_to_mode_reg (mode2, op2);
10706 if (op1 == const0_rtx)
10708 addr = gen_rtx_MEM (tmode, op2);
10712 op1 = copy_to_mode_reg (mode1, op1);
10713 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
10716 pat = GEN_FCN (icode) (addr, op0);
10723 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
10726 tree arg0 = CALL_EXPR_ARG (exp, 0);
10727 tree arg1 = CALL_EXPR_ARG (exp, 1);
10728 tree arg2 = CALL_EXPR_ARG (exp, 2);
10729 rtx op0 = expand_normal (arg0);
10730 rtx op1 = expand_normal (arg1);
10731 rtx op2 = expand_normal (arg2);
10732 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10733 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10734 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10735 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
10737 if (icode == CODE_FOR_nothing)
10738 /* Builtin not supported on this processor. */
10741 /* If we got invalid arguments bail out before generating bad rtl. */
10742 if (arg0 == error_mark_node
10743 || arg1 == error_mark_node
10744 || arg2 == error_mark_node)
10747 /* Check and prepare argument depending on the instruction code.
10749 Note that a switch statement instead of the sequence of tests
10750 would be incorrect as many of the CODE_FOR values could be
10751 CODE_FOR_nothing and that would yield multiple alternatives
10752 with identical values. We'd never reach here at runtime in
10754 if (icode == CODE_FOR_altivec_vsldoi_v4sf
10755 || icode == CODE_FOR_altivec_vsldoi_v4si
10756 || icode == CODE_FOR_altivec_vsldoi_v8hi
10757 || icode == CODE_FOR_altivec_vsldoi_v16qi)
10759 /* Only allow 4-bit unsigned literals. */
10761 if (TREE_CODE (arg2) != INTEGER_CST
10762 || TREE_INT_CST_LOW (arg2) & ~0xf)
10764 error ("argument 3 must be a 4-bit unsigned literal");
10768 else if (icode == CODE_FOR_vsx_xxpermdi_v2df
10769 || icode == CODE_FOR_vsx_xxpermdi_v2di
10770 || icode == CODE_FOR_vsx_xxsldwi_v16qi
10771 || icode == CODE_FOR_vsx_xxsldwi_v8hi
10772 || icode == CODE_FOR_vsx_xxsldwi_v4si
10773 || icode == CODE_FOR_vsx_xxsldwi_v4sf
10774 || icode == CODE_FOR_vsx_xxsldwi_v2di
10775 || icode == CODE_FOR_vsx_xxsldwi_v2df)
10777 /* Only allow 2-bit unsigned literals. */
10779 if (TREE_CODE (arg2) != INTEGER_CST
10780 || TREE_INT_CST_LOW (arg2) & ~0x3)
10782 error ("argument 3 must be a 2-bit unsigned literal");
10786 else if (icode == CODE_FOR_vsx_set_v2df
10787 || icode == CODE_FOR_vsx_set_v2di)
10789 /* Only allow 1-bit unsigned literals. */
10791 if (TREE_CODE (arg2) != INTEGER_CST
10792 || TREE_INT_CST_LOW (arg2) & ~0x1)
10794 error ("argument 3 must be a 1-bit unsigned literal");
10800 || GET_MODE (target) != tmode
10801 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10802 target = gen_reg_rtx (tmode);
10804 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10805 op0 = copy_to_mode_reg (mode0, op0);
10806 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10807 op1 = copy_to_mode_reg (mode1, op1);
10808 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
10809 op2 = copy_to_mode_reg (mode2, op2);
10811 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
10812 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
10814 pat = GEN_FCN (icode) (target, op0, op1, op2);
10822 /* Expand the lvx builtins. */
10824 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
10826 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10827 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10829 enum machine_mode tmode, mode0;
10831 enum insn_code icode;
10835 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
10836 icode = CODE_FOR_vector_altivec_load_v16qi;
10838 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
10839 icode = CODE_FOR_vector_altivec_load_v8hi;
10841 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
10842 icode = CODE_FOR_vector_altivec_load_v4si;
10844 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
10845 icode = CODE_FOR_vector_altivec_load_v4sf;
10847 case ALTIVEC_BUILTIN_LD_INTERNAL_2df:
10848 icode = CODE_FOR_vector_altivec_load_v2df;
10850 case ALTIVEC_BUILTIN_LD_INTERNAL_2di:
10851 icode = CODE_FOR_vector_altivec_load_v2di;
10854 *expandedp = false;
10860 arg0 = CALL_EXPR_ARG (exp, 0);
10861 op0 = expand_normal (arg0);
10862 tmode = insn_data[icode].operand[0].mode;
10863 mode0 = insn_data[icode].operand[1].mode;
10866 || GET_MODE (target) != tmode
10867 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10868 target = gen_reg_rtx (tmode);
10870 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10871 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10873 pat = GEN_FCN (icode) (target, op0);
10880 /* Expand the stvx builtins. */
10882 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10885 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10886 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10888 enum machine_mode mode0, mode1;
10890 enum insn_code icode;
10894 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
10895 icode = CODE_FOR_vector_altivec_store_v16qi;
10897 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
10898 icode = CODE_FOR_vector_altivec_store_v8hi;
10900 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
10901 icode = CODE_FOR_vector_altivec_store_v4si;
10903 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
10904 icode = CODE_FOR_vector_altivec_store_v4sf;
10906 case ALTIVEC_BUILTIN_ST_INTERNAL_2df:
10907 icode = CODE_FOR_vector_altivec_store_v2df;
10909 case ALTIVEC_BUILTIN_ST_INTERNAL_2di:
10910 icode = CODE_FOR_vector_altivec_store_v2di;
10913 *expandedp = false;
10917 arg0 = CALL_EXPR_ARG (exp, 0);
10918 arg1 = CALL_EXPR_ARG (exp, 1);
10919 op0 = expand_normal (arg0);
10920 op1 = expand_normal (arg1);
10921 mode0 = insn_data[icode].operand[0].mode;
10922 mode1 = insn_data[icode].operand[1].mode;
10924 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10925 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10926 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
10927 op1 = copy_to_mode_reg (mode1, op1);
10929 pat = GEN_FCN (icode) (op0, op1);
10937 /* Expand the dst builtins. */
10939 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10942 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10943 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10944 tree arg0, arg1, arg2;
10945 enum machine_mode mode0, mode1;
10946 rtx pat, op0, op1, op2;
10947 const struct builtin_description *d;
10950 *expandedp = false;
10952 /* Handle DST variants. */
10954 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
10955 if (d->code == fcode)
10957 arg0 = CALL_EXPR_ARG (exp, 0);
10958 arg1 = CALL_EXPR_ARG (exp, 1);
10959 arg2 = CALL_EXPR_ARG (exp, 2);
10960 op0 = expand_normal (arg0);
10961 op1 = expand_normal (arg1);
10962 op2 = expand_normal (arg2);
10963 mode0 = insn_data[d->icode].operand[0].mode;
10964 mode1 = insn_data[d->icode].operand[1].mode;
10966 /* Invalid arguments, bail out before generating bad rtl. */
10967 if (arg0 == error_mark_node
10968 || arg1 == error_mark_node
10969 || arg2 == error_mark_node)
10974 if (TREE_CODE (arg2) != INTEGER_CST
10975 || TREE_INT_CST_LOW (arg2) & ~0x3)
10977 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
10981 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
10982 op0 = copy_to_mode_reg (Pmode, op0);
10983 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
10984 op1 = copy_to_mode_reg (mode1, op1);
10986 pat = GEN_FCN (d->icode) (op0, op1, op2);
10996 /* Expand vec_init builtin. */
10998 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
11000 enum machine_mode tmode = TYPE_MODE (type);
11001 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
11002 int i, n_elt = GET_MODE_NUNITS (tmode);
11003 rtvec v = rtvec_alloc (n_elt);
11005 gcc_assert (VECTOR_MODE_P (tmode));
11006 gcc_assert (n_elt == call_expr_nargs (exp));
11008 for (i = 0; i < n_elt; ++i)
11010 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
11011 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
11014 if (!target || !register_operand (target, tmode))
11015 target = gen_reg_rtx (tmode);
11017 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
11021 /* Return the integer constant in ARG. Constrain it to be in the range
11022 of the subparts of VEC_TYPE; issue an error if not. */
11025 get_element_number (tree vec_type, tree arg)
11027 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
11029 if (!host_integerp (arg, 1)
11030 || (elt = tree_low_cst (arg, 1), elt > max))
11032 error ("selector must be an integer constant in the range 0..%wi", max);
11039 /* Expand vec_set builtin. */
11041 altivec_expand_vec_set_builtin (tree exp)
11043 enum machine_mode tmode, mode1;
11044 tree arg0, arg1, arg2;
11048 arg0 = CALL_EXPR_ARG (exp, 0);
11049 arg1 = CALL_EXPR_ARG (exp, 1);
11050 arg2 = CALL_EXPR_ARG (exp, 2);
11052 tmode = TYPE_MODE (TREE_TYPE (arg0));
11053 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11054 gcc_assert (VECTOR_MODE_P (tmode));
11056 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
11057 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
11058 elt = get_element_number (TREE_TYPE (arg0), arg2);
11060 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
11061 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
11063 op0 = force_reg (tmode, op0);
11064 op1 = force_reg (mode1, op1);
11066 rs6000_expand_vector_set (op0, op1, elt);
11071 /* Expand vec_ext builtin. */
11073 altivec_expand_vec_ext_builtin (tree exp, rtx target)
11075 enum machine_mode tmode, mode0;
11080 arg0 = CALL_EXPR_ARG (exp, 0);
11081 arg1 = CALL_EXPR_ARG (exp, 1);
11083 op0 = expand_normal (arg0);
11084 elt = get_element_number (TREE_TYPE (arg0), arg1);
11086 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11087 mode0 = TYPE_MODE (TREE_TYPE (arg0));
11088 gcc_assert (VECTOR_MODE_P (mode0));
11090 op0 = force_reg (mode0, op0);
11092 if (optimize || !target || !register_operand (target, tmode))
11093 target = gen_reg_rtx (tmode);
11095 rs6000_expand_vector_extract (target, op0, elt);
11100 /* Expand the builtin in EXP and store the result in TARGET. Store
11101 true in *EXPANDEDP if we found a builtin to expand. */
11103 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
11105 const struct builtin_description *d;
11106 const struct builtin_description_predicates *dp;
11108 enum insn_code icode;
11109 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11112 enum machine_mode tmode, mode0;
11113 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11115 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11116 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11117 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
11118 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
11121 error ("unresolved overload for Altivec builtin %qF", fndecl);
11125 target = altivec_expand_ld_builtin (exp, target, expandedp);
11129 target = altivec_expand_st_builtin (exp, target, expandedp);
11133 target = altivec_expand_dst_builtin (exp, target, expandedp);
11141 case ALTIVEC_BUILTIN_STVX:
11142 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v4si, exp);
11143 case ALTIVEC_BUILTIN_STVEBX:
11144 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
11145 case ALTIVEC_BUILTIN_STVEHX:
11146 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
11147 case ALTIVEC_BUILTIN_STVEWX:
11148 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
11149 case ALTIVEC_BUILTIN_STVXL:
11150 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
11152 case ALTIVEC_BUILTIN_STVLX:
11153 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
11154 case ALTIVEC_BUILTIN_STVLXL:
11155 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
11156 case ALTIVEC_BUILTIN_STVRX:
11157 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
11158 case ALTIVEC_BUILTIN_STVRXL:
11159 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
11161 case VSX_BUILTIN_STXVD2X_V2DF:
11162 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2df, exp);
11163 case VSX_BUILTIN_STXVD2X_V2DI:
11164 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2di, exp);
11165 case VSX_BUILTIN_STXVW4X_V4SF:
11166 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4sf, exp);
11167 case VSX_BUILTIN_STXVW4X_V4SI:
11168 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4si, exp);
11169 case VSX_BUILTIN_STXVW4X_V8HI:
11170 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v8hi, exp);
11171 case VSX_BUILTIN_STXVW4X_V16QI:
11172 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v16qi, exp);
11174 case ALTIVEC_BUILTIN_MFVSCR:
11175 icode = CODE_FOR_altivec_mfvscr;
11176 tmode = insn_data[icode].operand[0].mode;
11179 || GET_MODE (target) != tmode
11180 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11181 target = gen_reg_rtx (tmode);
11183 pat = GEN_FCN (icode) (target);
11189 case ALTIVEC_BUILTIN_MTVSCR:
11190 icode = CODE_FOR_altivec_mtvscr;
11191 arg0 = CALL_EXPR_ARG (exp, 0);
11192 op0 = expand_normal (arg0);
11193 mode0 = insn_data[icode].operand[0].mode;
11195 /* If we got invalid arguments bail out before generating bad rtl. */
11196 if (arg0 == error_mark_node)
11199 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11200 op0 = copy_to_mode_reg (mode0, op0);
11202 pat = GEN_FCN (icode) (op0);
11207 case ALTIVEC_BUILTIN_DSSALL:
11208 emit_insn (gen_altivec_dssall ());
11211 case ALTIVEC_BUILTIN_DSS:
11212 icode = CODE_FOR_altivec_dss;
11213 arg0 = CALL_EXPR_ARG (exp, 0);
11215 op0 = expand_normal (arg0);
11216 mode0 = insn_data[icode].operand[0].mode;
11218 /* If we got invalid arguments bail out before generating bad rtl. */
11219 if (arg0 == error_mark_node)
11222 if (TREE_CODE (arg0) != INTEGER_CST
11223 || TREE_INT_CST_LOW (arg0) & ~0x3)
11225 error ("argument to dss must be a 2-bit unsigned literal");
11229 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11230 op0 = copy_to_mode_reg (mode0, op0);
11232 emit_insn (gen_altivec_dss (op0));
11235 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
11236 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
11237 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
11238 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
11239 case VSX_BUILTIN_VEC_INIT_V2DF:
11240 case VSX_BUILTIN_VEC_INIT_V2DI:
11241 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
11243 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
11244 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
11245 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
11246 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
11247 case VSX_BUILTIN_VEC_SET_V2DF:
11248 case VSX_BUILTIN_VEC_SET_V2DI:
11249 return altivec_expand_vec_set_builtin (exp);
11251 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
11252 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
11253 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
11254 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
11255 case VSX_BUILTIN_VEC_EXT_V2DF:
11256 case VSX_BUILTIN_VEC_EXT_V2DI:
11257 return altivec_expand_vec_ext_builtin (exp, target);
11261 /* Fall through. */
11264 /* Expand abs* operations. */
11266 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11267 if (d->code == fcode)
11268 return altivec_expand_abs_builtin (d->icode, exp, target);
11270 /* Expand the AltiVec predicates. */
11271 dp = bdesc_altivec_preds;
11272 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11273 if (dp->code == fcode)
11274 return altivec_expand_predicate_builtin (dp->icode, exp, target);
11276 /* LV* are funky. We initialized them differently. */
11279 case ALTIVEC_BUILTIN_LVSL:
11280 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
11281 exp, target, false);
11282 case ALTIVEC_BUILTIN_LVSR:
11283 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
11284 exp, target, false);
11285 case ALTIVEC_BUILTIN_LVEBX:
11286 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
11287 exp, target, false);
11288 case ALTIVEC_BUILTIN_LVEHX:
11289 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
11290 exp, target, false);
11291 case ALTIVEC_BUILTIN_LVEWX:
11292 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
11293 exp, target, false);
11294 case ALTIVEC_BUILTIN_LVXL:
11295 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
11296 exp, target, false);
11297 case ALTIVEC_BUILTIN_LVX:
11298 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v4si,
11299 exp, target, false);
11300 case ALTIVEC_BUILTIN_LVLX:
11301 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
11302 exp, target, true);
11303 case ALTIVEC_BUILTIN_LVLXL:
11304 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
11305 exp, target, true);
11306 case ALTIVEC_BUILTIN_LVRX:
11307 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
11308 exp, target, true);
11309 case ALTIVEC_BUILTIN_LVRXL:
11310 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
11311 exp, target, true);
11312 case VSX_BUILTIN_LXVD2X_V2DF:
11313 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2df,
11314 exp, target, false);
11315 case VSX_BUILTIN_LXVD2X_V2DI:
11316 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2di,
11317 exp, target, false);
11318 case VSX_BUILTIN_LXVW4X_V4SF:
11319 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4sf,
11320 exp, target, false);
11321 case VSX_BUILTIN_LXVW4X_V4SI:
11322 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4si,
11323 exp, target, false);
11324 case VSX_BUILTIN_LXVW4X_V8HI:
11325 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v8hi,
11326 exp, target, false);
11327 case VSX_BUILTIN_LXVW4X_V16QI:
11328 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v16qi,
11329 exp, target, false);
11333 /* Fall through. */
11336 *expandedp = false;
11340 /* Expand the builtin in EXP and store the result in TARGET. Store
11341 true in *EXPANDEDP if we found a builtin to expand. */
11343 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
11345 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11346 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11347 const struct builtin_description *d;
11354 case PAIRED_BUILTIN_STX:
11355 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
11356 case PAIRED_BUILTIN_LX:
11357 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
11360 /* Fall through. */
11363 /* Expand the paired predicates. */
11364 d = bdesc_paired_preds;
11365 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
11366 if (d->code == fcode)
11367 return paired_expand_predicate_builtin (d->icode, exp, target);
11369 *expandedp = false;
11373 /* Binops that need to be initialized manually, but can be expanded
11374 automagically by rs6000_expand_binop_builtin. */
11375 static struct builtin_description bdesc_2arg_spe[] =
11377 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
11378 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
11379 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
11380 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
11381 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
11382 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
11383 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
11384 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
11385 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
11386 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
11387 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
11388 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
11389 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
11390 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
11391 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
11392 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
11393 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
11394 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
11395 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
11396 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
11397 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
11398 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
11401 /* Expand the builtin in EXP and store the result in TARGET. Store
11402 true in *EXPANDEDP if we found a builtin to expand.
11404 This expands the SPE builtins that are not simple unary and binary
11407 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
11409 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11411 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11412 enum insn_code icode;
11413 enum machine_mode tmode, mode0;
11415 struct builtin_description *d;
11420 /* Syntax check for a 5-bit unsigned immediate. */
11423 case SPE_BUILTIN_EVSTDD:
11424 case SPE_BUILTIN_EVSTDH:
11425 case SPE_BUILTIN_EVSTDW:
11426 case SPE_BUILTIN_EVSTWHE:
11427 case SPE_BUILTIN_EVSTWHO:
11428 case SPE_BUILTIN_EVSTWWE:
11429 case SPE_BUILTIN_EVSTWWO:
11430 arg1 = CALL_EXPR_ARG (exp, 2);
11431 if (TREE_CODE (arg1) != INTEGER_CST
11432 || TREE_INT_CST_LOW (arg1) & ~0x1f)
11434 error ("argument 2 must be a 5-bit unsigned literal");
11442 /* The evsplat*i instructions are not quite generic. */
11445 case SPE_BUILTIN_EVSPLATFI:
11446 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
11448 case SPE_BUILTIN_EVSPLATI:
11449 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
11455 d = (struct builtin_description *) bdesc_2arg_spe;
11456 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
11457 if (d->code == fcode)
11458 return rs6000_expand_binop_builtin (d->icode, exp, target);
11460 d = (struct builtin_description *) bdesc_spe_predicates;
11461 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
11462 if (d->code == fcode)
11463 return spe_expand_predicate_builtin (d->icode, exp, target);
11465 d = (struct builtin_description *) bdesc_spe_evsel;
11466 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
11467 if (d->code == fcode)
11468 return spe_expand_evsel_builtin (d->icode, exp, target);
11472 case SPE_BUILTIN_EVSTDDX:
11473 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
11474 case SPE_BUILTIN_EVSTDHX:
11475 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
11476 case SPE_BUILTIN_EVSTDWX:
11477 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
11478 case SPE_BUILTIN_EVSTWHEX:
11479 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
11480 case SPE_BUILTIN_EVSTWHOX:
11481 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
11482 case SPE_BUILTIN_EVSTWWEX:
11483 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
11484 case SPE_BUILTIN_EVSTWWOX:
11485 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
11486 case SPE_BUILTIN_EVSTDD:
11487 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
11488 case SPE_BUILTIN_EVSTDH:
11489 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
11490 case SPE_BUILTIN_EVSTDW:
11491 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
11492 case SPE_BUILTIN_EVSTWHE:
11493 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
11494 case SPE_BUILTIN_EVSTWHO:
11495 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
11496 case SPE_BUILTIN_EVSTWWE:
11497 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
11498 case SPE_BUILTIN_EVSTWWO:
11499 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
11500 case SPE_BUILTIN_MFSPEFSCR:
11501 icode = CODE_FOR_spe_mfspefscr;
11502 tmode = insn_data[icode].operand[0].mode;
11505 || GET_MODE (target) != tmode
11506 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11507 target = gen_reg_rtx (tmode);
11509 pat = GEN_FCN (icode) (target);
11514 case SPE_BUILTIN_MTSPEFSCR:
11515 icode = CODE_FOR_spe_mtspefscr;
11516 arg0 = CALL_EXPR_ARG (exp, 0);
11517 op0 = expand_normal (arg0);
11518 mode0 = insn_data[icode].operand[0].mode;
11520 if (arg0 == error_mark_node)
11523 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11524 op0 = copy_to_mode_reg (mode0, op0);
11526 pat = GEN_FCN (icode) (op0);
11534 *expandedp = false;
11539 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11541 rtx pat, scratch, tmp;
11542 tree form = CALL_EXPR_ARG (exp, 0);
11543 tree arg0 = CALL_EXPR_ARG (exp, 1);
11544 tree arg1 = CALL_EXPR_ARG (exp, 2);
11545 rtx op0 = expand_normal (arg0);
11546 rtx op1 = expand_normal (arg1);
11547 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11548 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11550 enum rtx_code code;
11552 if (TREE_CODE (form) != INTEGER_CST)
11554 error ("argument 1 of __builtin_paired_predicate must be a constant");
11558 form_int = TREE_INT_CST_LOW (form);
11560 gcc_assert (mode0 == mode1);
11562 if (arg0 == error_mark_node || arg1 == error_mark_node)
11566 || GET_MODE (target) != SImode
11567 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
11568 target = gen_reg_rtx (SImode);
11569 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
11570 op0 = copy_to_mode_reg (mode0, op0);
11571 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
11572 op1 = copy_to_mode_reg (mode1, op1);
11574 scratch = gen_reg_rtx (CCFPmode);
11576 pat = GEN_FCN (icode) (scratch, op0, op1);
11598 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11601 error ("argument 1 of __builtin_paired_predicate is out of range");
11605 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11606 emit_move_insn (target, tmp);
11611 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11613 rtx pat, scratch, tmp;
11614 tree form = CALL_EXPR_ARG (exp, 0);
11615 tree arg0 = CALL_EXPR_ARG (exp, 1);
11616 tree arg1 = CALL_EXPR_ARG (exp, 2);
11617 rtx op0 = expand_normal (arg0);
11618 rtx op1 = expand_normal (arg1);
11619 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11620 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11622 enum rtx_code code;
11624 if (TREE_CODE (form) != INTEGER_CST)
11626 error ("argument 1 of __builtin_spe_predicate must be a constant");
11630 form_int = TREE_INT_CST_LOW (form);
11632 gcc_assert (mode0 == mode1);
11634 if (arg0 == error_mark_node || arg1 == error_mark_node)
11638 || GET_MODE (target) != SImode
11639 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
11640 target = gen_reg_rtx (SImode);
11642 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11643 op0 = copy_to_mode_reg (mode0, op0);
11644 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11645 op1 = copy_to_mode_reg (mode1, op1);
11647 scratch = gen_reg_rtx (CCmode);
11649 pat = GEN_FCN (icode) (scratch, op0, op1);
11654 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
11655 _lower_. We use one compare, but look in different bits of the
11656 CR for each variant.
11658 There are 2 elements in each SPE simd type (upper/lower). The CR
11659 bits are set as follows:
11661 BIT0 | BIT 1 | BIT 2 | BIT 3
11662 U | L | (U | L) | (U & L)
11664 So, for an "all" relationship, BIT 3 would be set.
11665 For an "any" relationship, BIT 2 would be set. Etc.
11667 Following traditional nomenclature, these bits map to:
11669 BIT0 | BIT 1 | BIT 2 | BIT 3
11672 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
11677 /* All variant. OV bit. */
11679 /* We need to get to the OV bit, which is the ORDERED bit. We
11680 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
11681 that's ugly and will make validate_condition_mode die.
11682 So let's just use another pattern. */
11683 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11685 /* Any variant. EQ bit. */
11689 /* Upper variant. LT bit. */
11693 /* Lower variant. GT bit. */
11698 error ("argument 1 of __builtin_spe_predicate is out of range");
11702 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11703 emit_move_insn (target, tmp);
11708 /* The evsel builtins look like this:
11710 e = __builtin_spe_evsel_OP (a, b, c, d);
11712 and work like this:
11714 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
11715 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
11719 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
11722 tree arg0 = CALL_EXPR_ARG (exp, 0);
11723 tree arg1 = CALL_EXPR_ARG (exp, 1);
11724 tree arg2 = CALL_EXPR_ARG (exp, 2);
11725 tree arg3 = CALL_EXPR_ARG (exp, 3);
11726 rtx op0 = expand_normal (arg0);
11727 rtx op1 = expand_normal (arg1);
11728 rtx op2 = expand_normal (arg2);
11729 rtx op3 = expand_normal (arg3);
11730 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11731 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11733 gcc_assert (mode0 == mode1);
11735 if (arg0 == error_mark_node || arg1 == error_mark_node
11736 || arg2 == error_mark_node || arg3 == error_mark_node)
11740 || GET_MODE (target) != mode0
11741 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
11742 target = gen_reg_rtx (mode0);
11744 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11745 op0 = copy_to_mode_reg (mode0, op0);
11746 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11747 op1 = copy_to_mode_reg (mode0, op1);
11748 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
11749 op2 = copy_to_mode_reg (mode0, op2);
11750 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
11751 op3 = copy_to_mode_reg (mode0, op3);
11753 /* Generate the compare. */
11754 scratch = gen_reg_rtx (CCmode);
11755 pat = GEN_FCN (icode) (scratch, op0, op1);
11760 if (mode0 == V2SImode)
11761 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
11763 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
11768 /* Expand an expression EXP that calls a built-in function,
11769 with result going to TARGET if that's convenient
11770 (and in mode MODE if that's convenient).
11771 SUBTARGET may be used as the target for computing one of EXP's operands.
11772 IGNORE is nonzero if the value is to be ignored. */
11775 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
11776 enum machine_mode mode ATTRIBUTE_UNUSED,
11777 int ignore ATTRIBUTE_UNUSED)
11779 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11780 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11781 const struct builtin_description *d;
11788 case RS6000_BUILTIN_RECIP:
11789 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
11791 case RS6000_BUILTIN_RECIPF:
11792 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
11794 case RS6000_BUILTIN_RSQRTF:
11795 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
11797 case RS6000_BUILTIN_RSQRT:
11798 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2, exp, target);
11800 case RS6000_BUILTIN_BSWAP_HI:
11801 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
11803 case POWER7_BUILTIN_BPERMD:
11804 return rs6000_expand_binop_builtin (((TARGET_64BIT)
11805 ? CODE_FOR_bpermd_di
11806 : CODE_FOR_bpermd_si), exp, target);
11808 case ALTIVEC_BUILTIN_MASK_FOR_LOAD:
11809 case ALTIVEC_BUILTIN_MASK_FOR_STORE:
11811 int icode = (int) CODE_FOR_altivec_lvsr;
11812 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11813 enum machine_mode mode = insn_data[icode].operand[1].mode;
11817 gcc_assert (TARGET_ALTIVEC);
11819 arg = CALL_EXPR_ARG (exp, 0);
11820 gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg)));
11821 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
11822 addr = memory_address (mode, op);
11823 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
11827 /* For the load case need to negate the address. */
11828 op = gen_reg_rtx (GET_MODE (addr));
11829 emit_insn (gen_rtx_SET (VOIDmode, op,
11830 gen_rtx_NEG (GET_MODE (addr), addr)));
11832 op = gen_rtx_MEM (mode, op);
11835 || GET_MODE (target) != tmode
11836 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11837 target = gen_reg_rtx (tmode);
11839 /*pat = gen_altivec_lvsr (target, op);*/
11840 pat = GEN_FCN (icode) (target, op);
11848 case ALTIVEC_BUILTIN_VCFUX:
11849 case ALTIVEC_BUILTIN_VCFSX:
11850 case ALTIVEC_BUILTIN_VCTUXS:
11851 case ALTIVEC_BUILTIN_VCTSXS:
11852 /* FIXME: There's got to be a nicer way to handle this case than
11853 constructing a new CALL_EXPR. */
11854 if (call_expr_nargs (exp) == 1)
11856 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
11857 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
11865 if (TARGET_ALTIVEC)
11867 ret = altivec_expand_builtin (exp, target, &success);
11874 ret = spe_expand_builtin (exp, target, &success);
11879 if (TARGET_PAIRED_FLOAT)
11881 ret = paired_expand_builtin (exp, target, &success);
11887 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
11889 /* Handle simple unary operations. */
11890 d = (struct builtin_description *) bdesc_1arg;
11891 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
11892 if (d->code == fcode)
11893 return rs6000_expand_unop_builtin (d->icode, exp, target);
11895 /* Handle simple binary operations. */
11896 d = (struct builtin_description *) bdesc_2arg;
11897 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
11898 if (d->code == fcode)
11899 return rs6000_expand_binop_builtin (d->icode, exp, target);
11901 /* Handle simple ternary operations. */
11903 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
11904 if (d->code == fcode)
11905 return rs6000_expand_ternop_builtin (d->icode, exp, target);
11907 gcc_unreachable ();
11911 rs6000_init_builtins (void)
11916 V2SI_type_node = build_vector_type (intSI_type_node, 2);
11917 V2SF_type_node = build_vector_type (float_type_node, 2);
11918 V2DI_type_node = build_vector_type (intDI_type_node, 2);
11919 V2DF_type_node = build_vector_type (double_type_node, 2);
11920 V4HI_type_node = build_vector_type (intHI_type_node, 4);
11921 V4SI_type_node = build_vector_type (intSI_type_node, 4);
11922 V4SF_type_node = build_vector_type (float_type_node, 4);
11923 V8HI_type_node = build_vector_type (intHI_type_node, 8);
11924 V16QI_type_node = build_vector_type (intQI_type_node, 16);
11926 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
11927 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
11928 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
11929 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
11931 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
11932 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
11933 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
11934 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
11936 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
11937 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
11938 'vector unsigned short'. */
11940 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
11941 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
11942 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
11943 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
11944 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
11946 long_integer_type_internal_node = long_integer_type_node;
11947 long_unsigned_type_internal_node = long_unsigned_type_node;
11948 long_long_integer_type_internal_node = long_long_integer_type_node;
11949 long_long_unsigned_type_internal_node = long_long_unsigned_type_node;
11950 intQI_type_internal_node = intQI_type_node;
11951 uintQI_type_internal_node = unsigned_intQI_type_node;
11952 intHI_type_internal_node = intHI_type_node;
11953 uintHI_type_internal_node = unsigned_intHI_type_node;
11954 intSI_type_internal_node = intSI_type_node;
11955 uintSI_type_internal_node = unsigned_intSI_type_node;
11956 intDI_type_internal_node = intDI_type_node;
11957 uintDI_type_internal_node = unsigned_intDI_type_node;
11958 float_type_internal_node = float_type_node;
11959 double_type_internal_node = double_type_node;
11960 void_type_internal_node = void_type_node;
11962 /* Initialize the modes for builtin_function_type, mapping a machine mode to
11964 builtin_mode_to_type[QImode][0] = integer_type_node;
11965 builtin_mode_to_type[HImode][0] = integer_type_node;
11966 builtin_mode_to_type[SImode][0] = intSI_type_node;
11967 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
11968 builtin_mode_to_type[DImode][0] = intDI_type_node;
11969 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
11970 builtin_mode_to_type[SFmode][0] = float_type_node;
11971 builtin_mode_to_type[DFmode][0] = double_type_node;
11972 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
11973 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
11974 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
11975 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
11976 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
11977 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
11978 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
11979 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
11980 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
11981 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
11982 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
11983 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
11984 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
11986 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11987 get_identifier ("__bool char"),
11988 bool_char_type_node);
11989 TYPE_NAME (bool_char_type_node) = tdecl;
11990 (*lang_hooks.decls.pushdecl) (tdecl);
11991 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11992 get_identifier ("__bool short"),
11993 bool_short_type_node);
11994 TYPE_NAME (bool_short_type_node) = tdecl;
11995 (*lang_hooks.decls.pushdecl) (tdecl);
11996 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11997 get_identifier ("__bool int"),
11998 bool_int_type_node);
11999 TYPE_NAME (bool_int_type_node) = tdecl;
12000 (*lang_hooks.decls.pushdecl) (tdecl);
12001 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
12003 TYPE_NAME (pixel_type_node) = tdecl;
12004 (*lang_hooks.decls.pushdecl) (tdecl);
12006 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
12007 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
12008 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
12009 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
12010 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
12012 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12013 get_identifier ("__vector unsigned char"),
12014 unsigned_V16QI_type_node);
12015 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
12016 (*lang_hooks.decls.pushdecl) (tdecl);
12017 tdecl = build_decl (BUILTINS_LOCATION,
12018 TYPE_DECL, get_identifier ("__vector signed char"),
12020 TYPE_NAME (V16QI_type_node) = tdecl;
12021 (*lang_hooks.decls.pushdecl) (tdecl);
12022 tdecl = build_decl (BUILTINS_LOCATION,
12023 TYPE_DECL, get_identifier ("__vector __bool char"),
12024 bool_V16QI_type_node);
12025 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
12026 (*lang_hooks.decls.pushdecl) (tdecl);
12028 tdecl = build_decl (BUILTINS_LOCATION,
12029 TYPE_DECL, get_identifier ("__vector unsigned short"),
12030 unsigned_V8HI_type_node);
12031 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
12032 (*lang_hooks.decls.pushdecl) (tdecl);
12033 tdecl = build_decl (BUILTINS_LOCATION,
12034 TYPE_DECL, get_identifier ("__vector signed short"),
12036 TYPE_NAME (V8HI_type_node) = tdecl;
12037 (*lang_hooks.decls.pushdecl) (tdecl);
12038 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12039 get_identifier ("__vector __bool short"),
12040 bool_V8HI_type_node);
12041 TYPE_NAME (bool_V8HI_type_node) = tdecl;
12042 (*lang_hooks.decls.pushdecl) (tdecl);
12044 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12045 get_identifier ("__vector unsigned int"),
12046 unsigned_V4SI_type_node);
12047 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
12048 (*lang_hooks.decls.pushdecl) (tdecl);
12049 tdecl = build_decl (BUILTINS_LOCATION,
12050 TYPE_DECL, get_identifier ("__vector signed int"),
12052 TYPE_NAME (V4SI_type_node) = tdecl;
12053 (*lang_hooks.decls.pushdecl) (tdecl);
12054 tdecl = build_decl (BUILTINS_LOCATION,
12055 TYPE_DECL, get_identifier ("__vector __bool int"),
12056 bool_V4SI_type_node);
12057 TYPE_NAME (bool_V4SI_type_node) = tdecl;
12058 (*lang_hooks.decls.pushdecl) (tdecl);
12060 tdecl = build_decl (BUILTINS_LOCATION,
12061 TYPE_DECL, get_identifier ("__vector float"),
12063 TYPE_NAME (V4SF_type_node) = tdecl;
12064 (*lang_hooks.decls.pushdecl) (tdecl);
12065 tdecl = build_decl (BUILTINS_LOCATION,
12066 TYPE_DECL, get_identifier ("__vector __pixel"),
12067 pixel_V8HI_type_node);
12068 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
12069 (*lang_hooks.decls.pushdecl) (tdecl);
12073 tdecl = build_decl (BUILTINS_LOCATION,
12074 TYPE_DECL, get_identifier ("__vector double"),
12076 TYPE_NAME (V2DF_type_node) = tdecl;
12077 (*lang_hooks.decls.pushdecl) (tdecl);
12079 tdecl = build_decl (BUILTINS_LOCATION,
12080 TYPE_DECL, get_identifier ("__vector long"),
12082 TYPE_NAME (V2DI_type_node) = tdecl;
12083 (*lang_hooks.decls.pushdecl) (tdecl);
12085 tdecl = build_decl (BUILTINS_LOCATION,
12086 TYPE_DECL, get_identifier ("__vector unsigned long"),
12087 unsigned_V2DI_type_node);
12088 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
12089 (*lang_hooks.decls.pushdecl) (tdecl);
12091 tdecl = build_decl (BUILTINS_LOCATION,
12092 TYPE_DECL, get_identifier ("__vector __bool long"),
12093 bool_V2DI_type_node);
12094 TYPE_NAME (bool_V2DI_type_node) = tdecl;
12095 (*lang_hooks.decls.pushdecl) (tdecl);
12098 if (TARGET_PAIRED_FLOAT)
12099 paired_init_builtins ();
12101 spe_init_builtins ();
12102 if (TARGET_ALTIVEC)
12103 altivec_init_builtins ();
12104 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
12105 rs6000_common_init_builtins ();
12108 ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
12109 RS6000_BUILTIN_RECIP,
12110 "__builtin_recipdiv");
12111 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
12112 RS6000_BUILTIN_RECIP);
12116 ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
12117 RS6000_BUILTIN_RECIPF,
12118 "__builtin_recipdivf");
12119 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
12120 RS6000_BUILTIN_RECIPF);
12122 if (TARGET_FRSQRTE)
12124 ftype = builtin_function_type (DFmode, DFmode, VOIDmode, VOIDmode,
12125 RS6000_BUILTIN_RSQRT,
12126 "__builtin_rsqrt");
12127 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrt", ftype,
12128 RS6000_BUILTIN_RSQRT);
12130 if (TARGET_FRSQRTES)
12132 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
12133 RS6000_BUILTIN_RSQRTF,
12134 "__builtin_rsqrtf");
12135 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
12136 RS6000_BUILTIN_RSQRTF);
12138 if (TARGET_POPCNTD)
12140 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
12141 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
12142 POWER7_BUILTIN_BPERMD,
12143 "__builtin_bpermd");
12144 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
12145 POWER7_BUILTIN_BPERMD);
12147 if (TARGET_POWERPC)
12149 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
12150 tree ftype = build_function_type_list (unsigned_intHI_type_node,
12151 unsigned_intHI_type_node,
12153 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
12154 RS6000_BUILTIN_BSWAP_HI);
12158 /* AIX libm provides clog as __clog. */
12159 if ((tdecl = builtin_decl_explicit (BUILT_IN_CLOG)) != NULL_TREE)
12160 set_user_assembler_name (tdecl, "__clog");
12163 #ifdef SUBTARGET_INIT_BUILTINS
12164 SUBTARGET_INIT_BUILTINS;
12168 /* Returns the rs6000 builtin decl for CODE. */
12171 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
12173 if (code >= RS6000_BUILTIN_COUNT)
12174 return error_mark_node;
12176 return rs6000_builtin_decls[code];
12179 /* Search through a set of builtins and enable the mask bits.
12180 DESC is an array of builtins.
12181 SIZE is the total number of builtins.
12182 START is the builtin enum at which to start.
12183 END is the builtin enum at which to end. */
12185 enable_mask_for_builtins (struct builtin_description *desc, int size,
12186 enum rs6000_builtins start,
12187 enum rs6000_builtins end)
12191 for (i = 0; i < size; ++i)
12192 if (desc[i].code == start)
12198 for (; i < size; ++i)
12200 /* Flip all the bits on. */
12201 desc[i].mask = target_flags;
12202 if (desc[i].code == end)
12208 spe_init_builtins (void)
12210 tree puint_type_node = build_pointer_type (unsigned_type_node);
12211 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
12212 struct builtin_description *d;
12215 tree v2si_ftype_4_v2si
12216 = build_function_type_list (opaque_V2SI_type_node,
12217 opaque_V2SI_type_node,
12218 opaque_V2SI_type_node,
12219 opaque_V2SI_type_node,
12220 opaque_V2SI_type_node,
12223 tree v2sf_ftype_4_v2sf
12224 = build_function_type_list (opaque_V2SF_type_node,
12225 opaque_V2SF_type_node,
12226 opaque_V2SF_type_node,
12227 opaque_V2SF_type_node,
12228 opaque_V2SF_type_node,
12231 tree int_ftype_int_v2si_v2si
12232 = build_function_type_list (integer_type_node,
12234 opaque_V2SI_type_node,
12235 opaque_V2SI_type_node,
12238 tree int_ftype_int_v2sf_v2sf
12239 = build_function_type_list (integer_type_node,
12241 opaque_V2SF_type_node,
12242 opaque_V2SF_type_node,
12245 tree void_ftype_v2si_puint_int
12246 = build_function_type_list (void_type_node,
12247 opaque_V2SI_type_node,
12252 tree void_ftype_v2si_puint_char
12253 = build_function_type_list (void_type_node,
12254 opaque_V2SI_type_node,
12259 tree void_ftype_v2si_pv2si_int
12260 = build_function_type_list (void_type_node,
12261 opaque_V2SI_type_node,
12262 opaque_p_V2SI_type_node,
12266 tree void_ftype_v2si_pv2si_char
12267 = build_function_type_list (void_type_node,
12268 opaque_V2SI_type_node,
12269 opaque_p_V2SI_type_node,
12273 tree void_ftype_int
12274 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
12276 tree int_ftype_void
12277 = build_function_type_list (integer_type_node, NULL_TREE);
12279 tree v2si_ftype_pv2si_int
12280 = build_function_type_list (opaque_V2SI_type_node,
12281 opaque_p_V2SI_type_node,
12285 tree v2si_ftype_puint_int
12286 = build_function_type_list (opaque_V2SI_type_node,
12291 tree v2si_ftype_pushort_int
12292 = build_function_type_list (opaque_V2SI_type_node,
12297 tree v2si_ftype_signed_char
12298 = build_function_type_list (opaque_V2SI_type_node,
12299 signed_char_type_node,
12302 /* The initialization of the simple binary and unary builtins is
12303 done in rs6000_common_init_builtins, but we have to enable the
12304 mask bits here manually because we have run out of `target_flags'
12305 bits. We really need to redesign this mask business. */
12307 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
12308 ARRAY_SIZE (bdesc_2arg),
12309 SPE_BUILTIN_EVADDW,
12310 SPE_BUILTIN_EVXOR);
12311 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
12312 ARRAY_SIZE (bdesc_1arg),
12314 SPE_BUILTIN_EVSUBFUSIAAW);
12315 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
12316 ARRAY_SIZE (bdesc_spe_predicates),
12317 SPE_BUILTIN_EVCMPEQ,
12318 SPE_BUILTIN_EVFSTSTLT);
12319 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
12320 ARRAY_SIZE (bdesc_spe_evsel),
12321 SPE_BUILTIN_EVSEL_CMPGTS,
12322 SPE_BUILTIN_EVSEL_FSTSTEQ);
12324 (*lang_hooks.decls.pushdecl)
12325 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
12326 get_identifier ("__ev64_opaque__"),
12327 opaque_V2SI_type_node));
12329 /* Initialize irregular SPE builtins. */
12331 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
12332 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
12333 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
12334 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
12335 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
12336 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
12337 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
12338 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
12339 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
12340 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
12341 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
12342 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
12343 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
12344 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
12345 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
12346 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
12347 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
12348 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
12351 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
12352 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
12353 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
12354 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
12355 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
12356 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
12357 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
12358 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
12359 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
12360 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
12361 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
12362 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
12363 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
12364 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
12365 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
12366 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
12367 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
12368 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
12369 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
12370 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
12371 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
12372 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
12375 d = (struct builtin_description *) bdesc_spe_predicates;
12376 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
12380 switch (insn_data[d->icode].operand[1].mode)
12383 type = int_ftype_int_v2si_v2si;
12386 type = int_ftype_int_v2sf_v2sf;
12389 gcc_unreachable ();
12392 def_builtin (d->mask, d->name, type, d->code);
12395 /* Evsel predicates. */
12396 d = (struct builtin_description *) bdesc_spe_evsel;
12397 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
12401 switch (insn_data[d->icode].operand[1].mode)
12404 type = v2si_ftype_4_v2si;
12407 type = v2sf_ftype_4_v2sf;
12410 gcc_unreachable ();
12413 def_builtin (d->mask, d->name, type, d->code);
12418 paired_init_builtins (void)
12420 const struct builtin_description *d;
12423 tree int_ftype_int_v2sf_v2sf
12424 = build_function_type_list (integer_type_node,
12429 tree pcfloat_type_node =
12430 build_pointer_type (build_qualified_type
12431 (float_type_node, TYPE_QUAL_CONST));
12433 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
12434 long_integer_type_node,
12437 tree void_ftype_v2sf_long_pcfloat =
12438 build_function_type_list (void_type_node,
12440 long_integer_type_node,
12445 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
12446 PAIRED_BUILTIN_LX);
12449 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
12450 PAIRED_BUILTIN_STX);
12453 d = bdesc_paired_preds;
12454 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
12458 switch (insn_data[d->icode].operand[1].mode)
12461 type = int_ftype_int_v2sf_v2sf;
12464 gcc_unreachable ();
12467 def_builtin (d->mask, d->name, type, d->code);
12472 altivec_init_builtins (void)
12474 const struct builtin_description *d;
12475 const struct builtin_description_predicates *dp;
12479 tree pvoid_type_node = build_pointer_type (void_type_node);
12481 tree pcvoid_type_node
12482 = build_pointer_type (build_qualified_type (void_type_node,
12485 tree int_ftype_opaque
12486 = build_function_type_list (integer_type_node,
12487 opaque_V4SI_type_node, NULL_TREE);
12488 tree opaque_ftype_opaque
12489 = build_function_type_list (integer_type_node, NULL_TREE);
12490 tree opaque_ftype_opaque_int
12491 = build_function_type_list (opaque_V4SI_type_node,
12492 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
12493 tree opaque_ftype_opaque_opaque_int
12494 = build_function_type_list (opaque_V4SI_type_node,
12495 opaque_V4SI_type_node, opaque_V4SI_type_node,
12496 integer_type_node, NULL_TREE);
12497 tree int_ftype_int_opaque_opaque
12498 = build_function_type_list (integer_type_node,
12499 integer_type_node, opaque_V4SI_type_node,
12500 opaque_V4SI_type_node, NULL_TREE);
12501 tree int_ftype_int_v4si_v4si
12502 = build_function_type_list (integer_type_node,
12503 integer_type_node, V4SI_type_node,
12504 V4SI_type_node, NULL_TREE);
12505 tree void_ftype_v4si
12506 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
12507 tree v8hi_ftype_void
12508 = build_function_type_list (V8HI_type_node, NULL_TREE);
12509 tree void_ftype_void
12510 = build_function_type_list (void_type_node, NULL_TREE);
12511 tree void_ftype_int
12512 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
12514 tree opaque_ftype_long_pcvoid
12515 = build_function_type_list (opaque_V4SI_type_node,
12516 long_integer_type_node, pcvoid_type_node,
12518 tree v16qi_ftype_long_pcvoid
12519 = build_function_type_list (V16QI_type_node,
12520 long_integer_type_node, pcvoid_type_node,
12522 tree v8hi_ftype_long_pcvoid
12523 = build_function_type_list (V8HI_type_node,
12524 long_integer_type_node, pcvoid_type_node,
12526 tree v4si_ftype_long_pcvoid
12527 = build_function_type_list (V4SI_type_node,
12528 long_integer_type_node, pcvoid_type_node,
12530 tree v4sf_ftype_long_pcvoid
12531 = build_function_type_list (V4SF_type_node,
12532 long_integer_type_node, pcvoid_type_node,
12534 tree v2df_ftype_long_pcvoid
12535 = build_function_type_list (V2DF_type_node,
12536 long_integer_type_node, pcvoid_type_node,
12538 tree v2di_ftype_long_pcvoid
12539 = build_function_type_list (V2DI_type_node,
12540 long_integer_type_node, pcvoid_type_node,
12543 tree void_ftype_opaque_long_pvoid
12544 = build_function_type_list (void_type_node,
12545 opaque_V4SI_type_node, long_integer_type_node,
12546 pvoid_type_node, NULL_TREE);
12547 tree void_ftype_v4si_long_pvoid
12548 = build_function_type_list (void_type_node,
12549 V4SI_type_node, long_integer_type_node,
12550 pvoid_type_node, NULL_TREE);
12551 tree void_ftype_v16qi_long_pvoid
12552 = build_function_type_list (void_type_node,
12553 V16QI_type_node, long_integer_type_node,
12554 pvoid_type_node, NULL_TREE);
12555 tree void_ftype_v8hi_long_pvoid
12556 = build_function_type_list (void_type_node,
12557 V8HI_type_node, long_integer_type_node,
12558 pvoid_type_node, NULL_TREE);
12559 tree void_ftype_v4sf_long_pvoid
12560 = build_function_type_list (void_type_node,
12561 V4SF_type_node, long_integer_type_node,
12562 pvoid_type_node, NULL_TREE);
12563 tree void_ftype_v2df_long_pvoid
12564 = build_function_type_list (void_type_node,
12565 V2DF_type_node, long_integer_type_node,
12566 pvoid_type_node, NULL_TREE);
12567 tree void_ftype_v2di_long_pvoid
12568 = build_function_type_list (void_type_node,
12569 V2DI_type_node, long_integer_type_node,
12570 pvoid_type_node, NULL_TREE);
12571 tree int_ftype_int_v8hi_v8hi
12572 = build_function_type_list (integer_type_node,
12573 integer_type_node, V8HI_type_node,
12574 V8HI_type_node, NULL_TREE);
12575 tree int_ftype_int_v16qi_v16qi
12576 = build_function_type_list (integer_type_node,
12577 integer_type_node, V16QI_type_node,
12578 V16QI_type_node, NULL_TREE);
12579 tree int_ftype_int_v4sf_v4sf
12580 = build_function_type_list (integer_type_node,
12581 integer_type_node, V4SF_type_node,
12582 V4SF_type_node, NULL_TREE);
12583 tree int_ftype_int_v2df_v2df
12584 = build_function_type_list (integer_type_node,
12585 integer_type_node, V2DF_type_node,
12586 V2DF_type_node, NULL_TREE);
12587 tree v4si_ftype_v4si
12588 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
12589 tree v8hi_ftype_v8hi
12590 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
12591 tree v16qi_ftype_v16qi
12592 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
12593 tree v4sf_ftype_v4sf
12594 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
12595 tree v2df_ftype_v2df
12596 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
12597 tree void_ftype_pcvoid_int_int
12598 = build_function_type_list (void_type_node,
12599 pcvoid_type_node, integer_type_node,
12600 integer_type_node, NULL_TREE);
12602 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
12603 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
12604 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
12605 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
12606 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
12607 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
12608 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
12609 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
12610 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
12611 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
12612 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
12613 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
12614 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
12615 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
12616 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
12617 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
12618 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
12619 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
12620 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
12621 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
12622 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
12623 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
12624 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
12625 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
12626 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
12627 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
12628 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
12629 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
12630 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
12631 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
12633 def_builtin (MASK_VSX, "__builtin_vsx_lxvd2x_v2df", v2df_ftype_long_pcvoid,
12634 VSX_BUILTIN_LXVD2X_V2DF);
12635 def_builtin (MASK_VSX, "__builtin_vsx_lxvd2x_v2di", v2di_ftype_long_pcvoid,
12636 VSX_BUILTIN_LXVD2X_V2DI);
12637 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v4sf", v4sf_ftype_long_pcvoid,
12638 VSX_BUILTIN_LXVW4X_V4SF);
12639 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v4si", v4si_ftype_long_pcvoid,
12640 VSX_BUILTIN_LXVW4X_V4SI);
12641 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v8hi",
12642 v8hi_ftype_long_pcvoid, VSX_BUILTIN_LXVW4X_V8HI);
12643 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v16qi",
12644 v16qi_ftype_long_pcvoid, VSX_BUILTIN_LXVW4X_V16QI);
12645 def_builtin (MASK_VSX, "__builtin_vsx_stxvd2x_v2df",
12646 void_ftype_v2df_long_pvoid, VSX_BUILTIN_STXVD2X_V2DF);
12647 def_builtin (MASK_VSX, "__builtin_vsx_stxvd2x_v2di",
12648 void_ftype_v2di_long_pvoid, VSX_BUILTIN_STXVD2X_V2DI);
12649 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v4sf",
12650 void_ftype_v4sf_long_pvoid, VSX_BUILTIN_STXVW4X_V4SF);
12651 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v4si",
12652 void_ftype_v4si_long_pvoid, VSX_BUILTIN_STXVW4X_V4SI);
12653 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v8hi",
12654 void_ftype_v8hi_long_pvoid, VSX_BUILTIN_STXVW4X_V8HI);
12655 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v16qi",
12656 void_ftype_v16qi_long_pvoid, VSX_BUILTIN_STXVW4X_V16QI);
12657 def_builtin (MASK_VSX, "__builtin_vec_vsx_ld", opaque_ftype_long_pcvoid,
12658 VSX_BUILTIN_VEC_LD);
12659 def_builtin (MASK_VSX, "__builtin_vec_vsx_st", void_ftype_opaque_long_pvoid,
12660 VSX_BUILTIN_VEC_ST);
12662 if (rs6000_cpu == PROCESSOR_CELL)
12664 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
12665 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
12666 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
12667 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
12669 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
12670 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
12671 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
12672 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
12674 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
12675 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
12676 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
12677 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
12679 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
12680 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
12681 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
12682 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
12684 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
12685 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
12686 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
12688 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
12689 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
12690 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
12691 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
12692 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
12693 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
12694 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
12695 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
12696 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
12697 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
12698 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
12699 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
12701 /* Add the DST variants. */
12703 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
12704 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
12706 /* Initialize the predicates. */
12707 dp = bdesc_altivec_preds;
12708 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
12710 enum machine_mode mode1;
12712 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12713 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12714 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
12715 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
12720 mode1 = insn_data[dp->icode].operand[1].mode;
12725 type = int_ftype_int_opaque_opaque;
12728 type = int_ftype_int_v4si_v4si;
12731 type = int_ftype_int_v8hi_v8hi;
12734 type = int_ftype_int_v16qi_v16qi;
12737 type = int_ftype_int_v4sf_v4sf;
12740 type = int_ftype_int_v2df_v2df;
12743 gcc_unreachable ();
12746 def_builtin (dp->mask, dp->name, type, dp->code);
12749 /* Initialize the abs* operators. */
12751 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
12753 enum machine_mode mode0;
12756 mode0 = insn_data[d->icode].operand[0].mode;
12761 type = v4si_ftype_v4si;
12764 type = v8hi_ftype_v8hi;
12767 type = v16qi_ftype_v16qi;
12770 type = v4sf_ftype_v4sf;
12773 type = v2df_ftype_v2df;
12776 gcc_unreachable ();
12779 def_builtin (d->mask, d->name, type, d->code);
12782 if (TARGET_ALTIVEC)
12786 /* Initialize target builtin that implements
12787 targetm.vectorize.builtin_mask_for_load. */
12789 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
12790 v16qi_ftype_long_pcvoid,
12791 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
12792 BUILT_IN_MD, NULL, NULL_TREE);
12793 TREE_READONLY (decl) = 1;
12794 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
12795 altivec_builtin_mask_for_load = decl;
12798 /* Access to the vec_init patterns. */
12799 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
12800 integer_type_node, integer_type_node,
12801 integer_type_node, NULL_TREE);
12802 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
12803 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
12805 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
12806 short_integer_type_node,
12807 short_integer_type_node,
12808 short_integer_type_node,
12809 short_integer_type_node,
12810 short_integer_type_node,
12811 short_integer_type_node,
12812 short_integer_type_node, NULL_TREE);
12813 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
12814 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
12816 ftype = build_function_type_list (V16QI_type_node, char_type_node,
12817 char_type_node, char_type_node,
12818 char_type_node, char_type_node,
12819 char_type_node, char_type_node,
12820 char_type_node, char_type_node,
12821 char_type_node, char_type_node,
12822 char_type_node, char_type_node,
12823 char_type_node, char_type_node,
12824 char_type_node, NULL_TREE);
12825 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
12826 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
12828 ftype = build_function_type_list (V4SF_type_node, float_type_node,
12829 float_type_node, float_type_node,
12830 float_type_node, NULL_TREE);
12831 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
12832 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
12836 ftype = build_function_type_list (V2DF_type_node, double_type_node,
12837 double_type_node, NULL_TREE);
12838 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
12839 VSX_BUILTIN_VEC_INIT_V2DF);
12841 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
12842 intDI_type_node, NULL_TREE);
12843 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
12844 VSX_BUILTIN_VEC_INIT_V2DI);
12847 /* Access to the vec_set patterns. */
12848 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
12850 integer_type_node, NULL_TREE);
12851 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
12852 ALTIVEC_BUILTIN_VEC_SET_V4SI);
12854 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
12856 integer_type_node, NULL_TREE);
12857 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
12858 ALTIVEC_BUILTIN_VEC_SET_V8HI);
12860 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
12862 integer_type_node, NULL_TREE);
12863 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
12864 ALTIVEC_BUILTIN_VEC_SET_V16QI);
12866 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
12868 integer_type_node, NULL_TREE);
12869 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
12870 ALTIVEC_BUILTIN_VEC_SET_V4SF);
12874 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
12876 integer_type_node, NULL_TREE);
12877 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
12878 VSX_BUILTIN_VEC_SET_V2DF);
12880 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
12882 integer_type_node, NULL_TREE);
12883 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
12884 VSX_BUILTIN_VEC_SET_V2DI);
12887 /* Access to the vec_extract patterns. */
12888 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
12889 integer_type_node, NULL_TREE);
12890 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
12891 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
12893 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
12894 integer_type_node, NULL_TREE);
12895 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
12896 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
12898 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
12899 integer_type_node, NULL_TREE);
12900 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
12901 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
12903 ftype = build_function_type_list (float_type_node, V4SF_type_node,
12904 integer_type_node, NULL_TREE);
12905 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
12906 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
12910 ftype = build_function_type_list (double_type_node, V2DF_type_node,
12911 integer_type_node, NULL_TREE);
12912 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
12913 VSX_BUILTIN_VEC_EXT_V2DF);
12915 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
12916 integer_type_node, NULL_TREE);
12917 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
12918 VSX_BUILTIN_VEC_EXT_V2DI);
12922 /* Hash function for builtin functions with up to 3 arguments and a return
12925 builtin_hash_function (const void *hash_entry)
12929 const struct builtin_hash_struct *bh =
12930 (const struct builtin_hash_struct *) hash_entry;
12932 for (i = 0; i < 4; i++)
12934 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
12935 ret = (ret * 2) + bh->uns_p[i];
12941 /* Compare builtin hash entries H1 and H2 for equivalence. */
12943 builtin_hash_eq (const void *h1, const void *h2)
12945 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
12946 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
12948 return ((p1->mode[0] == p2->mode[0])
12949 && (p1->mode[1] == p2->mode[1])
12950 && (p1->mode[2] == p2->mode[2])
12951 && (p1->mode[3] == p2->mode[3])
12952 && (p1->uns_p[0] == p2->uns_p[0])
12953 && (p1->uns_p[1] == p2->uns_p[1])
12954 && (p1->uns_p[2] == p2->uns_p[2])
12955 && (p1->uns_p[3] == p2->uns_p[3]));
12958 /* Map types for builtin functions with an explicit return type and up to 3
12959 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
12960 of the argument. */
12962 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
12963 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
12964 enum rs6000_builtins builtin, const char *name)
12966 struct builtin_hash_struct h;
12967 struct builtin_hash_struct *h2;
12971 tree ret_type = NULL_TREE;
12972 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
12974 /* Create builtin_hash_table. */
12975 if (builtin_hash_table == NULL)
12976 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
12977 builtin_hash_eq, NULL);
12979 h.type = NULL_TREE;
12980 h.mode[0] = mode_ret;
12981 h.mode[1] = mode_arg0;
12982 h.mode[2] = mode_arg1;
12983 h.mode[3] = mode_arg2;
12989 /* If the builtin is a type that produces unsigned results or takes unsigned
12990 arguments, and it is returned as a decl for the vectorizer (such as
12991 widening multiplies, permute), make sure the arguments and return value
12992 are type correct. */
12995 /* unsigned 2 argument functions. */
12996 case ALTIVEC_BUILTIN_VMULEUB_UNS:
12997 case ALTIVEC_BUILTIN_VMULEUH_UNS:
12998 case ALTIVEC_BUILTIN_VMULOUB_UNS:
12999 case ALTIVEC_BUILTIN_VMULOUH_UNS:
13005 /* unsigned 3 argument functions. */
13006 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
13007 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
13008 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
13009 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
13010 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
13011 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
13012 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
13013 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
13014 case VSX_BUILTIN_VPERM_16QI_UNS:
13015 case VSX_BUILTIN_VPERM_8HI_UNS:
13016 case VSX_BUILTIN_VPERM_4SI_UNS:
13017 case VSX_BUILTIN_VPERM_2DI_UNS:
13018 case VSX_BUILTIN_XXSEL_16QI_UNS:
13019 case VSX_BUILTIN_XXSEL_8HI_UNS:
13020 case VSX_BUILTIN_XXSEL_4SI_UNS:
13021 case VSX_BUILTIN_XXSEL_2DI_UNS:
13028 /* signed permute functions with unsigned char mask. */
13029 case ALTIVEC_BUILTIN_VPERM_16QI:
13030 case ALTIVEC_BUILTIN_VPERM_8HI:
13031 case ALTIVEC_BUILTIN_VPERM_4SI:
13032 case ALTIVEC_BUILTIN_VPERM_4SF:
13033 case ALTIVEC_BUILTIN_VPERM_2DI:
13034 case ALTIVEC_BUILTIN_VPERM_2DF:
13035 case VSX_BUILTIN_VPERM_16QI:
13036 case VSX_BUILTIN_VPERM_8HI:
13037 case VSX_BUILTIN_VPERM_4SI:
13038 case VSX_BUILTIN_VPERM_4SF:
13039 case VSX_BUILTIN_VPERM_2DI:
13040 case VSX_BUILTIN_VPERM_2DF:
13044 /* unsigned args, signed return. */
13045 case VSX_BUILTIN_XVCVUXDDP_UNS:
13046 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
13050 /* signed args, unsigned return. */
13051 case VSX_BUILTIN_XVCVDPUXDS_UNS:
13052 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
13060 /* Figure out how many args are present. */
13061 while (num_args > 0 && h.mode[num_args] == VOIDmode)
13065 fatal_error ("internal error: builtin function %s had no type", name);
13067 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
13068 if (!ret_type && h.uns_p[0])
13069 ret_type = builtin_mode_to_type[h.mode[0]][0];
13072 fatal_error ("internal error: builtin function %s had an unexpected "
13073 "return type %s", name, GET_MODE_NAME (h.mode[0]));
13075 for (i = 0; i < (int) ARRAY_SIZE (arg_type); i++)
13076 arg_type[i] = NULL_TREE;
13078 for (i = 0; i < num_args; i++)
13080 int m = (int) h.mode[i+1];
13081 int uns_p = h.uns_p[i+1];
13083 arg_type[i] = builtin_mode_to_type[m][uns_p];
13084 if (!arg_type[i] && uns_p)
13085 arg_type[i] = builtin_mode_to_type[m][0];
13088 fatal_error ("internal error: builtin function %s, argument %d "
13089 "had unexpected argument type %s", name, i,
13090 GET_MODE_NAME (m));
13093 found = htab_find_slot (builtin_hash_table, &h, INSERT);
13094 if (*found == NULL)
13096 h2 = ggc_alloc_builtin_hash_struct ();
13098 *found = (void *)h2;
13100 h2->type = build_function_type_list (ret_type, arg_type[0], arg_type[1],
13101 arg_type[2], NULL_TREE);
13104 return ((struct builtin_hash_struct *)(*found))->type;
13108 rs6000_common_init_builtins (void)
13110 const struct builtin_description *d;
13113 tree opaque_ftype_opaque = NULL_TREE;
13114 tree opaque_ftype_opaque_opaque = NULL_TREE;
13115 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
13116 tree v2si_ftype_qi = NULL_TREE;
13117 tree v2si_ftype_v2si_qi = NULL_TREE;
13118 tree v2si_ftype_int_qi = NULL_TREE;
13120 if (!TARGET_PAIRED_FLOAT)
13122 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
13123 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
13126 /* Add the ternary operators. */
13128 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
13131 int mask = d->mask;
13133 if ((mask != 0 && (mask & target_flags) == 0)
13134 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13137 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13138 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13139 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13140 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13142 if (! (type = opaque_ftype_opaque_opaque_opaque))
13143 type = opaque_ftype_opaque_opaque_opaque
13144 = build_function_type_list (opaque_V4SI_type_node,
13145 opaque_V4SI_type_node,
13146 opaque_V4SI_type_node,
13147 opaque_V4SI_type_node,
13152 enum insn_code icode = d->icode;
13153 if (d->name == 0 || icode == CODE_FOR_nothing)
13156 type = builtin_function_type (insn_data[icode].operand[0].mode,
13157 insn_data[icode].operand[1].mode,
13158 insn_data[icode].operand[2].mode,
13159 insn_data[icode].operand[3].mode,
13163 def_builtin (d->mask, d->name, type, d->code);
13166 /* Add the binary operators. */
13168 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
13170 enum machine_mode mode0, mode1, mode2;
13172 int mask = d->mask;
13174 if ((mask != 0 && (mask & target_flags) == 0)
13175 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13178 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13179 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13180 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13181 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13183 if (! (type = opaque_ftype_opaque_opaque))
13184 type = opaque_ftype_opaque_opaque
13185 = build_function_type_list (opaque_V4SI_type_node,
13186 opaque_V4SI_type_node,
13187 opaque_V4SI_type_node,
13192 enum insn_code icode = d->icode;
13193 if (d->name == 0 || icode == CODE_FOR_nothing)
13196 mode0 = insn_data[icode].operand[0].mode;
13197 mode1 = insn_data[icode].operand[1].mode;
13198 mode2 = insn_data[icode].operand[2].mode;
13200 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
13202 if (! (type = v2si_ftype_v2si_qi))
13203 type = v2si_ftype_v2si_qi
13204 = build_function_type_list (opaque_V2SI_type_node,
13205 opaque_V2SI_type_node,
13210 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
13211 && mode2 == QImode)
13213 if (! (type = v2si_ftype_int_qi))
13214 type = v2si_ftype_int_qi
13215 = build_function_type_list (opaque_V2SI_type_node,
13222 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
13226 def_builtin (d->mask, d->name, type, d->code);
13229 /* Add the simple unary operators. */
13230 d = (struct builtin_description *) bdesc_1arg;
13231 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
13233 enum machine_mode mode0, mode1;
13235 int mask = d->mask;
13237 if ((mask != 0 && (mask & target_flags) == 0)
13238 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13241 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13242 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13243 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13244 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13246 if (! (type = opaque_ftype_opaque))
13247 type = opaque_ftype_opaque
13248 = build_function_type_list (opaque_V4SI_type_node,
13249 opaque_V4SI_type_node,
13254 enum insn_code icode = d->icode;
13255 if (d->name == 0 || icode == CODE_FOR_nothing)
13258 mode0 = insn_data[icode].operand[0].mode;
13259 mode1 = insn_data[icode].operand[1].mode;
13261 if (mode0 == V2SImode && mode1 == QImode)
13263 if (! (type = v2si_ftype_qi))
13264 type = v2si_ftype_qi
13265 = build_function_type_list (opaque_V2SI_type_node,
13271 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
13275 def_builtin (d->mask, d->name, type, d->code);
13280 rs6000_init_libfuncs (void)
13282 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
13283 && !TARGET_POWER2 && !TARGET_POWERPC)
13285 /* AIX library routines for float->int conversion. */
13286 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
13287 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
13288 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
13289 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
13292 if (!TARGET_IEEEQUAD)
13293 /* AIX/Darwin/64-bit Linux quad floating point routines. */
13294 if (!TARGET_XL_COMPAT)
13296 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
13297 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
13298 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
13299 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
13301 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
13303 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
13304 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
13305 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
13306 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
13307 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
13308 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
13309 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
13311 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
13312 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
13313 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
13314 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
13315 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
13316 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
13317 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
13318 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
13321 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
13322 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
13326 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
13327 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
13328 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
13329 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
13333 /* 32-bit SVR4 quad floating point routines. */
13335 set_optab_libfunc (add_optab, TFmode, "_q_add");
13336 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
13337 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
13338 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
13339 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
13340 if (TARGET_PPC_GPOPT || TARGET_POWER2)
13341 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
13343 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
13344 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
13345 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
13346 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
13347 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
13348 set_optab_libfunc (le_optab, TFmode, "_q_fle");
13350 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
13351 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
13352 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
13353 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
13354 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
13355 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
13356 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
13357 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
13362 /* Expand a block clear operation, and return 1 if successful. Return 0
13363 if we should let the compiler generate normal code.
13365 operands[0] is the destination
13366 operands[1] is the length
13367 operands[3] is the alignment */
13370 expand_block_clear (rtx operands[])
13372 rtx orig_dest = operands[0];
13373 rtx bytes_rtx = operands[1];
13374 rtx align_rtx = operands[3];
13375 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
13376 HOST_WIDE_INT align;
13377 HOST_WIDE_INT bytes;
13382 /* If this is not a fixed size move, just call memcpy */
13386 /* This must be a fixed size alignment */
13387 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13388 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13390 /* Anything to clear? */
13391 bytes = INTVAL (bytes_rtx);
13395 /* Use the builtin memset after a point, to avoid huge code bloat.
13396 When optimize_size, avoid any significant code bloat; calling
13397 memset is about 4 instructions, so allow for one instruction to
13398 load zero and three to do clearing. */
13399 if (TARGET_ALTIVEC && align >= 128)
13401 else if (TARGET_POWERPC64 && align >= 32)
13403 else if (TARGET_SPE && align >= 64)
13408 if (optimize_size && bytes > 3 * clear_step)
13410 if (! optimize_size && bytes > 8 * clear_step)
13413 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
13415 enum machine_mode mode = BLKmode;
13418 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
13423 else if (bytes >= 8 && TARGET_SPE && align >= 64)
13428 else if (bytes >= 8 && TARGET_POWERPC64
13429 /* 64-bit loads and stores require word-aligned
13431 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13436 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13437 { /* move 4 bytes */
13441 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13442 { /* move 2 bytes */
13446 else /* move 1 byte at a time */
13452 dest = adjust_address (orig_dest, mode, offset);
13454 emit_move_insn (dest, CONST0_RTX (mode));
13461 /* Expand a block move operation, and return 1 if successful. Return 0
13462 if we should let the compiler generate normal code.
13464 operands[0] is the destination
13465 operands[1] is the source
13466 operands[2] is the length
13467 operands[3] is the alignment */
13469 #define MAX_MOVE_REG 4
13472 expand_block_move (rtx operands[])
13474 rtx orig_dest = operands[0];
13475 rtx orig_src = operands[1];
13476 rtx bytes_rtx = operands[2];
13477 rtx align_rtx = operands[3];
13478 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
13483 rtx stores[MAX_MOVE_REG];
13486 /* If this is not a fixed size move, just call memcpy */
13490 /* This must be a fixed size alignment */
13491 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13492 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13494 /* Anything to move? */
13495 bytes = INTVAL (bytes_rtx);
13499 if (bytes > rs6000_block_move_inline_limit)
13502 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
13505 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
13506 rtx (*mov) (rtx, rtx);
13508 enum machine_mode mode = BLKmode;
13511 /* Altivec first, since it will be faster than a string move
13512 when it applies, and usually not significantly larger. */
13513 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
13517 gen_func.mov = gen_movv4si;
13519 else if (TARGET_SPE && bytes >= 8 && align >= 64)
13523 gen_func.mov = gen_movv2si;
13525 else if (TARGET_STRING
13526 && bytes > 24 /* move up to 32 bytes at a time */
13532 && ! fixed_regs[10]
13533 && ! fixed_regs[11]
13534 && ! fixed_regs[12])
13536 move_bytes = (bytes > 32) ? 32 : bytes;
13537 gen_func.movmemsi = gen_movmemsi_8reg;
13539 else if (TARGET_STRING
13540 && bytes > 16 /* move up to 24 bytes at a time */
13546 && ! fixed_regs[10])
13548 move_bytes = (bytes > 24) ? 24 : bytes;
13549 gen_func.movmemsi = gen_movmemsi_6reg;
13551 else if (TARGET_STRING
13552 && bytes > 8 /* move up to 16 bytes at a time */
13556 && ! fixed_regs[8])
13558 move_bytes = (bytes > 16) ? 16 : bytes;
13559 gen_func.movmemsi = gen_movmemsi_4reg;
13561 else if (bytes >= 8 && TARGET_POWERPC64
13562 /* 64-bit loads and stores require word-aligned
13564 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13568 gen_func.mov = gen_movdi;
13570 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
13571 { /* move up to 8 bytes at a time */
13572 move_bytes = (bytes > 8) ? 8 : bytes;
13573 gen_func.movmemsi = gen_movmemsi_2reg;
13575 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13576 { /* move 4 bytes */
13579 gen_func.mov = gen_movsi;
13581 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13582 { /* move 2 bytes */
13585 gen_func.mov = gen_movhi;
13587 else if (TARGET_STRING && bytes > 1)
13588 { /* move up to 4 bytes at a time */
13589 move_bytes = (bytes > 4) ? 4 : bytes;
13590 gen_func.movmemsi = gen_movmemsi_1reg;
13592 else /* move 1 byte at a time */
13596 gen_func.mov = gen_movqi;
13599 src = adjust_address (orig_src, mode, offset);
13600 dest = adjust_address (orig_dest, mode, offset);
13602 if (mode != BLKmode)
13604 rtx tmp_reg = gen_reg_rtx (mode);
13606 emit_insn ((*gen_func.mov) (tmp_reg, src));
13607 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
13610 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
13613 for (i = 0; i < num_reg; i++)
13614 emit_insn (stores[i]);
13618 if (mode == BLKmode)
13620 /* Move the address into scratch registers. The movmemsi
13621 patterns require zero offset. */
13622 if (!REG_P (XEXP (src, 0)))
13624 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
13625 src = replace_equiv_address (src, src_reg);
13627 set_mem_size (src, move_bytes);
13629 if (!REG_P (XEXP (dest, 0)))
13631 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
13632 dest = replace_equiv_address (dest, dest_reg);
13634 set_mem_size (dest, move_bytes);
13636 emit_insn ((*gen_func.movmemsi) (dest, src,
13637 GEN_INT (move_bytes & 31),
13646 /* Return a string to perform a load_multiple operation.
13647 operands[0] is the vector.
13648 operands[1] is the source address.
13649 operands[2] is the first destination register. */
13652 rs6000_output_load_multiple (rtx operands[3])
13654 /* We have to handle the case where the pseudo used to contain the address
13655 is assigned to one of the output registers. */
13657 int words = XVECLEN (operands[0], 0);
13660 if (XVECLEN (operands[0], 0) == 1)
13661 return "{l|lwz} %2,0(%1)";
13663 for (i = 0; i < words; i++)
13664 if (refers_to_regno_p (REGNO (operands[2]) + i,
13665 REGNO (operands[2]) + i + 1, operands[1], 0))
13669 xop[0] = GEN_INT (4 * (words-1));
13670 xop[1] = operands[1];
13671 xop[2] = operands[2];
13672 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
13677 xop[0] = GEN_INT (4 * (words-1));
13678 xop[1] = operands[1];
13679 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
13680 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);
13685 for (j = 0; j < words; j++)
13688 xop[0] = GEN_INT (j * 4);
13689 xop[1] = operands[1];
13690 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
13691 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
13693 xop[0] = GEN_INT (i * 4);
13694 xop[1] = operands[1];
13695 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
13700 return "{lsi|lswi} %2,%1,%N0";
13704 /* A validation routine: say whether CODE, a condition code, and MODE
13705 match. The other alternatives either don't make sense or should
13706 never be generated. */
13709 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
13711 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
13712 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
13713 && GET_MODE_CLASS (mode) == MODE_CC);
13715 /* These don't make sense. */
13716 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
13717 || mode != CCUNSmode);
13719 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
13720 || mode == CCUNSmode);
13722 gcc_assert (mode == CCFPmode
13723 || (code != ORDERED && code != UNORDERED
13724 && code != UNEQ && code != LTGT
13725 && code != UNGT && code != UNLT
13726 && code != UNGE && code != UNLE));
13728 /* These should never be generated except for
13729 flag_finite_math_only. */
13730 gcc_assert (mode != CCFPmode
13731 || flag_finite_math_only
13732 || (code != LE && code != GE
13733 && code != UNEQ && code != LTGT
13734 && code != UNGT && code != UNLT));
13736 /* These are invalid; the information is not there. */
13737 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
13741 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
13742 mask required to convert the result of a rotate insn into a shift
13743 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
13746 includes_lshift_p (rtx shiftop, rtx andop)
13748 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
13750 shift_mask <<= INTVAL (shiftop);
13752 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
13755 /* Similar, but for right shift. */
13758 includes_rshift_p (rtx shiftop, rtx andop)
13760 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
13762 shift_mask >>= INTVAL (shiftop);
13764 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
13767 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
13768 to perform a left shift. It must have exactly SHIFTOP least
13769 significant 0's, then one or more 1's, then zero or more 0's. */
13772 includes_rldic_lshift_p (rtx shiftop, rtx andop)
13774 if (GET_CODE (andop) == CONST_INT)
13776 HOST_WIDE_INT c, lsb, shift_mask;
13778 c = INTVAL (andop);
13779 if (c == 0 || c == ~0)
13783 shift_mask <<= INTVAL (shiftop);
13785 /* Find the least significant one bit. */
13788 /* It must coincide with the LSB of the shift mask. */
13789 if (-lsb != shift_mask)
13792 /* Invert to look for the next transition (if any). */
13795 /* Remove the low group of ones (originally low group of zeros). */
13798 /* Again find the lsb, and check we have all 1's above. */
13802 else if (GET_CODE (andop) == CONST_DOUBLE
13803 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
13805 HOST_WIDE_INT low, high, lsb;
13806 HOST_WIDE_INT shift_mask_low, shift_mask_high;
13808 low = CONST_DOUBLE_LOW (andop);
13809 if (HOST_BITS_PER_WIDE_INT < 64)
13810 high = CONST_DOUBLE_HIGH (andop);
13812 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
13813 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
13816 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13818 shift_mask_high = ~0;
13819 if (INTVAL (shiftop) > 32)
13820 shift_mask_high <<= INTVAL (shiftop) - 32;
13822 lsb = high & -high;
13824 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
13830 lsb = high & -high;
13831 return high == -lsb;
13834 shift_mask_low = ~0;
13835 shift_mask_low <<= INTVAL (shiftop);
13839 if (-lsb != shift_mask_low)
13842 if (HOST_BITS_PER_WIDE_INT < 64)
13847 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13849 lsb = high & -high;
13850 return high == -lsb;
13854 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
13860 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
13861 to perform a left shift. It must have SHIFTOP or more least
13862 significant 0's, with the remainder of the word 1's. */
13865 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
13867 if (GET_CODE (andop) == CONST_INT)
13869 HOST_WIDE_INT c, lsb, shift_mask;
13872 shift_mask <<= INTVAL (shiftop);
13873 c = INTVAL (andop);
13875 /* Find the least significant one bit. */
13878 /* It must be covered by the shift mask.
13879 This test also rejects c == 0. */
13880 if ((lsb & shift_mask) == 0)
13883 /* Check we have all 1's above the transition, and reject all 1's. */
13884 return c == -lsb && lsb != 1;
13886 else if (GET_CODE (andop) == CONST_DOUBLE
13887 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
13889 HOST_WIDE_INT low, lsb, shift_mask_low;
13891 low = CONST_DOUBLE_LOW (andop);
13893 if (HOST_BITS_PER_WIDE_INT < 64)
13895 HOST_WIDE_INT high, shift_mask_high;
13897 high = CONST_DOUBLE_HIGH (andop);
13901 shift_mask_high = ~0;
13902 if (INTVAL (shiftop) > 32)
13903 shift_mask_high <<= INTVAL (shiftop) - 32;
13905 lsb = high & -high;
13907 if ((lsb & shift_mask_high) == 0)
13910 return high == -lsb;
13916 shift_mask_low = ~0;
13917 shift_mask_low <<= INTVAL (shiftop);
13921 if ((lsb & shift_mask_low) == 0)
13924 return low == -lsb && lsb != 1;
13930 /* Return 1 if operands will generate a valid arguments to rlwimi
13931 instruction for insert with right shift in 64-bit mode. The mask may
13932 not start on the first bit or stop on the last bit because wrap-around
13933 effects of instruction do not correspond to semantics of RTL insn. */
13936 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
13938 if (INTVAL (startop) > 32
13939 && INTVAL (startop) < 64
13940 && INTVAL (sizeop) > 1
13941 && INTVAL (sizeop) + INTVAL (startop) < 64
13942 && INTVAL (shiftop) > 0
13943 && INTVAL (sizeop) + INTVAL (shiftop) < 32
13944 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
13950 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
13951 for lfq and stfq insns iff the registers are hard registers. */
13954 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
13956 /* We might have been passed a SUBREG. */
13957 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
13960 /* We might have been passed non floating point registers. */
13961 if (!FP_REGNO_P (REGNO (reg1))
13962 || !FP_REGNO_P (REGNO (reg2)))
13965 return (REGNO (reg1) == REGNO (reg2) - 1);
13968 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
13969 addr1 and addr2 must be in consecutive memory locations
13970 (addr2 == addr1 + 8). */
13973 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
13976 unsigned int reg1, reg2;
13977 int offset1, offset2;
13979 /* The mems cannot be volatile. */
13980 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
13983 addr1 = XEXP (mem1, 0);
13984 addr2 = XEXP (mem2, 0);
13986 /* Extract an offset (if used) from the first addr. */
13987 if (GET_CODE (addr1) == PLUS)
13989 /* If not a REG, return zero. */
13990 if (GET_CODE (XEXP (addr1, 0)) != REG)
13994 reg1 = REGNO (XEXP (addr1, 0));
13995 /* The offset must be constant! */
13996 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
13998 offset1 = INTVAL (XEXP (addr1, 1));
14001 else if (GET_CODE (addr1) != REG)
14005 reg1 = REGNO (addr1);
14006 /* This was a simple (mem (reg)) expression. Offset is 0. */
14010 /* And now for the second addr. */
14011 if (GET_CODE (addr2) == PLUS)
14013 /* If not a REG, return zero. */
14014 if (GET_CODE (XEXP (addr2, 0)) != REG)
14018 reg2 = REGNO (XEXP (addr2, 0));
14019 /* The offset must be constant. */
14020 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
14022 offset2 = INTVAL (XEXP (addr2, 1));
14025 else if (GET_CODE (addr2) != REG)
14029 reg2 = REGNO (addr2);
14030 /* This was a simple (mem (reg)) expression. Offset is 0. */
14034 /* Both of these must have the same base register. */
14038 /* The offset for the second addr must be 8 more than the first addr. */
14039 if (offset2 != offset1 + 8)
14042 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
14049 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
14051 static bool eliminated = false;
14054 if (mode != SDmode)
14055 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
14058 rtx mem = cfun->machine->sdmode_stack_slot;
14059 gcc_assert (mem != NULL_RTX);
14063 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
14064 cfun->machine->sdmode_stack_slot = mem;
14070 if (TARGET_DEBUG_ADDR)
14072 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
14073 GET_MODE_NAME (mode));
14075 fprintf (stderr, "\tNULL_RTX\n");
14084 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
14086 /* Don't walk into types. */
14087 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
14089 *walk_subtrees = 0;
14093 switch (TREE_CODE (*tp))
14102 case VIEW_CONVERT_EXPR:
14103 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
14113 enum reload_reg_type {
14115 VECTOR_REGISTER_TYPE,
14116 OTHER_REGISTER_TYPE
14119 static enum reload_reg_type
14120 rs6000_reload_register_type (enum reg_class rclass)
14126 return GPR_REGISTER_TYPE;
14131 return VECTOR_REGISTER_TYPE;
14134 return OTHER_REGISTER_TYPE;
14138 /* Inform reload about cases where moving X with a mode MODE to a register in
14139 RCLASS requires an extra scratch or immediate register. Return the class
14140 needed for the immediate register.
14142 For VSX and Altivec, we may need a register to convert sp+offset into
14145 For misaligned 64-bit gpr loads and stores we need a register to
14146 convert an offset address to indirect. */
14149 rs6000_secondary_reload (bool in_p,
14151 reg_class_t rclass_i,
14152 enum machine_mode mode,
14153 secondary_reload_info *sri)
14155 enum reg_class rclass = (enum reg_class) rclass_i;
14156 reg_class_t ret = ALL_REGS;
14157 enum insn_code icode;
14158 bool default_p = false;
14160 sri->icode = CODE_FOR_nothing;
14162 /* Convert vector loads and stores into gprs to use an additional base
14164 icode = rs6000_vector_reload[mode][in_p != false];
14165 if (icode != CODE_FOR_nothing)
14168 sri->icode = CODE_FOR_nothing;
14169 sri->extra_cost = 0;
14171 if (GET_CODE (x) == MEM)
14173 rtx addr = XEXP (x, 0);
14175 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
14176 an extra register in that case, but it would need an extra
14177 register if the addressing is reg+reg or (reg+reg)&(-16). */
14178 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
14180 if (!legitimate_indirect_address_p (addr, false)
14181 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14183 sri->icode = icode;
14184 /* account for splitting the loads, and converting the
14185 address from reg+reg to reg. */
14186 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
14187 + ((GET_CODE (addr) == AND) ? 1 : 0));
14190 /* Loads to and stores from vector registers can only do reg+reg
14191 addressing. Altivec registers can also do (reg+reg)&(-16). */
14192 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
14193 || rclass == FLOAT_REGS || rclass == NO_REGS)
14195 if (!VECTOR_MEM_ALTIVEC_P (mode)
14196 && GET_CODE (addr) == AND
14197 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14198 && INTVAL (XEXP (addr, 1)) == -16
14199 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
14200 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
14202 sri->icode = icode;
14203 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
14206 else if (!legitimate_indirect_address_p (addr, false)
14207 && (rclass == NO_REGS
14208 || !legitimate_indexed_address_p (addr, false)))
14210 sri->icode = icode;
14211 sri->extra_cost = 1;
14214 icode = CODE_FOR_nothing;
14216 /* Any other loads, including to pseudo registers which haven't been
14217 assigned to a register yet, default to require a scratch
14221 sri->icode = icode;
14222 sri->extra_cost = 2;
14225 else if (REG_P (x))
14227 int regno = true_regnum (x);
14229 icode = CODE_FOR_nothing;
14230 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
14234 enum reg_class xclass = REGNO_REG_CLASS (regno);
14235 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
14236 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
14238 /* If memory is needed, use default_secondary_reload to create the
14240 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
14249 else if (TARGET_POWERPC64
14250 && rs6000_reload_register_type (rclass) == GPR_REGISTER_TYPE
14252 && GET_MODE_SIZE (GET_MODE (x)) >= UNITS_PER_WORD)
14254 rtx addr = XEXP (x, 0);
14256 if (GET_CODE (addr) == PRE_MODIFY)
14257 addr = XEXP (addr, 1);
14258 else if (GET_CODE (addr) == LO_SUM
14259 && GET_CODE (XEXP (addr, 0)) == REG
14260 && GET_CODE (XEXP (addr, 1)) == CONST)
14261 addr = XEXP (XEXP (addr, 1), 0);
14263 if (GET_CODE (addr) == PLUS
14264 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14265 && (INTVAL (XEXP (addr, 1)) & 3) != 0)
14268 sri->icode = CODE_FOR_reload_di_load;
14270 sri->icode = CODE_FOR_reload_di_store;
14271 sri->extra_cost = 2;
14281 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
14283 gcc_assert (ret != ALL_REGS);
14285 if (TARGET_DEBUG_ADDR)
14288 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
14290 reg_class_names[ret],
14291 in_p ? "true" : "false",
14292 reg_class_names[rclass],
14293 GET_MODE_NAME (mode));
14296 fprintf (stderr, ", default secondary reload");
14298 if (sri->icode != CODE_FOR_nothing)
14299 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
14300 insn_data[sri->icode].name, sri->extra_cost);
14302 fprintf (stderr, "\n");
14310 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
14311 to SP+reg addressing. */
14314 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
14316 int regno = true_regnum (reg);
14317 enum machine_mode mode = GET_MODE (reg);
14318 enum reg_class rclass;
14320 rtx and_op2 = NULL_RTX;
14323 rtx scratch_or_premodify = scratch;
14327 if (TARGET_DEBUG_ADDR)
14329 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
14330 store_p ? "store" : "load");
14331 fprintf (stderr, "reg:\n");
14333 fprintf (stderr, "mem:\n");
14335 fprintf (stderr, "scratch:\n");
14336 debug_rtx (scratch);
14339 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
14340 gcc_assert (GET_CODE (mem) == MEM);
14341 rclass = REGNO_REG_CLASS (regno);
14342 addr = XEXP (mem, 0);
14346 /* GPRs can handle reg + small constant, all other addresses need to use
14347 the scratch register. */
14350 if (GET_CODE (addr) == AND)
14352 and_op2 = XEXP (addr, 1);
14353 addr = XEXP (addr, 0);
14356 if (GET_CODE (addr) == PRE_MODIFY)
14358 scratch_or_premodify = XEXP (addr, 0);
14359 gcc_assert (REG_P (scratch_or_premodify));
14360 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14361 addr = XEXP (addr, 1);
14364 if (GET_CODE (addr) == PLUS
14365 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
14366 || and_op2 != NULL_RTX))
14368 addr_op1 = XEXP (addr, 0);
14369 addr_op2 = XEXP (addr, 1);
14370 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
14372 if (!REG_P (addr_op2)
14373 && (GET_CODE (addr_op2) != CONST_INT
14374 || !satisfies_constraint_I (addr_op2)))
14376 if (TARGET_DEBUG_ADDR)
14379 "\nMove plus addr to register %s, mode = %s: ",
14380 rs6000_reg_names[REGNO (scratch)],
14381 GET_MODE_NAME (mode));
14382 debug_rtx (addr_op2);
14384 rs6000_emit_move (scratch, addr_op2, Pmode);
14385 addr_op2 = scratch;
14388 emit_insn (gen_rtx_SET (VOIDmode,
14389 scratch_or_premodify,
14390 gen_rtx_PLUS (Pmode,
14394 addr = scratch_or_premodify;
14395 scratch_or_premodify = scratch;
14397 else if (!legitimate_indirect_address_p (addr, false)
14398 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14400 if (TARGET_DEBUG_ADDR)
14402 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14403 rs6000_reg_names[REGNO (scratch_or_premodify)],
14404 GET_MODE_NAME (mode));
14407 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14408 addr = scratch_or_premodify;
14409 scratch_or_premodify = scratch;
14413 /* Float/Altivec registers can only handle reg+reg addressing. Move
14414 other addresses into a scratch register. */
14419 /* With float regs, we need to handle the AND ourselves, since we can't
14420 use the Altivec instruction with an implicit AND -16. Allow scalar
14421 loads to float registers to use reg+offset even if VSX. */
14422 if (GET_CODE (addr) == AND
14423 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
14424 || GET_CODE (XEXP (addr, 1)) != CONST_INT
14425 || INTVAL (XEXP (addr, 1)) != -16
14426 || !VECTOR_MEM_ALTIVEC_P (mode)))
14428 and_op2 = XEXP (addr, 1);
14429 addr = XEXP (addr, 0);
14432 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
14433 as the address later. */
14434 if (GET_CODE (addr) == PRE_MODIFY
14435 && (!VECTOR_MEM_VSX_P (mode)
14436 || and_op2 != NULL_RTX
14437 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
14439 scratch_or_premodify = XEXP (addr, 0);
14440 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
14442 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14443 addr = XEXP (addr, 1);
14446 if (legitimate_indirect_address_p (addr, false) /* reg */
14447 || legitimate_indexed_address_p (addr, false) /* reg+reg */
14448 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
14449 || (GET_CODE (addr) == AND /* Altivec memory */
14450 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14451 && INTVAL (XEXP (addr, 1)) == -16
14452 && VECTOR_MEM_ALTIVEC_P (mode))
14453 || (rclass == FLOAT_REGS /* legacy float mem */
14454 && GET_MODE_SIZE (mode) == 8
14455 && and_op2 == NULL_RTX
14456 && scratch_or_premodify == scratch
14457 && rs6000_legitimate_offset_address_p (mode, addr, false)))
14460 else if (GET_CODE (addr) == PLUS)
14462 addr_op1 = XEXP (addr, 0);
14463 addr_op2 = XEXP (addr, 1);
14464 gcc_assert (REG_P (addr_op1));
14466 if (TARGET_DEBUG_ADDR)
14468 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
14469 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14470 debug_rtx (addr_op2);
14472 rs6000_emit_move (scratch, addr_op2, Pmode);
14473 emit_insn (gen_rtx_SET (VOIDmode,
14474 scratch_or_premodify,
14475 gen_rtx_PLUS (Pmode,
14478 addr = scratch_or_premodify;
14479 scratch_or_premodify = scratch;
14482 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
14483 || GET_CODE (addr) == CONST_INT || REG_P (addr))
14485 if (TARGET_DEBUG_ADDR)
14487 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14488 rs6000_reg_names[REGNO (scratch_or_premodify)],
14489 GET_MODE_NAME (mode));
14493 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14494 addr = scratch_or_premodify;
14495 scratch_or_premodify = scratch;
14499 gcc_unreachable ();
14504 gcc_unreachable ();
14507 /* If the original address involved a pre-modify that we couldn't use the VSX
14508 memory instruction with update, and we haven't taken care of already,
14509 store the address in the pre-modify register and use that as the
14511 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
14513 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
14514 addr = scratch_or_premodify;
14517 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
14518 memory instruction, recreate the AND now, including the clobber which is
14519 generated by the general ANDSI3/ANDDI3 patterns for the
14520 andi. instruction. */
14521 if (and_op2 != NULL_RTX)
14523 if (! legitimate_indirect_address_p (addr, false))
14525 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
14529 if (TARGET_DEBUG_ADDR)
14531 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
14532 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14533 debug_rtx (and_op2);
14536 and_rtx = gen_rtx_SET (VOIDmode,
14538 gen_rtx_AND (Pmode,
14542 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
14543 emit_insn (gen_rtx_PARALLEL (VOIDmode,
14544 gen_rtvec (2, and_rtx, cc_clobber)));
14548 /* Adjust the address if it changed. */
14549 if (addr != XEXP (mem, 0))
14551 mem = change_address (mem, mode, addr);
14552 if (TARGET_DEBUG_ADDR)
14553 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
14556 /* Now create the move. */
14558 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
14560 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
14565 /* Convert reloads involving 64-bit gprs and misaligned offset
14566 addressing to use indirect addressing. */
14569 rs6000_secondary_reload_ppc64 (rtx reg, rtx mem, rtx scratch, bool store_p)
14571 int regno = true_regnum (reg);
14572 enum reg_class rclass;
14574 rtx scratch_or_premodify = scratch;
14576 if (TARGET_DEBUG_ADDR)
14578 fprintf (stderr, "\nrs6000_secondary_reload_ppc64, type = %s\n",
14579 store_p ? "store" : "load");
14580 fprintf (stderr, "reg:\n");
14582 fprintf (stderr, "mem:\n");
14584 fprintf (stderr, "scratch:\n");
14585 debug_rtx (scratch);
14588 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
14589 gcc_assert (GET_CODE (mem) == MEM);
14590 rclass = REGNO_REG_CLASS (regno);
14591 gcc_assert (rclass == GENERAL_REGS || rclass == BASE_REGS);
14592 addr = XEXP (mem, 0);
14594 if (GET_CODE (addr) == PRE_MODIFY)
14596 scratch_or_premodify = XEXP (addr, 0);
14597 gcc_assert (REG_P (scratch_or_premodify));
14598 addr = XEXP (addr, 1);
14600 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
14602 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14604 mem = replace_equiv_address_nv (mem, scratch_or_premodify);
14606 /* Now create the move. */
14608 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
14610 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
14615 /* Allocate a 64-bit stack slot to be used for copying SDmode
14616 values through if this function has any SDmode references. */
14619 rs6000_alloc_sdmode_stack_slot (void)
14623 gimple_stmt_iterator gsi;
14625 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
14628 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
14630 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
14633 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14634 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14640 /* Check for any SDmode parameters of the function. */
14641 for (t = DECL_ARGUMENTS (cfun->decl); t; t = DECL_CHAIN (t))
14643 if (TREE_TYPE (t) == error_mark_node)
14646 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
14647 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
14649 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14650 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14658 rs6000_instantiate_decls (void)
14660 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
14661 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
14664 /* Given an rtx X being reloaded into a reg required to be
14665 in class CLASS, return the class of reg to actually use.
14666 In general this is just CLASS; but on some machines
14667 in some cases it is preferable to use a more restrictive class.
14669 On the RS/6000, we have to return NO_REGS when we want to reload a
14670 floating-point CONST_DOUBLE to force it to be copied to memory.
14672 We also don't want to reload integer values into floating-point
14673 registers if we can at all help it. In fact, this can
14674 cause reload to die, if it tries to generate a reload of CTR
14675 into a FP register and discovers it doesn't have the memory location
14678 ??? Would it be a good idea to have reload do the converse, that is
14679 try to reload floating modes into FP registers if possible?
14682 static enum reg_class
14683 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
14685 enum machine_mode mode = GET_MODE (x);
14687 if (VECTOR_UNIT_VSX_P (mode)
14688 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
14691 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
14692 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
14693 && easy_vector_constant (x, mode))
14694 return ALTIVEC_REGS;
14696 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
14699 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
14700 return GENERAL_REGS;
14702 /* For VSX, prefer the traditional registers for 64-bit values because we can
14703 use the non-VSX loads. Prefer the Altivec registers if Altivec is
14704 handling the vector operations (i.e. V16QI, V8HI, and V4SI), or if we
14705 prefer Altivec loads.. */
14706 if (rclass == VSX_REGS)
14708 if (GET_MODE_SIZE (mode) <= 8)
14711 if (VECTOR_UNIT_ALTIVEC_P (mode) || VECTOR_MEM_ALTIVEC_P (mode))
14712 return ALTIVEC_REGS;
14720 /* Debug version of rs6000_preferred_reload_class. */
14721 static enum reg_class
14722 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
14724 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
14727 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
14729 reg_class_names[ret], reg_class_names[rclass],
14730 GET_MODE_NAME (GET_MODE (x)));
14736 /* If we are copying between FP or AltiVec registers and anything else, we need
14737 a memory location. The exception is when we are targeting ppc64 and the
14738 move to/from fpr to gpr instructions are available. Also, under VSX, you
14739 can copy vector registers from the FP register set to the Altivec register
14740 set and vice versa. */
14743 rs6000_secondary_memory_needed (enum reg_class class1,
14744 enum reg_class class2,
14745 enum machine_mode mode)
14747 if (class1 == class2)
14750 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
14751 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
14752 between these classes. But we need memory for other things that can go in
14753 FLOAT_REGS like SFmode. */
14755 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
14756 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
14757 || class1 == FLOAT_REGS))
14758 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
14759 && class2 != FLOAT_REGS);
14761 if (class1 == VSX_REGS || class2 == VSX_REGS)
14764 if (class1 == FLOAT_REGS
14765 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14766 || ((mode != DFmode)
14767 && (mode != DDmode)
14768 && (mode != DImode))))
14771 if (class2 == FLOAT_REGS
14772 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14773 || ((mode != DFmode)
14774 && (mode != DDmode)
14775 && (mode != DImode))))
14778 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
14784 /* Debug version of rs6000_secondary_memory_needed. */
14786 rs6000_debug_secondary_memory_needed (enum reg_class class1,
14787 enum reg_class class2,
14788 enum machine_mode mode)
14790 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
14793 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
14794 "class2 = %s, mode = %s\n",
14795 ret ? "true" : "false", reg_class_names[class1],
14796 reg_class_names[class2], GET_MODE_NAME (mode));
14801 /* Return the register class of a scratch register needed to copy IN into
14802 or out of a register in RCLASS in MODE. If it can be done directly,
14803 NO_REGS is returned. */
14805 static enum reg_class
14806 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
14811 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
14813 && MACHOPIC_INDIRECT
14817 /* We cannot copy a symbolic operand directly into anything
14818 other than BASE_REGS for TARGET_ELF. So indicate that a
14819 register from BASE_REGS is needed as an intermediate
14822 On Darwin, pic addresses require a load from memory, which
14823 needs a base register. */
14824 if (rclass != BASE_REGS
14825 && (GET_CODE (in) == SYMBOL_REF
14826 || GET_CODE (in) == HIGH
14827 || GET_CODE (in) == LABEL_REF
14828 || GET_CODE (in) == CONST))
14832 if (GET_CODE (in) == REG)
14834 regno = REGNO (in);
14835 if (regno >= FIRST_PSEUDO_REGISTER)
14837 regno = true_regnum (in);
14838 if (regno >= FIRST_PSEUDO_REGISTER)
14842 else if (GET_CODE (in) == SUBREG)
14844 regno = true_regnum (in);
14845 if (regno >= FIRST_PSEUDO_REGISTER)
14851 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
14853 if (rclass == GENERAL_REGS || rclass == BASE_REGS
14854 || (regno >= 0 && INT_REGNO_P (regno)))
14857 /* Constants, memory, and FP registers can go into FP registers. */
14858 if ((regno == -1 || FP_REGNO_P (regno))
14859 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
14860 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
14862 /* Memory, and FP/altivec registers can go into fp/altivec registers under
14865 && (regno == -1 || VSX_REGNO_P (regno))
14866 && VSX_REG_CLASS_P (rclass))
14869 /* Memory, and AltiVec registers can go into AltiVec registers. */
14870 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
14871 && rclass == ALTIVEC_REGS)
14874 /* We can copy among the CR registers. */
14875 if ((rclass == CR_REGS || rclass == CR0_REGS)
14876 && regno >= 0 && CR_REGNO_P (regno))
14879 /* Otherwise, we need GENERAL_REGS. */
14880 return GENERAL_REGS;
14883 /* Debug version of rs6000_secondary_reload_class. */
14884 static enum reg_class
14885 rs6000_debug_secondary_reload_class (enum reg_class rclass,
14886 enum machine_mode mode, rtx in)
14888 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
14890 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
14891 "mode = %s, input rtx:\n",
14892 reg_class_names[ret], reg_class_names[rclass],
14893 GET_MODE_NAME (mode));
14899 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
14902 rs6000_cannot_change_mode_class (enum machine_mode from,
14903 enum machine_mode to,
14904 enum reg_class rclass)
14906 unsigned from_size = GET_MODE_SIZE (from);
14907 unsigned to_size = GET_MODE_SIZE (to);
14909 if (from_size != to_size)
14911 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
14912 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
14913 && reg_classes_intersect_p (xclass, rclass));
14916 if (TARGET_E500_DOUBLE
14917 && ((((to) == DFmode) + ((from) == DFmode)) == 1
14918 || (((to) == TFmode) + ((from) == TFmode)) == 1
14919 || (((to) == DDmode) + ((from) == DDmode)) == 1
14920 || (((to) == TDmode) + ((from) == TDmode)) == 1
14921 || (((to) == DImode) + ((from) == DImode)) == 1))
14924 /* Since the VSX register set includes traditional floating point registers
14925 and altivec registers, just check for the size being different instead of
14926 trying to check whether the modes are vector modes. Otherwise it won't
14927 allow say DF and DI to change classes. */
14928 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
14929 return (from_size != 8 && from_size != 16);
14931 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
14932 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
14935 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
14936 && reg_classes_intersect_p (GENERAL_REGS, rclass))
14942 /* Debug version of rs6000_cannot_change_mode_class. */
14944 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
14945 enum machine_mode to,
14946 enum reg_class rclass)
14948 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
14951 "rs6000_cannot_change_mode_class, return %s, from = %s, "
14952 "to = %s, rclass = %s\n",
14953 ret ? "true" : "false",
14954 GET_MODE_NAME (from), GET_MODE_NAME (to),
14955 reg_class_names[rclass]);
14960 /* Given a comparison operation, return the bit number in CCR to test. We
14961 know this is a valid comparison.
14963 SCC_P is 1 if this is for an scc. That means that %D will have been
14964 used instead of %C, so the bits will be in different places.
14966 Return -1 if OP isn't a valid comparison for some reason. */
14969 ccr_bit (rtx op, int scc_p)
14971 enum rtx_code code = GET_CODE (op);
14972 enum machine_mode cc_mode;
14977 if (!COMPARISON_P (op))
14980 reg = XEXP (op, 0);
14982 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
14984 cc_mode = GET_MODE (reg);
14985 cc_regnum = REGNO (reg);
14986 base_bit = 4 * (cc_regnum - CR0_REGNO);
14988 validate_condition_mode (code, cc_mode);
14990 /* When generating a sCOND operation, only positive conditions are
14993 || code == EQ || code == GT || code == LT || code == UNORDERED
14994 || code == GTU || code == LTU);
14999 return scc_p ? base_bit + 3 : base_bit + 2;
15001 return base_bit + 2;
15002 case GT: case GTU: case UNLE:
15003 return base_bit + 1;
15004 case LT: case LTU: case UNGE:
15006 case ORDERED: case UNORDERED:
15007 return base_bit + 3;
15010 /* If scc, we will have done a cror to put the bit in the
15011 unordered position. So test that bit. For integer, this is ! LT
15012 unless this is an scc insn. */
15013 return scc_p ? base_bit + 3 : base_bit;
15016 return scc_p ? base_bit + 3 : base_bit + 1;
15019 gcc_unreachable ();
15023 /* Return the GOT register. */
15026 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
15028 /* The second flow pass currently (June 1999) can't update
15029 regs_ever_live without disturbing other parts of the compiler, so
15030 update it here to make the prolog/epilogue code happy. */
15031 if (!can_create_pseudo_p ()
15032 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
15033 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
15035 crtl->uses_pic_offset_table = 1;
15037 return pic_offset_table_rtx;
15040 static rs6000_stack_t stack_info;
15042 /* Function to init struct machine_function.
15043 This will be called, via a pointer variable,
15044 from push_function_context. */
15046 static struct machine_function *
15047 rs6000_init_machine_status (void)
15049 stack_info.reload_completed = 0;
15050 return ggc_alloc_cleared_machine_function ();
15053 /* These macros test for integers and extract the low-order bits. */
15055 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
15056 && GET_MODE (X) == VOIDmode)
15058 #define INT_LOWPART(X) \
15059 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
15062 extract_MB (rtx op)
15065 unsigned long val = INT_LOWPART (op);
15067 /* If the high bit is zero, the value is the first 1 bit we find
15069 if ((val & 0x80000000) == 0)
15071 gcc_assert (val & 0xffffffff);
15074 while (((val <<= 1) & 0x80000000) == 0)
15079 /* If the high bit is set and the low bit is not, or the mask is all
15080 1's, the value is zero. */
15081 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
15084 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15087 while (((val >>= 1) & 1) != 0)
15094 extract_ME (rtx op)
15097 unsigned long val = INT_LOWPART (op);
15099 /* If the low bit is zero, the value is the first 1 bit we find from
15101 if ((val & 1) == 0)
15103 gcc_assert (val & 0xffffffff);
15106 while (((val >>= 1) & 1) == 0)
15112 /* If the low bit is set and the high bit is not, or the mask is all
15113 1's, the value is 31. */
15114 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
15117 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15120 while (((val <<= 1) & 0x80000000) != 0)
15126 /* Locate some local-dynamic symbol still in use by this function
15127 so that we can print its name in some tls_ld pattern. */
15129 static const char *
15130 rs6000_get_some_local_dynamic_name (void)
15134 if (cfun->machine->some_ld_name)
15135 return cfun->machine->some_ld_name;
15137 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
15139 && for_each_rtx (&PATTERN (insn),
15140 rs6000_get_some_local_dynamic_name_1, 0))
15141 return cfun->machine->some_ld_name;
15143 gcc_unreachable ();
15146 /* Helper function for rs6000_get_some_local_dynamic_name. */
15149 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
15153 if (GET_CODE (x) == SYMBOL_REF)
15155 const char *str = XSTR (x, 0);
15156 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
15158 cfun->machine->some_ld_name = str;
15166 /* Write out a function code label. */
15169 rs6000_output_function_entry (FILE *file, const char *fname)
15171 if (fname[0] != '.')
15173 switch (DEFAULT_ABI)
15176 gcc_unreachable ();
15182 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
15191 RS6000_OUTPUT_BASENAME (file, fname);
15194 /* Print an operand. Recognize special options, documented below. */
15197 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
15198 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
15200 #define SMALL_DATA_RELOC "sda21"
15201 #define SMALL_DATA_REG 0
15205 print_operand (FILE *file, rtx x, int code)
15209 unsigned HOST_WIDE_INT uval;
15214 /* Write out an instruction after the call which may be replaced
15215 with glue code by the loader. This depends on the AIX version. */
15216 asm_fprintf (file, RS6000_CALL_GLUE);
15219 /* %a is output_address. */
15222 /* If X is a constant integer whose low-order 5 bits are zero,
15223 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
15224 in the AIX assembler where "sri" with a zero shift count
15225 writes a trash instruction. */
15226 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
15233 /* If constant, low-order 16 bits of constant, unsigned.
15234 Otherwise, write normally. */
15236 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
15238 print_operand (file, x, 0);
15242 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
15243 for 64-bit mask direction. */
15244 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
15247 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
15251 /* X is a CR register. Print the number of the GT bit of the CR. */
15252 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15253 output_operand_lossage ("invalid %%c value");
15255 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
15259 /* Like 'J' but get to the GT bit only. */
15260 gcc_assert (GET_CODE (x) == REG);
15262 /* Bit 1 is GT bit. */
15263 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
15265 /* Add one for shift count in rlinm for scc. */
15266 fprintf (file, "%d", i + 1);
15270 /* X is a CR register. Print the number of the EQ bit of the CR */
15271 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15272 output_operand_lossage ("invalid %%E value");
15274 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
15278 /* X is a CR register. Print the shift count needed to move it
15279 to the high-order four bits. */
15280 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15281 output_operand_lossage ("invalid %%f value");
15283 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
15287 /* Similar, but print the count for the rotate in the opposite
15289 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15290 output_operand_lossage ("invalid %%F value");
15292 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
15296 /* X is a constant integer. If it is negative, print "m",
15297 otherwise print "z". This is to make an aze or ame insn. */
15298 if (GET_CODE (x) != CONST_INT)
15299 output_operand_lossage ("invalid %%G value");
15300 else if (INTVAL (x) >= 0)
15307 /* If constant, output low-order five bits. Otherwise, write
15310 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
15312 print_operand (file, x, 0);
15316 /* If constant, output low-order six bits. Otherwise, write
15319 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
15321 print_operand (file, x, 0);
15325 /* Print `i' if this is a constant, else nothing. */
15331 /* Write the bit number in CCR for jump. */
15332 i = ccr_bit (x, 0);
15334 output_operand_lossage ("invalid %%j code");
15336 fprintf (file, "%d", i);
15340 /* Similar, but add one for shift count in rlinm for scc and pass
15341 scc flag to `ccr_bit'. */
15342 i = ccr_bit (x, 1);
15344 output_operand_lossage ("invalid %%J code");
15346 /* If we want bit 31, write a shift count of zero, not 32. */
15347 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15351 /* X must be a constant. Write the 1's complement of the
15354 output_operand_lossage ("invalid %%k value");
15356 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
15360 /* X must be a symbolic constant on ELF. Write an
15361 expression suitable for an 'addi' that adds in the low 16
15362 bits of the MEM. */
15363 if (GET_CODE (x) == CONST)
15365 if (GET_CODE (XEXP (x, 0)) != PLUS
15366 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
15367 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
15368 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
15369 output_operand_lossage ("invalid %%K value");
15371 print_operand_address (file, x);
15372 fputs ("@l", file);
15375 /* %l is output_asm_label. */
15378 /* Write second word of DImode or DFmode reference. Works on register
15379 or non-indexed memory only. */
15380 if (GET_CODE (x) == REG)
15381 fputs (reg_names[REGNO (x) + 1], file);
15382 else if (GET_CODE (x) == MEM)
15384 /* Handle possible auto-increment. Since it is pre-increment and
15385 we have already done it, we can just use an offset of word. */
15386 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15387 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15388 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15390 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15391 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15394 output_address (XEXP (adjust_address_nv (x, SImode,
15398 if (small_data_operand (x, GET_MODE (x)))
15399 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15400 reg_names[SMALL_DATA_REG]);
15405 /* MB value for a mask operand. */
15406 if (! mask_operand (x, SImode))
15407 output_operand_lossage ("invalid %%m value");
15409 fprintf (file, "%d", extract_MB (x));
15413 /* ME value for a mask operand. */
15414 if (! mask_operand (x, SImode))
15415 output_operand_lossage ("invalid %%M value");
15417 fprintf (file, "%d", extract_ME (x));
15420 /* %n outputs the negative of its operand. */
15423 /* Write the number of elements in the vector times 4. */
15424 if (GET_CODE (x) != PARALLEL)
15425 output_operand_lossage ("invalid %%N value");
15427 fprintf (file, "%d", XVECLEN (x, 0) * 4);
15431 /* Similar, but subtract 1 first. */
15432 if (GET_CODE (x) != PARALLEL)
15433 output_operand_lossage ("invalid %%O value");
15435 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
15439 /* X is a CONST_INT that is a power of two. Output the logarithm. */
15441 || INT_LOWPART (x) < 0
15442 || (i = exact_log2 (INT_LOWPART (x))) < 0)
15443 output_operand_lossage ("invalid %%p value");
15445 fprintf (file, "%d", i);
15449 /* The operand must be an indirect memory reference. The result
15450 is the register name. */
15451 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
15452 || REGNO (XEXP (x, 0)) >= 32)
15453 output_operand_lossage ("invalid %%P value");
15455 fputs (reg_names[REGNO (XEXP (x, 0))], file);
15459 /* This outputs the logical code corresponding to a boolean
15460 expression. The expression may have one or both operands
15461 negated (if one, only the first one). For condition register
15462 logical operations, it will also treat the negated
15463 CR codes as NOTs, but not handle NOTs of them. */
15465 const char *const *t = 0;
15467 enum rtx_code code = GET_CODE (x);
15468 static const char * const tbl[3][3] = {
15469 { "and", "andc", "nor" },
15470 { "or", "orc", "nand" },
15471 { "xor", "eqv", "xor" } };
15475 else if (code == IOR)
15477 else if (code == XOR)
15480 output_operand_lossage ("invalid %%q value");
15482 if (GET_CODE (XEXP (x, 0)) != NOT)
15486 if (GET_CODE (XEXP (x, 1)) == NOT)
15504 /* X is a CR register. Print the mask for `mtcrf'. */
15505 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15506 output_operand_lossage ("invalid %%R value");
15508 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
15512 /* Low 5 bits of 32 - value */
15514 output_operand_lossage ("invalid %%s value");
15516 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
15520 /* PowerPC64 mask position. All 0's is excluded.
15521 CONST_INT 32-bit mask is considered sign-extended so any
15522 transition must occur within the CONST_INT, not on the boundary. */
15523 if (! mask64_operand (x, DImode))
15524 output_operand_lossage ("invalid %%S value");
15526 uval = INT_LOWPART (x);
15528 if (uval & 1) /* Clear Left */
15530 #if HOST_BITS_PER_WIDE_INT > 64
15531 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15535 else /* Clear Right */
15538 #if HOST_BITS_PER_WIDE_INT > 64
15539 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15545 gcc_assert (i >= 0);
15546 fprintf (file, "%d", i);
15550 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
15551 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
15553 /* Bit 3 is OV bit. */
15554 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
15556 /* If we want bit 31, write a shift count of zero, not 32. */
15557 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15561 /* Print the symbolic name of a branch target register. */
15562 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
15563 && REGNO (x) != CTR_REGNO))
15564 output_operand_lossage ("invalid %%T value");
15565 else if (REGNO (x) == LR_REGNO)
15566 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
15568 fputs ("ctr", file);
15572 /* High-order 16 bits of constant for use in unsigned operand. */
15574 output_operand_lossage ("invalid %%u value");
15576 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15577 (INT_LOWPART (x) >> 16) & 0xffff);
15581 /* High-order 16 bits of constant for use in signed operand. */
15583 output_operand_lossage ("invalid %%v value");
15585 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15586 (INT_LOWPART (x) >> 16) & 0xffff);
15590 /* Print `u' if this has an auto-increment or auto-decrement. */
15591 if (GET_CODE (x) == MEM
15592 && (GET_CODE (XEXP (x, 0)) == PRE_INC
15593 || GET_CODE (XEXP (x, 0)) == PRE_DEC
15594 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
15599 /* Print the trap code for this operand. */
15600 switch (GET_CODE (x))
15603 fputs ("eq", file); /* 4 */
15606 fputs ("ne", file); /* 24 */
15609 fputs ("lt", file); /* 16 */
15612 fputs ("le", file); /* 20 */
15615 fputs ("gt", file); /* 8 */
15618 fputs ("ge", file); /* 12 */
15621 fputs ("llt", file); /* 2 */
15624 fputs ("lle", file); /* 6 */
15627 fputs ("lgt", file); /* 1 */
15630 fputs ("lge", file); /* 5 */
15633 gcc_unreachable ();
15638 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
15641 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
15642 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
15644 print_operand (file, x, 0);
15648 /* MB value for a PowerPC64 rldic operand. */
15649 val = (GET_CODE (x) == CONST_INT
15650 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
15655 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
15656 if ((val <<= 1) < 0)
15659 #if HOST_BITS_PER_WIDE_INT == 32
15660 if (GET_CODE (x) == CONST_INT && i >= 0)
15661 i += 32; /* zero-extend high-part was all 0's */
15662 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
15664 val = CONST_DOUBLE_LOW (x);
15670 for ( ; i < 64; i++)
15671 if ((val <<= 1) < 0)
15676 fprintf (file, "%d", i + 1);
15680 /* X is a FPR or Altivec register used in a VSX context. */
15681 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
15682 output_operand_lossage ("invalid %%x value");
15685 int reg = REGNO (x);
15686 int vsx_reg = (FP_REGNO_P (reg)
15688 : reg - FIRST_ALTIVEC_REGNO + 32);
15690 #ifdef TARGET_REGNAMES
15691 if (TARGET_REGNAMES)
15692 fprintf (file, "%%vs%d", vsx_reg);
15695 fprintf (file, "%d", vsx_reg);
15700 if (GET_CODE (x) == MEM
15701 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
15702 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
15703 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
15708 /* Like 'L', for third word of TImode */
15709 if (GET_CODE (x) == REG)
15710 fputs (reg_names[REGNO (x) + 2], file);
15711 else if (GET_CODE (x) == MEM)
15713 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15714 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15715 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15716 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15717 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15719 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
15720 if (small_data_operand (x, GET_MODE (x)))
15721 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15722 reg_names[SMALL_DATA_REG]);
15727 /* X is a SYMBOL_REF. Write out the name preceded by a
15728 period and without any trailing data in brackets. Used for function
15729 names. If we are configured for System V (or the embedded ABI) on
15730 the PowerPC, do not emit the period, since those systems do not use
15731 TOCs and the like. */
15732 gcc_assert (GET_CODE (x) == SYMBOL_REF);
15734 /* Mark the decl as referenced so that cgraph will output the
15736 if (SYMBOL_REF_DECL (x))
15737 mark_decl_referenced (SYMBOL_REF_DECL (x));
15739 /* For macho, check to see if we need a stub. */
15742 const char *name = XSTR (x, 0);
15744 if (darwin_emit_branch_islands
15745 && MACHOPIC_INDIRECT
15746 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
15747 name = machopic_indirection_name (x, /*stub_p=*/true);
15749 assemble_name (file, name);
15751 else if (!DOT_SYMBOLS)
15752 assemble_name (file, XSTR (x, 0));
15754 rs6000_output_function_entry (file, XSTR (x, 0));
15758 /* Like 'L', for last word of TImode. */
15759 if (GET_CODE (x) == REG)
15760 fputs (reg_names[REGNO (x) + 3], file);
15761 else if (GET_CODE (x) == MEM)
15763 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15764 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15765 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15766 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15767 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15769 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
15770 if (small_data_operand (x, GET_MODE (x)))
15771 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15772 reg_names[SMALL_DATA_REG]);
15776 /* Print AltiVec or SPE memory operand. */
15781 gcc_assert (GET_CODE (x) == MEM);
15785 /* Ugly hack because %y is overloaded. */
15786 if ((TARGET_SPE || TARGET_E500_DOUBLE)
15787 && (GET_MODE_SIZE (GET_MODE (x)) == 8
15788 || GET_MODE (x) == TFmode
15789 || GET_MODE (x) == TImode))
15791 /* Handle [reg]. */
15792 if (GET_CODE (tmp) == REG)
15794 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
15797 /* Handle [reg+UIMM]. */
15798 else if (GET_CODE (tmp) == PLUS &&
15799 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
15803 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
15805 x = INTVAL (XEXP (tmp, 1));
15806 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
15810 /* Fall through. Must be [reg+reg]. */
15812 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
15813 && GET_CODE (tmp) == AND
15814 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
15815 && INTVAL (XEXP (tmp, 1)) == -16)
15816 tmp = XEXP (tmp, 0);
15817 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
15818 && GET_CODE (tmp) == PRE_MODIFY)
15819 tmp = XEXP (tmp, 1);
15820 if (GET_CODE (tmp) == REG)
15821 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
15824 if (!GET_CODE (tmp) == PLUS
15825 || !REG_P (XEXP (tmp, 0))
15826 || !REG_P (XEXP (tmp, 1)))
15828 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
15832 if (REGNO (XEXP (tmp, 0)) == 0)
15833 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
15834 reg_names[ REGNO (XEXP (tmp, 0)) ]);
15836 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
15837 reg_names[ REGNO (XEXP (tmp, 1)) ]);
15843 if (GET_CODE (x) == REG)
15844 fprintf (file, "%s", reg_names[REGNO (x)]);
15845 else if (GET_CODE (x) == MEM)
15847 /* We need to handle PRE_INC and PRE_DEC here, since we need to
15848 know the width from the mode. */
15849 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
15850 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
15851 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
15852 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
15853 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
15854 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
15855 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15856 output_address (XEXP (XEXP (x, 0), 1));
15858 output_address (XEXP (x, 0));
15862 if (toc_relative_expr_p (x))
15863 /* This hack along with a corresponding hack in
15864 rs6000_output_addr_const_extra arranges to output addends
15865 where the assembler expects to find them. eg.
15866 (const (plus (unspec [symbol_ref ("x") tocrel]) 4))
15867 without this hack would be output as "x@toc+4". We
15869 output_addr_const (file, tocrel_base);
15871 output_addr_const (file, x);
15876 assemble_name (file, rs6000_get_some_local_dynamic_name ());
15880 output_operand_lossage ("invalid %%xn code");
15884 /* Print the address of an operand. */
15887 print_operand_address (FILE *file, rtx x)
15889 if (GET_CODE (x) == REG)
15890 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
15891 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
15892 || GET_CODE (x) == LABEL_REF)
15894 output_addr_const (file, x);
15895 if (small_data_operand (x, GET_MODE (x)))
15896 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15897 reg_names[SMALL_DATA_REG]);
15899 gcc_assert (!TARGET_TOC);
15901 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
15903 gcc_assert (REG_P (XEXP (x, 0)));
15904 if (REGNO (XEXP (x, 0)) == 0)
15905 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
15906 reg_names[ REGNO (XEXP (x, 0)) ]);
15908 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
15909 reg_names[ REGNO (XEXP (x, 1)) ]);
15911 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
15912 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
15913 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
15915 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15916 && CONSTANT_P (XEXP (x, 1)))
15918 fprintf (file, "lo16(");
15919 output_addr_const (file, XEXP (x, 1));
15920 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15923 else if (legitimate_constant_pool_address_p (x, QImode, true))
15925 /* This hack along with a corresponding hack in
15926 rs6000_output_addr_const_extra arranges to output addends
15927 where the assembler expects to find them. eg.
15929 . (const (plus (unspec [symbol_ref ("x") tocrel]) 8)))
15930 without this hack would be output as "x@toc+8@l(9)". We
15931 want "x+8@toc@l(9)". */
15932 output_addr_const (file, tocrel_base);
15933 if (GET_CODE (x) == LO_SUM)
15934 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15936 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
15939 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15940 && CONSTANT_P (XEXP (x, 1)))
15942 output_addr_const (file, XEXP (x, 1));
15943 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15947 gcc_unreachable ();
15950 /* Implement TARGET_OUTPUT_ADDR_CONST_EXTRA. */
15953 rs6000_output_addr_const_extra (FILE *file, rtx x)
15955 if (GET_CODE (x) == UNSPEC)
15956 switch (XINT (x, 1))
15958 case UNSPEC_TOCREL:
15959 gcc_assert (GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF);
15960 output_addr_const (file, XVECEXP (x, 0, 0));
15961 if (x == tocrel_base && tocrel_offset != const0_rtx)
15963 if (INTVAL (tocrel_offset) >= 0)
15964 fprintf (file, "+");
15965 output_addr_const (file, tocrel_offset);
15967 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
15970 assemble_name (file, toc_label_name);
15972 else if (TARGET_ELF)
15973 fputs ("@toc", file);
15977 case UNSPEC_MACHOPIC_OFFSET:
15978 output_addr_const (file, XVECEXP (x, 0, 0));
15980 machopic_output_function_base_name (file);
15987 /* Target hook for assembling integer objects. The PowerPC version has
15988 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
15989 is defined. It also needs to handle DI-mode objects on 64-bit
15993 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
15995 #ifdef RELOCATABLE_NEEDS_FIXUP
15996 /* Special handling for SI values. */
15997 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
15999 static int recurse = 0;
16001 /* For -mrelocatable, we mark all addresses that need to be fixed up
16002 in the .fixup section. */
16003 if (TARGET_RELOCATABLE
16004 && in_section != toc_section
16005 && in_section != text_section
16006 && !unlikely_text_section_p (in_section)
16008 && GET_CODE (x) != CONST_INT
16009 && GET_CODE (x) != CONST_DOUBLE
16015 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
16017 ASM_OUTPUT_LABEL (asm_out_file, buf);
16018 fprintf (asm_out_file, "\t.long\t(");
16019 output_addr_const (asm_out_file, x);
16020 fprintf (asm_out_file, ")@fixup\n");
16021 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
16022 ASM_OUTPUT_ALIGN (asm_out_file, 2);
16023 fprintf (asm_out_file, "\t.long\t");
16024 assemble_name (asm_out_file, buf);
16025 fprintf (asm_out_file, "\n\t.previous\n");
16029 /* Remove initial .'s to turn a -mcall-aixdesc function
16030 address into the address of the descriptor, not the function
16032 else if (GET_CODE (x) == SYMBOL_REF
16033 && XSTR (x, 0)[0] == '.'
16034 && DEFAULT_ABI == ABI_AIX)
16036 const char *name = XSTR (x, 0);
16037 while (*name == '.')
16040 fprintf (asm_out_file, "\t.long\t%s\n", name);
16044 #endif /* RELOCATABLE_NEEDS_FIXUP */
16045 return default_assemble_integer (x, size, aligned_p);
16048 #if defined (HAVE_GAS_HIDDEN) && !defined (TARGET_MACHO)
16049 /* Emit an assembler directive to set symbol visibility for DECL to
16050 VISIBILITY_TYPE. */
16053 rs6000_assemble_visibility (tree decl, int vis)
16055 /* Functions need to have their entry point symbol visibility set as
16056 well as their descriptor symbol visibility. */
16057 if (DEFAULT_ABI == ABI_AIX
16059 && TREE_CODE (decl) == FUNCTION_DECL)
16061 static const char * const visibility_types[] = {
16062 NULL, "internal", "hidden", "protected"
16065 const char *name, *type;
16067 name = ((* targetm.strip_name_encoding)
16068 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
16069 type = visibility_types[vis];
16071 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
16072 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
16075 default_assemble_visibility (decl, vis);
16080 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
16082 /* Reversal of FP compares takes care -- an ordered compare
16083 becomes an unordered compare and vice versa. */
16084 if (mode == CCFPmode
16085 && (!flag_finite_math_only
16086 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
16087 || code == UNEQ || code == LTGT))
16088 return reverse_condition_maybe_unordered (code);
16090 return reverse_condition (code);
16093 /* Generate a compare for CODE. Return a brand-new rtx that
16094 represents the result of the compare. */
16097 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
16099 enum machine_mode comp_mode;
16100 rtx compare_result;
16101 enum rtx_code code = GET_CODE (cmp);
16102 rtx op0 = XEXP (cmp, 0);
16103 rtx op1 = XEXP (cmp, 1);
16105 if (FLOAT_MODE_P (mode))
16106 comp_mode = CCFPmode;
16107 else if (code == GTU || code == LTU
16108 || code == GEU || code == LEU)
16109 comp_mode = CCUNSmode;
16110 else if ((code == EQ || code == NE)
16111 && GET_CODE (op0) == SUBREG
16112 && GET_CODE (op1) == SUBREG
16113 && SUBREG_PROMOTED_UNSIGNED_P (op0)
16114 && SUBREG_PROMOTED_UNSIGNED_P (op1))
16115 /* These are unsigned values, perhaps there will be a later
16116 ordering compare that can be shared with this one.
16117 Unfortunately we cannot detect the signedness of the operands
16118 for non-subregs. */
16119 comp_mode = CCUNSmode;
16121 comp_mode = CCmode;
16123 /* First, the compare. */
16124 compare_result = gen_reg_rtx (comp_mode);
16126 /* E500 FP compare instructions on the GPRs. Yuck! */
16127 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
16128 && FLOAT_MODE_P (mode))
16130 rtx cmp, or_result, compare_result2;
16131 enum machine_mode op_mode = GET_MODE (op0);
16133 if (op_mode == VOIDmode)
16134 op_mode = GET_MODE (op1);
16136 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
16137 This explains the following mess. */
16141 case EQ: case UNEQ: case NE: case LTGT:
16145 cmp = (flag_finite_math_only && !flag_trapping_math)
16146 ? gen_tstsfeq_gpr (compare_result, op0, op1)
16147 : gen_cmpsfeq_gpr (compare_result, op0, op1);
16151 cmp = (flag_finite_math_only && !flag_trapping_math)
16152 ? gen_tstdfeq_gpr (compare_result, op0, op1)
16153 : gen_cmpdfeq_gpr (compare_result, op0, op1);
16157 cmp = (flag_finite_math_only && !flag_trapping_math)
16158 ? gen_tsttfeq_gpr (compare_result, op0, op1)
16159 : gen_cmptfeq_gpr (compare_result, op0, op1);
16163 gcc_unreachable ();
16167 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
16171 cmp = (flag_finite_math_only && !flag_trapping_math)
16172 ? gen_tstsfgt_gpr (compare_result, op0, op1)
16173 : gen_cmpsfgt_gpr (compare_result, op0, op1);
16177 cmp = (flag_finite_math_only && !flag_trapping_math)
16178 ? gen_tstdfgt_gpr (compare_result, op0, op1)
16179 : gen_cmpdfgt_gpr (compare_result, op0, op1);
16183 cmp = (flag_finite_math_only && !flag_trapping_math)
16184 ? gen_tsttfgt_gpr (compare_result, op0, op1)
16185 : gen_cmptfgt_gpr (compare_result, op0, op1);
16189 gcc_unreachable ();
16193 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
16197 cmp = (flag_finite_math_only && !flag_trapping_math)
16198 ? gen_tstsflt_gpr (compare_result, op0, op1)
16199 : gen_cmpsflt_gpr (compare_result, op0, op1);
16203 cmp = (flag_finite_math_only && !flag_trapping_math)
16204 ? gen_tstdflt_gpr (compare_result, op0, op1)
16205 : gen_cmpdflt_gpr (compare_result, op0, op1);
16209 cmp = (flag_finite_math_only && !flag_trapping_math)
16210 ? gen_tsttflt_gpr (compare_result, op0, op1)
16211 : gen_cmptflt_gpr (compare_result, op0, op1);
16215 gcc_unreachable ();
16219 gcc_unreachable ();
16222 /* Synthesize LE and GE from LT/GT || EQ. */
16223 if (code == LE || code == GE || code == LEU || code == GEU)
16229 case LE: code = LT; break;
16230 case GE: code = GT; break;
16231 case LEU: code = LT; break;
16232 case GEU: code = GT; break;
16233 default: gcc_unreachable ();
16236 compare_result2 = gen_reg_rtx (CCFPmode);
16242 cmp = (flag_finite_math_only && !flag_trapping_math)
16243 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
16244 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
16248 cmp = (flag_finite_math_only && !flag_trapping_math)
16249 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
16250 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
16254 cmp = (flag_finite_math_only && !flag_trapping_math)
16255 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
16256 : gen_cmptfeq_gpr (compare_result2, op0, op1);
16260 gcc_unreachable ();
16264 /* OR them together. */
16265 or_result = gen_reg_rtx (CCFPmode);
16266 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
16268 compare_result = or_result;
16273 if (code == NE || code == LTGT)
16283 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
16284 CLOBBERs to match cmptf_internal2 pattern. */
16285 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
16286 && GET_MODE (op0) == TFmode
16287 && !TARGET_IEEEQUAD
16288 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
16289 emit_insn (gen_rtx_PARALLEL (VOIDmode,
16291 gen_rtx_SET (VOIDmode,
16293 gen_rtx_COMPARE (comp_mode, op0, op1)),
16294 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16295 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16296 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16297 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16298 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16299 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16300 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16301 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16302 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (Pmode)))));
16303 else if (GET_CODE (op1) == UNSPEC
16304 && XINT (op1, 1) == UNSPEC_SP_TEST)
16306 rtx op1b = XVECEXP (op1, 0, 0);
16307 comp_mode = CCEQmode;
16308 compare_result = gen_reg_rtx (CCEQmode);
16310 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
16312 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
16315 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
16316 gen_rtx_COMPARE (comp_mode, op0, op1)));
16319 /* Some kinds of FP comparisons need an OR operation;
16320 under flag_finite_math_only we don't bother. */
16321 if (FLOAT_MODE_P (mode)
16322 && !flag_finite_math_only
16323 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
16324 && (code == LE || code == GE
16325 || code == UNEQ || code == LTGT
16326 || code == UNGT || code == UNLT))
16328 enum rtx_code or1, or2;
16329 rtx or1_rtx, or2_rtx, compare2_rtx;
16330 rtx or_result = gen_reg_rtx (CCEQmode);
16334 case LE: or1 = LT; or2 = EQ; break;
16335 case GE: or1 = GT; or2 = EQ; break;
16336 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
16337 case LTGT: or1 = LT; or2 = GT; break;
16338 case UNGT: or1 = UNORDERED; or2 = GT; break;
16339 case UNLT: or1 = UNORDERED; or2 = LT; break;
16340 default: gcc_unreachable ();
16342 validate_condition_mode (or1, comp_mode);
16343 validate_condition_mode (or2, comp_mode);
16344 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
16345 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
16346 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
16347 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
16349 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
16351 compare_result = or_result;
16355 validate_condition_mode (code, GET_MODE (compare_result));
16357 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
16361 /* Emit the RTL for an sISEL pattern. */
16364 rs6000_emit_sISEL (enum machine_mode mode ATTRIBUTE_UNUSED, rtx operands[])
16366 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
16370 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
16373 enum machine_mode op_mode;
16374 enum rtx_code cond_code;
16375 rtx result = operands[0];
16377 if (TARGET_ISEL && (mode == SImode || mode == DImode))
16379 rs6000_emit_sISEL (mode, operands);
16383 condition_rtx = rs6000_generate_compare (operands[1], mode);
16384 cond_code = GET_CODE (condition_rtx);
16386 if (FLOAT_MODE_P (mode)
16387 && !TARGET_FPRS && TARGET_HARD_FLOAT)
16391 PUT_MODE (condition_rtx, SImode);
16392 t = XEXP (condition_rtx, 0);
16394 gcc_assert (cond_code == NE || cond_code == EQ);
16396 if (cond_code == NE)
16397 emit_insn (gen_e500_flip_gt_bit (t, t));
16399 emit_insn (gen_move_from_CR_gt_bit (result, t));
16403 if (cond_code == NE
16404 || cond_code == GE || cond_code == LE
16405 || cond_code == GEU || cond_code == LEU
16406 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
16408 rtx not_result = gen_reg_rtx (CCEQmode);
16409 rtx not_op, rev_cond_rtx;
16410 enum machine_mode cc_mode;
16412 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
16414 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
16415 SImode, XEXP (condition_rtx, 0), const0_rtx);
16416 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
16417 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
16418 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
16421 op_mode = GET_MODE (XEXP (operands[1], 0));
16422 if (op_mode == VOIDmode)
16423 op_mode = GET_MODE (XEXP (operands[1], 1));
16425 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
16427 PUT_MODE (condition_rtx, DImode);
16428 convert_move (result, condition_rtx, 0);
16432 PUT_MODE (condition_rtx, SImode);
16433 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
16437 /* Emit a branch of kind CODE to location LOC. */
16440 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
16442 rtx condition_rtx, loc_ref;
16444 condition_rtx = rs6000_generate_compare (operands[0], mode);
16445 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
16446 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
16447 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
16448 loc_ref, pc_rtx)));
16451 /* Return the string to output a conditional branch to LABEL, which is
16452 the operand number of the label, or -1 if the branch is really a
16453 conditional return.
16455 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
16456 condition code register and its mode specifies what kind of
16457 comparison we made.
16459 REVERSED is nonzero if we should reverse the sense of the comparison.
16461 INSN is the insn. */
16464 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
16466 static char string[64];
16467 enum rtx_code code = GET_CODE (op);
16468 rtx cc_reg = XEXP (op, 0);
16469 enum machine_mode mode = GET_MODE (cc_reg);
16470 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
16471 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
16472 int really_reversed = reversed ^ need_longbranch;
16478 validate_condition_mode (code, mode);
16480 /* Work out which way this really branches. We could use
16481 reverse_condition_maybe_unordered here always but this
16482 makes the resulting assembler clearer. */
16483 if (really_reversed)
16485 /* Reversal of FP compares takes care -- an ordered compare
16486 becomes an unordered compare and vice versa. */
16487 if (mode == CCFPmode)
16488 code = reverse_condition_maybe_unordered (code);
16490 code = reverse_condition (code);
16493 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
16495 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
16500 /* Opposite of GT. */
16509 gcc_unreachable ();
16515 /* Not all of these are actually distinct opcodes, but
16516 we distinguish them for clarity of the resulting assembler. */
16517 case NE: case LTGT:
16518 ccode = "ne"; break;
16519 case EQ: case UNEQ:
16520 ccode = "eq"; break;
16522 ccode = "ge"; break;
16523 case GT: case GTU: case UNGT:
16524 ccode = "gt"; break;
16526 ccode = "le"; break;
16527 case LT: case LTU: case UNLT:
16528 ccode = "lt"; break;
16529 case UNORDERED: ccode = "un"; break;
16530 case ORDERED: ccode = "nu"; break;
16531 case UNGE: ccode = "nl"; break;
16532 case UNLE: ccode = "ng"; break;
16534 gcc_unreachable ();
16537 /* Maybe we have a guess as to how likely the branch is.
16538 The old mnemonics don't have a way to specify this information. */
16540 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
16541 if (note != NULL_RTX)
16543 /* PROB is the difference from 50%. */
16544 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
16546 /* Only hint for highly probable/improbable branches on newer
16547 cpus as static prediction overrides processor dynamic
16548 prediction. For older cpus we may as well always hint, but
16549 assume not taken for branches that are very close to 50% as a
16550 mispredicted taken branch is more expensive than a
16551 mispredicted not-taken branch. */
16552 if (rs6000_always_hint
16553 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
16554 && br_prob_note_reliable_p (note)))
16556 if (abs (prob) > REG_BR_PROB_BASE / 20
16557 && ((prob > 0) ^ need_longbranch))
16565 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
16567 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
16569 /* We need to escape any '%' characters in the reg_names string.
16570 Assume they'd only be the first character.... */
16571 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
16573 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
16577 /* If the branch distance was too far, we may have to use an
16578 unconditional branch to go the distance. */
16579 if (need_longbranch)
16580 s += sprintf (s, ",$+8\n\tb %s", label);
16582 s += sprintf (s, ",%s", label);
16588 /* Return the string to flip the GT bit on a CR. */
16590 output_e500_flip_gt_bit (rtx dst, rtx src)
16592 static char string[64];
16595 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
16596 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
16599 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
16600 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
16602 sprintf (string, "crnot %d,%d", a, b);
16606 /* Return insn for VSX or Altivec comparisons. */
16609 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
16612 enum machine_mode mode = GET_MODE (op0);
16620 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
16626 mask = gen_reg_rtx (mode);
16627 emit_insn (gen_rtx_SET (VOIDmode,
16629 gen_rtx_fmt_ee (code, mode, op0, op1)));
16636 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
16637 DMODE is expected destination mode. This is a recursive function. */
16640 rs6000_emit_vector_compare (enum rtx_code rcode,
16642 enum machine_mode dmode)
16645 bool swap_operands = false;
16646 bool try_again = false;
16648 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
16649 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
16651 /* See if the comparison works as is. */
16652 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16660 swap_operands = true;
16665 swap_operands = true;
16673 /* Invert condition and try again.
16674 e.g., A != B becomes ~(A==B). */
16676 enum rtx_code rev_code;
16677 enum insn_code nor_code;
16680 rev_code = reverse_condition_maybe_unordered (rcode);
16681 if (rev_code == UNKNOWN)
16684 nor_code = optab_handler (one_cmpl_optab, dmode);
16685 if (nor_code == CODE_FOR_nothing)
16688 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
16692 mask = gen_reg_rtx (dmode);
16693 emit_insn (GEN_FCN (nor_code) (mask, mask2));
16701 /* Try GT/GTU/LT/LTU OR EQ */
16704 enum insn_code ior_code;
16705 enum rtx_code new_code;
16726 gcc_unreachable ();
16729 ior_code = optab_handler (ior_optab, dmode);
16730 if (ior_code == CODE_FOR_nothing)
16733 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
16737 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
16741 mask = gen_reg_rtx (dmode);
16742 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
16760 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16765 /* You only get two chances. */
16769 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
16770 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
16771 operands for the relation operation COND. */
16774 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
16775 rtx cond, rtx cc_op0, rtx cc_op1)
16777 enum machine_mode dest_mode = GET_MODE (dest);
16778 enum rtx_code rcode = GET_CODE (cond);
16779 enum machine_mode cc_mode = CCmode;
16783 bool invert_move = false;
16785 if (VECTOR_UNIT_NONE_P (dest_mode))
16790 /* Swap operands if we can, and fall back to doing the operation as
16791 specified, and doing a NOR to invert the test. */
16797 /* Invert condition and try again.
16798 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
16799 invert_move = true;
16800 rcode = reverse_condition_maybe_unordered (rcode);
16801 if (rcode == UNKNOWN)
16805 /* Mark unsigned tests with CCUNSmode. */
16810 cc_mode = CCUNSmode;
16817 /* Get the vector mask for the given relational operations. */
16818 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
16826 op_true = op_false;
16830 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, CONST0_RTX (dest_mode));
16831 emit_insn (gen_rtx_SET (VOIDmode,
16833 gen_rtx_IF_THEN_ELSE (dest_mode,
16840 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
16841 operands of the last comparison is nonzero/true, FALSE_COND if it
16842 is zero/false. Return 0 if the hardware has no such operation. */
16845 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
16847 enum rtx_code code = GET_CODE (op);
16848 rtx op0 = XEXP (op, 0);
16849 rtx op1 = XEXP (op, 1);
16850 REAL_VALUE_TYPE c1;
16851 enum machine_mode compare_mode = GET_MODE (op0);
16852 enum machine_mode result_mode = GET_MODE (dest);
16854 bool is_against_zero;
16856 /* These modes should always match. */
16857 if (GET_MODE (op1) != compare_mode
16858 /* In the isel case however, we can use a compare immediate, so
16859 op1 may be a small constant. */
16860 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
16862 if (GET_MODE (true_cond) != result_mode)
16864 if (GET_MODE (false_cond) != result_mode)
16867 /* First, work out if the hardware can do this at all, or
16868 if it's too slow.... */
16869 if (!FLOAT_MODE_P (compare_mode))
16872 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
16875 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
16876 && SCALAR_FLOAT_MODE_P (compare_mode))
16879 is_against_zero = op1 == CONST0_RTX (compare_mode);
16881 /* A floating-point subtract might overflow, underflow, or produce
16882 an inexact result, thus changing the floating-point flags, so it
16883 can't be generated if we care about that. It's safe if one side
16884 of the construct is zero, since then no subtract will be
16886 if (SCALAR_FLOAT_MODE_P (compare_mode)
16887 && flag_trapping_math && ! is_against_zero)
16890 /* Eliminate half of the comparisons by switching operands, this
16891 makes the remaining code simpler. */
16892 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
16893 || code == LTGT || code == LT || code == UNLE)
16895 code = reverse_condition_maybe_unordered (code);
16897 true_cond = false_cond;
16901 /* UNEQ and LTGT take four instructions for a comparison with zero,
16902 it'll probably be faster to use a branch here too. */
16903 if (code == UNEQ && HONOR_NANS (compare_mode))
16906 if (GET_CODE (op1) == CONST_DOUBLE)
16907 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
16909 /* We're going to try to implement comparisons by performing
16910 a subtract, then comparing against zero. Unfortunately,
16911 Inf - Inf is NaN which is not zero, and so if we don't
16912 know that the operand is finite and the comparison
16913 would treat EQ different to UNORDERED, we can't do it. */
16914 if (HONOR_INFINITIES (compare_mode)
16915 && code != GT && code != UNGE
16916 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
16917 /* Constructs of the form (a OP b ? a : b) are safe. */
16918 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
16919 || (! rtx_equal_p (op0, true_cond)
16920 && ! rtx_equal_p (op1, true_cond))))
16923 /* At this point we know we can use fsel. */
16925 /* Reduce the comparison to a comparison against zero. */
16926 if (! is_against_zero)
16928 temp = gen_reg_rtx (compare_mode);
16929 emit_insn (gen_rtx_SET (VOIDmode, temp,
16930 gen_rtx_MINUS (compare_mode, op0, op1)));
16932 op1 = CONST0_RTX (compare_mode);
16935 /* If we don't care about NaNs we can reduce some of the comparisons
16936 down to faster ones. */
16937 if (! HONOR_NANS (compare_mode))
16943 true_cond = false_cond;
16956 /* Now, reduce everything down to a GE. */
16963 temp = gen_reg_rtx (compare_mode);
16964 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16969 temp = gen_reg_rtx (compare_mode);
16970 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
16975 temp = gen_reg_rtx (compare_mode);
16976 emit_insn (gen_rtx_SET (VOIDmode, temp,
16977 gen_rtx_NEG (compare_mode,
16978 gen_rtx_ABS (compare_mode, op0))));
16983 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
16984 temp = gen_reg_rtx (result_mode);
16985 emit_insn (gen_rtx_SET (VOIDmode, temp,
16986 gen_rtx_IF_THEN_ELSE (result_mode,
16987 gen_rtx_GE (VOIDmode,
16989 true_cond, false_cond)));
16990 false_cond = true_cond;
16993 temp = gen_reg_rtx (compare_mode);
16994 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16999 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
17000 temp = gen_reg_rtx (result_mode);
17001 emit_insn (gen_rtx_SET (VOIDmode, temp,
17002 gen_rtx_IF_THEN_ELSE (result_mode,
17003 gen_rtx_GE (VOIDmode,
17005 true_cond, false_cond)));
17006 true_cond = false_cond;
17009 temp = gen_reg_rtx (compare_mode);
17010 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17015 gcc_unreachable ();
17018 emit_insn (gen_rtx_SET (VOIDmode, dest,
17019 gen_rtx_IF_THEN_ELSE (result_mode,
17020 gen_rtx_GE (VOIDmode,
17022 true_cond, false_cond)));
17026 /* Same as above, but for ints (isel). */
17029 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
17031 rtx condition_rtx, cr;
17032 enum machine_mode mode = GET_MODE (dest);
17033 enum rtx_code cond_code;
17034 rtx (*isel_func) (rtx, rtx, rtx, rtx, rtx);
17037 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
17040 /* We still have to do the compare, because isel doesn't do a
17041 compare, it just looks at the CRx bits set by a previous compare
17043 condition_rtx = rs6000_generate_compare (op, mode);
17044 cond_code = GET_CODE (condition_rtx);
17045 cr = XEXP (condition_rtx, 0);
17046 signedp = GET_MODE (cr) == CCmode;
17048 isel_func = (mode == SImode
17049 ? (signedp ? gen_isel_signed_si : gen_isel_unsigned_si)
17050 : (signedp ? gen_isel_signed_di : gen_isel_unsigned_di));
17054 case LT: case GT: case LTU: case GTU: case EQ:
17055 /* isel handles these directly. */
17059 /* We need to swap the sense of the comparison. */
17062 true_cond = false_cond;
17064 PUT_CODE (condition_rtx, reverse_condition (cond_code));
17069 false_cond = force_reg (mode, false_cond);
17070 if (true_cond != const0_rtx)
17071 true_cond = force_reg (mode, true_cond);
17073 emit_insn (isel_func (dest, condition_rtx, true_cond, false_cond, cr));
17079 output_isel (rtx *operands)
17081 enum rtx_code code;
17083 code = GET_CODE (operands[1]);
17085 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
17087 gcc_assert (GET_CODE (operands[2]) == REG
17088 && GET_CODE (operands[3]) == REG);
17089 PUT_CODE (operands[1], reverse_condition (code));
17090 return "isel %0,%3,%2,%j1";
17093 return "isel %0,%2,%3,%j1";
17097 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
17099 enum machine_mode mode = GET_MODE (op0);
17103 /* VSX/altivec have direct min/max insns. */
17104 if ((code == SMAX || code == SMIN)
17105 && (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
17106 || (mode == SFmode && VECTOR_UNIT_VSX_P (DFmode))))
17108 emit_insn (gen_rtx_SET (VOIDmode,
17110 gen_rtx_fmt_ee (code, mode, op0, op1)));
17114 if (code == SMAX || code == SMIN)
17119 if (code == SMAX || code == UMAX)
17120 target = emit_conditional_move (dest, c, op0, op1, mode,
17121 op0, op1, mode, 0);
17123 target = emit_conditional_move (dest, c, op0, op1, mode,
17124 op1, op0, mode, 0);
17125 gcc_assert (target);
17126 if (target != dest)
17127 emit_move_insn (dest, target);
17130 /* Emit instructions to perform a load-reserved/store-conditional operation.
17131 The operation performed is an atomic
17132 (set M (CODE:MODE M OP))
17133 If not NULL, BEFORE is atomically set to M before the operation, and
17134 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
17135 If SYNC_P then a memory barrier is emitted before the operation.
17136 Either OP or M may be wrapped in a NOT operation. */
17139 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
17140 rtx m, rtx op, rtx before_param, rtx after_param,
17143 enum machine_mode used_mode;
17144 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
17147 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17148 rtx shift = NULL_RTX;
17151 emit_insn (gen_lwsync ());
17155 /* If this is smaller than SImode, we'll have to use SImode with
17157 if (mode == QImode || mode == HImode)
17161 if (MEM_ALIGN (used_m) >= 32)
17164 if (BYTES_BIG_ENDIAN)
17165 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
17167 shift = GEN_INT (ishift);
17168 used_m = change_address (used_m, SImode, 0);
17172 rtx addrSI, aligned_addr;
17173 int shift_mask = mode == QImode ? 0x18 : 0x10;
17175 addrSI = gen_lowpart_common (SImode,
17176 force_reg (Pmode, XEXP (used_m, 0)));
17177 addrSI = force_reg (SImode, addrSI);
17178 shift = gen_reg_rtx (SImode);
17180 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17181 GEN_INT (shift_mask)));
17182 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17184 aligned_addr = expand_binop (Pmode, and_optab,
17186 GEN_INT (-4), NULL_RTX,
17187 1, OPTAB_LIB_WIDEN);
17188 used_m = change_address (used_m, SImode, aligned_addr);
17189 set_mem_align (used_m, 32);
17191 /* It's safe to keep the old alias set of USED_M, because
17192 the operation is atomic and only affects the original
17196 if (GET_CODE (op) == NOT)
17198 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
17199 oldop = gen_rtx_NOT (SImode, oldop);
17202 oldop = lowpart_subreg (SImode, op, mode);
17208 newop = expand_binop (SImode, and_optab,
17209 oldop, GEN_INT (imask), NULL_RTX,
17210 1, OPTAB_LIB_WIDEN);
17211 emit_insn (gen_ashlsi3 (newop, newop, shift));
17214 case NOT: /* NAND */
17215 newop = expand_binop (SImode, ior_optab,
17216 oldop, GEN_INT (~imask), NULL_RTX,
17217 1, OPTAB_LIB_WIDEN);
17218 emit_insn (gen_rotlsi3 (newop, newop, shift));
17222 newop = expand_binop (SImode, ior_optab,
17223 oldop, GEN_INT (~imask), NULL_RTX,
17224 1, OPTAB_LIB_WIDEN);
17225 emit_insn (gen_rotlsi3 (newop, newop, shift));
17233 newop = expand_binop (SImode, and_optab,
17234 oldop, GEN_INT (imask), NULL_RTX,
17235 1, OPTAB_LIB_WIDEN);
17236 emit_insn (gen_ashlsi3 (newop, newop, shift));
17238 mask = gen_reg_rtx (SImode);
17239 emit_move_insn (mask, GEN_INT (imask));
17240 emit_insn (gen_ashlsi3 (mask, mask, shift));
17243 newop = gen_rtx_PLUS (SImode, m, newop);
17245 newop = gen_rtx_MINUS (SImode, m, newop);
17246 newop = gen_rtx_AND (SImode, newop, mask);
17247 newop = gen_rtx_IOR (SImode, newop,
17248 gen_rtx_AND (SImode,
17249 gen_rtx_NOT (SImode, mask),
17255 gcc_unreachable ();
17259 used_mode = SImode;
17260 before = gen_reg_rtx (used_mode);
17261 after = gen_reg_rtx (used_mode);
17266 before = before_param;
17267 after = after_param;
17269 if (before == NULL_RTX)
17270 before = gen_reg_rtx (used_mode);
17271 if (after == NULL_RTX)
17272 after = gen_reg_rtx (used_mode);
17275 if ((code == PLUS || code == MINUS)
17276 && used_mode != mode)
17277 the_op = op; /* Computed above. */
17278 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
17279 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
17280 else if (code == NOT)
17281 the_op = gen_rtx_fmt_ee (IOR, used_mode,
17282 gen_rtx_NOT (used_mode, m),
17283 gen_rtx_NOT (used_mode, op));
17285 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
17287 set_after = gen_rtx_SET (VOIDmode, after, the_op);
17288 set_before = gen_rtx_SET (VOIDmode, before, used_m);
17289 set_atomic = gen_rtx_SET (VOIDmode, used_m,
17290 gen_rtx_UNSPEC (used_mode,
17291 gen_rtvec (1, the_op),
17293 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
17295 if ((code == PLUS || code == MINUS) && used_mode != mode)
17296 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
17297 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
17299 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
17300 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
17302 /* Shift and mask the return values properly. */
17303 if (used_mode != mode && before_param)
17305 emit_insn (gen_lshrsi3 (before, before, shift));
17306 convert_move (before_param, before, 1);
17309 if (used_mode != mode && after_param)
17311 emit_insn (gen_lshrsi3 (after, after, shift));
17312 convert_move (after_param, after, 1);
17315 /* The previous sequence will end with a branch that's dependent on
17316 the conditional store, so placing an isync will ensure that no
17317 other instructions (especially, no load or store instructions)
17318 can start before the atomic operation completes. */
17320 emit_insn (gen_isync ());
17323 /* A subroutine of the atomic operation splitters. Jump to LABEL if
17324 COND is true. Mark the jump as unlikely to be taken. */
17327 emit_unlikely_jump (rtx cond, rtx label)
17329 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
17332 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
17333 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
17334 add_reg_note (x, REG_BR_PROB, very_unlikely);
17337 /* A subroutine of the atomic operation splitters. Emit a load-locked
17338 instruction in MODE. */
17341 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
17343 rtx (*fn) (rtx, rtx) = NULL;
17344 if (mode == SImode)
17345 fn = gen_load_locked_si;
17346 else if (mode == DImode)
17347 fn = gen_load_locked_di;
17348 emit_insn (fn (reg, mem));
17351 /* A subroutine of the atomic operation splitters. Emit a store-conditional
17352 instruction in MODE. */
17355 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
17357 rtx (*fn) (rtx, rtx, rtx) = NULL;
17358 if (mode == SImode)
17359 fn = gen_store_conditional_si;
17360 else if (mode == DImode)
17361 fn = gen_store_conditional_di;
17363 /* Emit sync before stwcx. to address PPC405 Erratum. */
17364 if (PPC405_ERRATUM77)
17365 emit_insn (gen_memory_barrier ());
17367 emit_insn (fn (res, mem, val));
17370 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
17371 to perform. MEM is the memory on which to operate. VAL is the second
17372 operand of the binary operator. BEFORE and AFTER are optional locations to
17373 return the value of MEM either before of after the operation. SCRATCH is
17374 a scratch register. */
17377 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
17378 rtx before, rtx after, rtx scratch)
17380 enum machine_mode mode = GET_MODE (mem);
17381 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17383 emit_insn (gen_lwsync ());
17385 label = gen_label_rtx ();
17386 emit_label (label);
17387 label = gen_rtx_LABEL_REF (VOIDmode, label);
17389 if (before == NULL_RTX)
17391 emit_load_locked (mode, before, mem);
17394 x = gen_rtx_IOR (mode,
17395 gen_rtx_NOT (mode, before),
17396 gen_rtx_NOT (mode, val));
17397 else if (code == AND)
17398 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
17400 x = gen_rtx_fmt_ee (code, mode, before, val);
17402 if (after != NULL_RTX)
17403 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
17404 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
17406 emit_store_conditional (mode, cond, mem, scratch);
17408 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17409 emit_unlikely_jump (x, label);
17411 emit_insn (gen_isync ());
17414 /* Expand an atomic compare and swap operation. MEM is the memory on which
17415 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
17416 value to be stored. SCRATCH is a scratch GPR. */
17419 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
17422 enum machine_mode mode = GET_MODE (mem);
17423 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17425 emit_insn (gen_lwsync ());
17427 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17428 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17429 emit_label (XEXP (label1, 0));
17431 emit_load_locked (mode, retval, mem);
17433 x = gen_rtx_COMPARE (CCmode, retval, oldval);
17434 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
17436 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17437 emit_unlikely_jump (x, label2);
17439 emit_move_insn (scratch, newval);
17440 emit_store_conditional (mode, cond, mem, scratch);
17442 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17443 emit_unlikely_jump (x, label1);
17445 emit_insn (gen_isync ());
17446 emit_label (XEXP (label2, 0));
17449 /* Expand an atomic test and set operation. MEM is the memory on which
17450 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
17453 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
17455 enum machine_mode mode = GET_MODE (mem);
17456 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17458 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17459 emit_label (XEXP (label, 0));
17461 emit_load_locked (mode, retval, mem);
17462 emit_move_insn (scratch, val);
17463 emit_store_conditional (mode, cond, mem, scratch);
17465 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17466 emit_unlikely_jump (x, label);
17468 emit_insn (gen_isync ());
17472 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
17474 enum machine_mode mode = GET_MODE (mem);
17475 rtx addrSI, align, wdst, shift, mask;
17476 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
17477 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17479 /* Shift amount for subword relative to aligned word. */
17480 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
17481 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
17482 shift = gen_reg_rtx (SImode);
17483 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17484 GEN_INT (shift_mask)));
17485 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17487 /* Shift and mask old value into position within word. */
17488 oldval = convert_modes (SImode, mode, oldval, 1);
17489 oldval = expand_binop (SImode, and_optab,
17490 oldval, GEN_INT (imask), NULL_RTX,
17491 1, OPTAB_LIB_WIDEN);
17492 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
17494 /* Shift and mask new value into position within word. */
17495 newval = convert_modes (SImode, mode, newval, 1);
17496 newval = expand_binop (SImode, and_optab,
17497 newval, GEN_INT (imask), NULL_RTX,
17498 1, OPTAB_LIB_WIDEN);
17499 emit_insn (gen_ashlsi3 (newval, newval, shift));
17501 /* Mask for insertion. */
17502 mask = gen_reg_rtx (SImode);
17503 emit_move_insn (mask, GEN_INT (imask));
17504 emit_insn (gen_ashlsi3 (mask, mask, shift));
17506 /* Address of aligned word containing subword. */
17507 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
17508 NULL_RTX, 1, OPTAB_LIB_WIDEN);
17509 mem = change_address (mem, SImode, align);
17510 set_mem_align (mem, 32);
17511 MEM_VOLATILE_P (mem) = 1;
17513 wdst = gen_reg_rtx (SImode);
17514 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
17515 oldval, newval, mem));
17517 /* Shift the result back. */
17518 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
17520 emit_move_insn (dst, gen_lowpart (mode, wdst));
17524 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
17525 rtx oldval, rtx newval, rtx mem,
17528 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17530 emit_insn (gen_lwsync ());
17531 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17532 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17533 emit_label (XEXP (label1, 0));
17535 emit_load_locked (SImode, scratch, mem);
17537 /* Mask subword within loaded value for comparison with oldval.
17538 Use UNSPEC_AND to avoid clobber.*/
17539 emit_insn (gen_rtx_SET (SImode, dest,
17540 gen_rtx_UNSPEC (SImode,
17541 gen_rtvec (2, scratch, mask),
17544 x = gen_rtx_COMPARE (CCmode, dest, oldval);
17545 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
17547 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17548 emit_unlikely_jump (x, label2);
17550 /* Clear subword within loaded value for insertion of new value. */
17551 emit_insn (gen_rtx_SET (SImode, scratch,
17552 gen_rtx_AND (SImode,
17553 gen_rtx_NOT (SImode, mask), scratch)));
17554 emit_insn (gen_iorsi3 (scratch, scratch, newval));
17555 emit_store_conditional (SImode, cond, mem, scratch);
17557 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17558 emit_unlikely_jump (x, label1);
17560 emit_insn (gen_isync ());
17561 emit_label (XEXP (label2, 0));
17565 /* Emit instructions to move SRC to DST. Called by splitters for
17566 multi-register moves. It will emit at most one instruction for
17567 each register that is accessed; that is, it won't emit li/lis pairs
17568 (or equivalent for 64-bit code). One of SRC or DST must be a hard
17572 rs6000_split_multireg_move (rtx dst, rtx src)
17574 /* The register number of the first register being moved. */
17576 /* The mode that is to be moved. */
17577 enum machine_mode mode;
17578 /* The mode that the move is being done in, and its size. */
17579 enum machine_mode reg_mode;
17581 /* The number of registers that will be moved. */
17584 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
17585 mode = GET_MODE (dst);
17586 nregs = hard_regno_nregs[reg][mode];
17587 if (FP_REGNO_P (reg))
17588 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
17589 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
17590 else if (ALTIVEC_REGNO_P (reg))
17591 reg_mode = V16QImode;
17592 else if (TARGET_E500_DOUBLE && mode == TFmode)
17595 reg_mode = word_mode;
17596 reg_mode_size = GET_MODE_SIZE (reg_mode);
17598 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
17600 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
17602 /* Move register range backwards, if we might have destructive
17605 for (i = nregs - 1; i >= 0; i--)
17606 emit_insn (gen_rtx_SET (VOIDmode,
17607 simplify_gen_subreg (reg_mode, dst, mode,
17608 i * reg_mode_size),
17609 simplify_gen_subreg (reg_mode, src, mode,
17610 i * reg_mode_size)));
17616 bool used_update = false;
17617 rtx restore_basereg = NULL_RTX;
17619 if (MEM_P (src) && INT_REGNO_P (reg))
17623 if (GET_CODE (XEXP (src, 0)) == PRE_INC
17624 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
17627 breg = XEXP (XEXP (src, 0), 0);
17628 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
17629 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
17630 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
17631 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17632 src = replace_equiv_address (src, breg);
17634 else if (! rs6000_offsettable_memref_p (src))
17636 if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)
17638 rtx basereg = XEXP (XEXP (src, 0), 0);
17641 rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0);
17642 emit_insn (gen_rtx_SET (VOIDmode, ndst,
17643 gen_rtx_MEM (reg_mode, XEXP (src, 0))));
17644 used_update = true;
17647 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17648 XEXP (XEXP (src, 0), 1)));
17649 src = replace_equiv_address (src, basereg);
17653 rtx basereg = gen_rtx_REG (Pmode, reg);
17654 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
17655 src = replace_equiv_address (src, basereg);
17659 breg = XEXP (src, 0);
17660 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
17661 breg = XEXP (breg, 0);
17663 /* If the base register we are using to address memory is
17664 also a destination reg, then change that register last. */
17666 && REGNO (breg) >= REGNO (dst)
17667 && REGNO (breg) < REGNO (dst) + nregs)
17668 j = REGNO (breg) - REGNO (dst);
17670 else if (MEM_P (dst) && INT_REGNO_P (reg))
17674 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
17675 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
17678 breg = XEXP (XEXP (dst, 0), 0);
17679 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
17680 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
17681 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
17683 /* We have to update the breg before doing the store.
17684 Use store with update, if available. */
17688 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17689 emit_insn (TARGET_32BIT
17690 ? (TARGET_POWERPC64
17691 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
17692 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
17693 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
17694 used_update = true;
17697 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17698 dst = replace_equiv_address (dst, breg);
17700 else if (!rs6000_offsettable_memref_p (dst)
17701 && GET_CODE (XEXP (dst, 0)) != LO_SUM)
17703 if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY)
17705 rtx basereg = XEXP (XEXP (dst, 0), 0);
17708 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17709 emit_insn (gen_rtx_SET (VOIDmode,
17710 gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc));
17711 used_update = true;
17714 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17715 XEXP (XEXP (dst, 0), 1)));
17716 dst = replace_equiv_address (dst, basereg);
17720 rtx basereg = XEXP (XEXP (dst, 0), 0);
17721 rtx offsetreg = XEXP (XEXP (dst, 0), 1);
17722 gcc_assert (GET_CODE (XEXP (dst, 0)) == PLUS
17724 && REG_P (offsetreg)
17725 && REGNO (basereg) != REGNO (offsetreg));
17726 if (REGNO (basereg) == 0)
17728 rtx tmp = offsetreg;
17729 offsetreg = basereg;
17732 emit_insn (gen_add3_insn (basereg, basereg, offsetreg));
17733 restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg);
17734 dst = replace_equiv_address (dst, basereg);
17737 else if (GET_CODE (XEXP (dst, 0)) != LO_SUM)
17738 gcc_assert (rs6000_offsettable_memref_p (dst));
17741 for (i = 0; i < nregs; i++)
17743 /* Calculate index to next subword. */
17748 /* If compiler already emitted move of first word by
17749 store with update, no need to do anything. */
17750 if (j == 0 && used_update)
17753 emit_insn (gen_rtx_SET (VOIDmode,
17754 simplify_gen_subreg (reg_mode, dst, mode,
17755 j * reg_mode_size),
17756 simplify_gen_subreg (reg_mode, src, mode,
17757 j * reg_mode_size)));
17759 if (restore_basereg != NULL_RTX)
17760 emit_insn (restore_basereg);
17765 /* This page contains routines that are used to determine what the
17766 function prologue and epilogue code will do and write them out. */
17768 /* Return the first fixed-point register that is required to be
17769 saved. 32 if none. */
17772 first_reg_to_save (void)
17776 /* Find lowest numbered live register. */
17777 for (first_reg = 13; first_reg <= 31; first_reg++)
17778 if (df_regs_ever_live_p (first_reg)
17779 && (! call_used_regs[first_reg]
17780 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
17781 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
17782 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
17783 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
17788 && crtl->uses_pic_offset_table
17789 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
17790 return RS6000_PIC_OFFSET_TABLE_REGNUM;
17796 /* Similar, for FP regs. */
17799 first_fp_reg_to_save (void)
17803 /* Find lowest numbered live register. */
17804 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
17805 if (df_regs_ever_live_p (first_reg))
17811 /* Similar, for AltiVec regs. */
17814 first_altivec_reg_to_save (void)
17818 /* Stack frame remains as is unless we are in AltiVec ABI. */
17819 if (! TARGET_ALTIVEC_ABI)
17820 return LAST_ALTIVEC_REGNO + 1;
17822 /* On Darwin, the unwind routines are compiled without
17823 TARGET_ALTIVEC, and use save_world to save/restore the
17824 altivec registers when necessary. */
17825 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17826 && ! TARGET_ALTIVEC)
17827 return FIRST_ALTIVEC_REGNO + 20;
17829 /* Find lowest numbered live register. */
17830 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
17831 if (df_regs_ever_live_p (i))
17837 /* Return a 32-bit mask of the AltiVec registers we need to set in
17838 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
17839 the 32-bit word is 0. */
17841 static unsigned int
17842 compute_vrsave_mask (void)
17844 unsigned int i, mask = 0;
17846 /* On Darwin, the unwind routines are compiled without
17847 TARGET_ALTIVEC, and use save_world to save/restore the
17848 call-saved altivec registers when necessary. */
17849 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17850 && ! TARGET_ALTIVEC)
17853 /* First, find out if we use _any_ altivec registers. */
17854 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
17855 if (df_regs_ever_live_p (i))
17856 mask |= ALTIVEC_REG_BIT (i);
17861 /* Next, remove the argument registers from the set. These must
17862 be in the VRSAVE mask set by the caller, so we don't need to add
17863 them in again. More importantly, the mask we compute here is
17864 used to generate CLOBBERs in the set_vrsave insn, and we do not
17865 wish the argument registers to die. */
17866 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
17867 mask &= ~ALTIVEC_REG_BIT (i);
17869 /* Similarly, remove the return value from the set. */
17872 diddle_return_value (is_altivec_return_reg, &yes);
17874 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
17880 /* For a very restricted set of circumstances, we can cut down the
17881 size of prologues/epilogues by calling our own save/restore-the-world
17885 compute_save_world_info (rs6000_stack_t *info_ptr)
17887 info_ptr->world_save_p = 1;
17888 info_ptr->world_save_p
17889 = (WORLD_SAVE_P (info_ptr)
17890 && DEFAULT_ABI == ABI_DARWIN
17891 && !cfun->has_nonlocal_label
17892 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
17893 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
17894 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
17895 && info_ptr->cr_save_p);
17897 /* This will not work in conjunction with sibcalls. Make sure there
17898 are none. (This check is expensive, but seldom executed.) */
17899 if (WORLD_SAVE_P (info_ptr))
17902 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
17903 if ( GET_CODE (insn) == CALL_INSN
17904 && SIBLING_CALL_P (insn))
17906 info_ptr->world_save_p = 0;
17911 if (WORLD_SAVE_P (info_ptr))
17913 /* Even if we're not touching VRsave, make sure there's room on the
17914 stack for it, if it looks like we're calling SAVE_WORLD, which
17915 will attempt to save it. */
17916 info_ptr->vrsave_size = 4;
17918 /* If we are going to save the world, we need to save the link register too. */
17919 info_ptr->lr_save_p = 1;
17921 /* "Save" the VRsave register too if we're saving the world. */
17922 if (info_ptr->vrsave_mask == 0)
17923 info_ptr->vrsave_mask = compute_vrsave_mask ();
17925 /* Because the Darwin register save/restore routines only handle
17926 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
17928 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
17929 && (info_ptr->first_altivec_reg_save
17930 >= FIRST_SAVED_ALTIVEC_REGNO));
17937 is_altivec_return_reg (rtx reg, void *xyes)
17939 bool *yes = (bool *) xyes;
17940 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
17945 /* Determine the strategy for savings/restoring registers. */
17948 SAVRES_MULTIPLE = 0x1,
17949 SAVE_INLINE_FPRS = 0x2,
17950 SAVE_INLINE_GPRS = 0x4,
17951 REST_INLINE_FPRS = 0x8,
17952 REST_INLINE_GPRS = 0x10,
17953 SAVE_NOINLINE_GPRS_SAVES_LR = 0x20,
17954 SAVE_NOINLINE_FPRS_SAVES_LR = 0x40,
17955 REST_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x80
17959 rs6000_savres_strategy (rs6000_stack_t *info,
17960 bool using_static_chain_p)
17964 if (TARGET_MULTIPLE
17965 && !TARGET_POWERPC64
17966 && !(TARGET_SPE_ABI && info->spe_64bit_regs_used)
17967 && info->first_gp_reg_save < 31
17968 && no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true))
17969 strategy |= SAVRES_MULTIPLE;
17971 if (crtl->calls_eh_return
17972 || cfun->machine->ra_need_lr
17973 || info->total_size > 32767)
17974 strategy |= (SAVE_INLINE_FPRS | REST_INLINE_FPRS
17975 | SAVE_INLINE_GPRS | REST_INLINE_GPRS);
17977 if (info->first_fp_reg_save == 64
17978 || FP_SAVE_INLINE (info->first_fp_reg_save)
17979 /* The out-of-line FP routines use double-precision stores;
17980 we can't use those routines if we don't have such stores. */
17981 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
17982 || !no_global_regs_above (info->first_fp_reg_save, /*gpr=*/false))
17983 strategy |= SAVE_INLINE_FPRS | REST_INLINE_FPRS;
17985 if (info->first_gp_reg_save == 32
17986 || GP_SAVE_INLINE (info->first_gp_reg_save)
17987 || !((strategy & SAVRES_MULTIPLE)
17988 || no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true)))
17989 strategy |= SAVE_INLINE_GPRS | REST_INLINE_GPRS;
17991 /* Don't bother to try to save things out-of-line if r11 is occupied
17992 by the static chain. It would require too much fiddling and the
17993 static chain is rarely used anyway. FPRs are saved w.r.t the stack
17994 pointer on Darwin. */
17995 if (using_static_chain_p)
17996 strategy |= (DEFAULT_ABI == ABI_DARWIN ? 0 : SAVE_INLINE_FPRS)
17997 | SAVE_INLINE_GPRS;
17999 /* If we are going to use store multiple, then don't even bother
18000 with the out-of-line routines, since the store-multiple
18001 instruction will always be smaller. */
18002 if ((strategy & SAVRES_MULTIPLE))
18003 strategy |= SAVE_INLINE_GPRS;
18005 /* The situation is more complicated with load multiple. We'd
18006 prefer to use the out-of-line routines for restores, since the
18007 "exit" out-of-line routines can handle the restore of LR and the
18008 frame teardown. However if doesn't make sense to use the
18009 out-of-line routine if that is the only reason we'd need to save
18010 LR, and we can't use the "exit" out-of-line gpr restore if we
18011 have saved some fprs; In those cases it is advantageous to use
18012 load multiple when available. */
18013 if ((strategy & SAVRES_MULTIPLE)
18014 && (!info->lr_save_p
18015 || info->first_fp_reg_save != 64))
18016 strategy |= REST_INLINE_GPRS;
18018 /* We can only use load multiple or the out-of-line routines to
18019 restore if we've used store multiple or out-of-line routines
18020 in the prologue, i.e. if we've saved all the registers from
18021 first_gp_reg_save. Otherwise, we risk loading garbage. */
18022 if ((strategy & (SAVE_INLINE_GPRS | SAVRES_MULTIPLE)) == SAVE_INLINE_GPRS)
18023 strategy |= REST_INLINE_GPRS;
18025 /* Saving CR interferes with the exit routines used on the SPE, so
18028 && info->spe_64bit_regs_used
18029 && info->cr_save_p)
18030 strategy |= REST_INLINE_GPRS;
18032 #ifdef POWERPC_LINUX
18035 if (!(strategy & SAVE_INLINE_FPRS))
18036 strategy |= SAVE_NOINLINE_FPRS_SAVES_LR;
18037 else if (!(strategy & SAVE_INLINE_GPRS)
18038 && info->first_fp_reg_save == 64)
18039 strategy |= SAVE_NOINLINE_GPRS_SAVES_LR;
18042 if (TARGET_AIX && !(strategy & REST_INLINE_FPRS))
18043 strategy |= REST_NOINLINE_FPRS_DOESNT_RESTORE_LR;
18045 if (TARGET_MACHO && !(strategy & SAVE_INLINE_FPRS))
18046 strategy |= SAVE_NOINLINE_FPRS_SAVES_LR;
18051 /* Calculate the stack information for the current function. This is
18052 complicated by having two separate calling sequences, the AIX calling
18053 sequence and the V.4 calling sequence.
18055 AIX (and Darwin/Mac OS X) stack frames look like:
18057 SP----> +---------------------------------------+
18058 | back chain to caller | 0 0
18059 +---------------------------------------+
18060 | saved CR | 4 8 (8-11)
18061 +---------------------------------------+
18063 +---------------------------------------+
18064 | reserved for compilers | 12 24
18065 +---------------------------------------+
18066 | reserved for binders | 16 32
18067 +---------------------------------------+
18068 | saved TOC pointer | 20 40
18069 +---------------------------------------+
18070 | Parameter save area (P) | 24 48
18071 +---------------------------------------+
18072 | Alloca space (A) | 24+P etc.
18073 +---------------------------------------+
18074 | Local variable space (L) | 24+P+A
18075 +---------------------------------------+
18076 | Float/int conversion temporary (X) | 24+P+A+L
18077 +---------------------------------------+
18078 | Save area for AltiVec registers (W) | 24+P+A+L+X
18079 +---------------------------------------+
18080 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
18081 +---------------------------------------+
18082 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
18083 +---------------------------------------+
18084 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
18085 +---------------------------------------+
18086 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
18087 +---------------------------------------+
18088 old SP->| back chain to caller's caller |
18089 +---------------------------------------+
18091 The required alignment for AIX configurations is two words (i.e., 8
18095 V.4 stack frames look like:
18097 SP----> +---------------------------------------+
18098 | back chain to caller | 0
18099 +---------------------------------------+
18100 | caller's saved LR | 4
18101 +---------------------------------------+
18102 | Parameter save area (P) | 8
18103 +---------------------------------------+
18104 | Alloca space (A) | 8+P
18105 +---------------------------------------+
18106 | Varargs save area (V) | 8+P+A
18107 +---------------------------------------+
18108 | Local variable space (L) | 8+P+A+V
18109 +---------------------------------------+
18110 | Float/int conversion temporary (X) | 8+P+A+V+L
18111 +---------------------------------------+
18112 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
18113 +---------------------------------------+
18114 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
18115 +---------------------------------------+
18116 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
18117 +---------------------------------------+
18118 | SPE: area for 64-bit GP registers |
18119 +---------------------------------------+
18120 | SPE alignment padding |
18121 +---------------------------------------+
18122 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
18123 +---------------------------------------+
18124 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
18125 +---------------------------------------+
18126 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
18127 +---------------------------------------+
18128 old SP->| back chain to caller's caller |
18129 +---------------------------------------+
18131 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
18132 given. (But note below and in sysv4.h that we require only 8 and
18133 may round up the size of our stack frame anyways. The historical
18134 reason is early versions of powerpc-linux which didn't properly
18135 align the stack at program startup. A happy side-effect is that
18136 -mno-eabi libraries can be used with -meabi programs.)
18138 The EABI configuration defaults to the V.4 layout. However,
18139 the stack alignment requirements may differ. If -mno-eabi is not
18140 given, the required stack alignment is 8 bytes; if -mno-eabi is
18141 given, the required alignment is 16 bytes. (But see V.4 comment
18144 #ifndef ABI_STACK_BOUNDARY
18145 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
18148 static rs6000_stack_t *
18149 rs6000_stack_info (void)
18151 rs6000_stack_t *info_ptr = &stack_info;
18152 int reg_size = TARGET_32BIT ? 4 : 8;
18156 HOST_WIDE_INT non_fixed_size;
18157 bool using_static_chain_p;
18159 if (reload_completed && info_ptr->reload_completed)
18162 memset (info_ptr, 0, sizeof (*info_ptr));
18163 info_ptr->reload_completed = reload_completed;
18167 /* Cache value so we don't rescan instruction chain over and over. */
18168 if (cfun->machine->insn_chain_scanned_p == 0)
18169 cfun->machine->insn_chain_scanned_p
18170 = spe_func_has_64bit_regs_p () + 1;
18171 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
18174 /* Select which calling sequence. */
18175 info_ptr->abi = DEFAULT_ABI;
18177 /* Calculate which registers need to be saved & save area size. */
18178 info_ptr->first_gp_reg_save = first_reg_to_save ();
18179 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
18180 even if it currently looks like we won't. Reload may need it to
18181 get at a constant; if so, it will have already created a constant
18182 pool entry for it. */
18183 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
18184 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
18185 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
18186 && crtl->uses_const_pool
18187 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
18188 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
18190 first_gp = info_ptr->first_gp_reg_save;
18192 info_ptr->gp_size = reg_size * (32 - first_gp);
18194 /* For the SPE, we have an additional upper 32-bits on each GPR.
18195 Ideally we should save the entire 64-bits only when the upper
18196 half is used in SIMD instructions. Since we only record
18197 registers live (not the size they are used in), this proves
18198 difficult because we'd have to traverse the instruction chain at
18199 the right time, taking reload into account. This is a real pain,
18200 so we opt to save the GPRs in 64-bits always if but one register
18201 gets used in 64-bits. Otherwise, all the registers in the frame
18202 get saved in 32-bits.
18204 So... since when we save all GPRs (except the SP) in 64-bits, the
18205 traditional GP save area will be empty. */
18206 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18207 info_ptr->gp_size = 0;
18209 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
18210 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
18212 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
18213 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
18214 - info_ptr->first_altivec_reg_save);
18216 /* Does this function call anything? */
18217 info_ptr->calls_p = (! current_function_is_leaf
18218 || cfun->machine->ra_needs_full_frame);
18220 /* Determine if we need to save the condition code registers. */
18221 if (df_regs_ever_live_p (CR2_REGNO)
18222 || df_regs_ever_live_p (CR3_REGNO)
18223 || df_regs_ever_live_p (CR4_REGNO))
18225 info_ptr->cr_save_p = 1;
18226 if (DEFAULT_ABI == ABI_V4)
18227 info_ptr->cr_size = reg_size;
18230 /* If the current function calls __builtin_eh_return, then we need
18231 to allocate stack space for registers that will hold data for
18232 the exception handler. */
18233 if (crtl->calls_eh_return)
18236 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
18239 /* SPE saves EH registers in 64-bits. */
18240 ehrd_size = i * (TARGET_SPE_ABI
18241 && info_ptr->spe_64bit_regs_used != 0
18242 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
18247 /* Determine various sizes. */
18248 info_ptr->reg_size = reg_size;
18249 info_ptr->fixed_size = RS6000_SAVE_AREA;
18250 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
18251 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
18252 TARGET_ALTIVEC ? 16 : 8);
18253 if (FRAME_GROWS_DOWNWARD)
18254 info_ptr->vars_size
18255 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
18256 + info_ptr->parm_size,
18257 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
18258 - (info_ptr->fixed_size + info_ptr->vars_size
18259 + info_ptr->parm_size);
18261 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18262 info_ptr->spe_gp_size = 8 * (32 - first_gp);
18264 info_ptr->spe_gp_size = 0;
18266 if (TARGET_ALTIVEC_ABI)
18267 info_ptr->vrsave_mask = compute_vrsave_mask ();
18269 info_ptr->vrsave_mask = 0;
18271 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
18272 info_ptr->vrsave_size = 4;
18274 info_ptr->vrsave_size = 0;
18276 compute_save_world_info (info_ptr);
18278 /* Calculate the offsets. */
18279 switch (DEFAULT_ABI)
18283 gcc_unreachable ();
18287 info_ptr->fp_save_offset = - info_ptr->fp_size;
18288 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18290 if (TARGET_ALTIVEC_ABI)
18292 info_ptr->vrsave_save_offset
18293 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
18295 /* Align stack so vector save area is on a quadword boundary.
18296 The padding goes above the vectors. */
18297 if (info_ptr->altivec_size != 0)
18298 info_ptr->altivec_padding_size
18299 = info_ptr->vrsave_save_offset & 0xF;
18301 info_ptr->altivec_padding_size = 0;
18303 info_ptr->altivec_save_offset
18304 = info_ptr->vrsave_save_offset
18305 - info_ptr->altivec_padding_size
18306 - info_ptr->altivec_size;
18307 gcc_assert (info_ptr->altivec_size == 0
18308 || info_ptr->altivec_save_offset % 16 == 0);
18310 /* Adjust for AltiVec case. */
18311 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
18314 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
18315 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
18316 info_ptr->lr_save_offset = 2*reg_size;
18320 info_ptr->fp_save_offset = - info_ptr->fp_size;
18321 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18322 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
18324 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18326 /* Align stack so SPE GPR save area is aligned on a
18327 double-word boundary. */
18328 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
18329 info_ptr->spe_padding_size
18330 = 8 - (-info_ptr->cr_save_offset % 8);
18332 info_ptr->spe_padding_size = 0;
18334 info_ptr->spe_gp_save_offset
18335 = info_ptr->cr_save_offset
18336 - info_ptr->spe_padding_size
18337 - info_ptr->spe_gp_size;
18339 /* Adjust for SPE case. */
18340 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
18342 else if (TARGET_ALTIVEC_ABI)
18344 info_ptr->vrsave_save_offset
18345 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
18347 /* Align stack so vector save area is on a quadword boundary. */
18348 if (info_ptr->altivec_size != 0)
18349 info_ptr->altivec_padding_size
18350 = 16 - (-info_ptr->vrsave_save_offset % 16);
18352 info_ptr->altivec_padding_size = 0;
18354 info_ptr->altivec_save_offset
18355 = info_ptr->vrsave_save_offset
18356 - info_ptr->altivec_padding_size
18357 - info_ptr->altivec_size;
18359 /* Adjust for AltiVec case. */
18360 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
18363 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
18364 info_ptr->ehrd_offset -= ehrd_size;
18365 info_ptr->lr_save_offset = reg_size;
18369 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
18370 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
18371 + info_ptr->gp_size
18372 + info_ptr->altivec_size
18373 + info_ptr->altivec_padding_size
18374 + info_ptr->spe_gp_size
18375 + info_ptr->spe_padding_size
18377 + info_ptr->cr_size
18378 + info_ptr->vrsave_size,
18381 non_fixed_size = (info_ptr->vars_size
18382 + info_ptr->parm_size
18383 + info_ptr->save_size);
18385 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
18386 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
18388 /* Determine if we need to save the link register. */
18389 if (info_ptr->calls_p
18390 || (DEFAULT_ABI == ABI_AIX
18392 && !TARGET_PROFILE_KERNEL)
18393 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
18394 #ifdef TARGET_RELOCATABLE
18395 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
18397 || rs6000_ra_ever_killed ())
18398 info_ptr->lr_save_p = 1;
18400 using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
18401 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
18402 && call_used_regs[STATIC_CHAIN_REGNUM]);
18403 info_ptr->savres_strategy = rs6000_savres_strategy (info_ptr,
18404 using_static_chain_p);
18406 if (!(info_ptr->savres_strategy & SAVE_INLINE_GPRS)
18407 || !(info_ptr->savres_strategy & SAVE_INLINE_FPRS)
18408 || !(info_ptr->savres_strategy & REST_INLINE_GPRS)
18409 || !(info_ptr->savres_strategy & REST_INLINE_FPRS))
18410 info_ptr->lr_save_p = 1;
18412 if (info_ptr->lr_save_p)
18413 df_set_regs_ever_live (LR_REGNO, true);
18415 /* Determine if we need to allocate any stack frame:
18417 For AIX we need to push the stack if a frame pointer is needed
18418 (because the stack might be dynamically adjusted), if we are
18419 debugging, if we make calls, or if the sum of fp_save, gp_save,
18420 and local variables are more than the space needed to save all
18421 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
18422 + 18*8 = 288 (GPR13 reserved).
18424 For V.4 we don't have the stack cushion that AIX uses, but assume
18425 that the debugger can handle stackless frames. */
18427 if (info_ptr->calls_p)
18428 info_ptr->push_p = 1;
18430 else if (DEFAULT_ABI == ABI_V4)
18431 info_ptr->push_p = non_fixed_size != 0;
18433 else if (frame_pointer_needed)
18434 info_ptr->push_p = 1;
18436 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
18437 info_ptr->push_p = 1;
18440 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
18442 /* Zero offsets if we're not saving those registers. */
18443 if (info_ptr->fp_size == 0)
18444 info_ptr->fp_save_offset = 0;
18446 if (info_ptr->gp_size == 0)
18447 info_ptr->gp_save_offset = 0;
18449 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
18450 info_ptr->altivec_save_offset = 0;
18452 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
18453 info_ptr->vrsave_save_offset = 0;
18455 if (! TARGET_SPE_ABI
18456 || info_ptr->spe_64bit_regs_used == 0
18457 || info_ptr->spe_gp_size == 0)
18458 info_ptr->spe_gp_save_offset = 0;
18460 if (! info_ptr->lr_save_p)
18461 info_ptr->lr_save_offset = 0;
18463 if (! info_ptr->cr_save_p)
18464 info_ptr->cr_save_offset = 0;
18469 /* Return true if the current function uses any GPRs in 64-bit SIMD
18473 spe_func_has_64bit_regs_p (void)
18477 /* Functions that save and restore all the call-saved registers will
18478 need to save/restore the registers in 64-bits. */
18479 if (crtl->calls_eh_return
18480 || cfun->calls_setjmp
18481 || crtl->has_nonlocal_goto)
18484 insns = get_insns ();
18486 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
18492 /* FIXME: This should be implemented with attributes...
18494 (set_attr "spe64" "true")....then,
18495 if (get_spe64(insn)) return true;
18497 It's the only reliable way to do the stuff below. */
18499 i = PATTERN (insn);
18500 if (GET_CODE (i) == SET)
18502 enum machine_mode mode = GET_MODE (SET_SRC (i));
18504 if (SPE_VECTOR_MODE (mode))
18506 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
18516 debug_stack_info (rs6000_stack_t *info)
18518 const char *abi_string;
18521 info = rs6000_stack_info ();
18523 fprintf (stderr, "\nStack information for function %s:\n",
18524 ((current_function_decl && DECL_NAME (current_function_decl))
18525 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
18530 default: abi_string = "Unknown"; break;
18531 case ABI_NONE: abi_string = "NONE"; break;
18532 case ABI_AIX: abi_string = "AIX"; break;
18533 case ABI_DARWIN: abi_string = "Darwin"; break;
18534 case ABI_V4: abi_string = "V.4"; break;
18537 fprintf (stderr, "\tABI = %5s\n", abi_string);
18539 if (TARGET_ALTIVEC_ABI)
18540 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
18542 if (TARGET_SPE_ABI)
18543 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
18545 if (info->first_gp_reg_save != 32)
18546 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
18548 if (info->first_fp_reg_save != 64)
18549 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
18551 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
18552 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
18553 info->first_altivec_reg_save);
18555 if (info->lr_save_p)
18556 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
18558 if (info->cr_save_p)
18559 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
18561 if (info->vrsave_mask)
18562 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
18565 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
18568 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
18570 if (info->gp_save_offset)
18571 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
18573 if (info->fp_save_offset)
18574 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
18576 if (info->altivec_save_offset)
18577 fprintf (stderr, "\taltivec_save_offset = %5d\n",
18578 info->altivec_save_offset);
18580 if (info->spe_gp_save_offset)
18581 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
18582 info->spe_gp_save_offset);
18584 if (info->vrsave_save_offset)
18585 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
18586 info->vrsave_save_offset);
18588 if (info->lr_save_offset)
18589 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
18591 if (info->cr_save_offset)
18592 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
18594 if (info->varargs_save_offset)
18595 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
18597 if (info->total_size)
18598 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18601 if (info->vars_size)
18602 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18605 if (info->parm_size)
18606 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
18608 if (info->fixed_size)
18609 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
18612 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
18614 if (info->spe_gp_size)
18615 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
18618 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
18620 if (info->altivec_size)
18621 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
18623 if (info->vrsave_size)
18624 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
18626 if (info->altivec_padding_size)
18627 fprintf (stderr, "\taltivec_padding_size= %5d\n",
18628 info->altivec_padding_size);
18630 if (info->spe_padding_size)
18631 fprintf (stderr, "\tspe_padding_size = %5d\n",
18632 info->spe_padding_size);
18635 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
18637 if (info->save_size)
18638 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
18640 if (info->reg_size != 4)
18641 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
18643 fprintf (stderr, "\tsave-strategy = %04x\n", info->savres_strategy);
18645 fprintf (stderr, "\n");
18649 rs6000_return_addr (int count, rtx frame)
18651 /* Currently we don't optimize very well between prolog and body
18652 code and for PIC code the code can be actually quite bad, so
18653 don't try to be too clever here. */
18654 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
18656 cfun->machine->ra_needs_full_frame = 1;
18663 plus_constant (copy_to_reg
18664 (gen_rtx_MEM (Pmode,
18665 memory_address (Pmode, frame))),
18666 RETURN_ADDRESS_OFFSET)));
18669 cfun->machine->ra_need_lr = 1;
18670 return get_hard_reg_initial_val (Pmode, LR_REGNO);
18673 /* Say whether a function is a candidate for sibcall handling or not. */
18676 rs6000_function_ok_for_sibcall (tree decl, tree exp)
18681 fntype = TREE_TYPE (decl);
18683 fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (exp)));
18685 /* We can't do it if the called function has more vector parameters
18686 than the current function; there's nowhere to put the VRsave code. */
18687 if (TARGET_ALTIVEC_ABI
18688 && TARGET_ALTIVEC_VRSAVE
18689 && !(decl && decl == current_function_decl))
18691 function_args_iterator args_iter;
18695 /* Functions with vector parameters are required to have a
18696 prototype, so the argument type info must be available
18698 FOREACH_FUNCTION_ARGS(fntype, type, args_iter)
18699 if (TREE_CODE (type) == VECTOR_TYPE
18700 && ALTIVEC_OR_VSX_VECTOR_MODE (TYPE_MODE (type)))
18703 FOREACH_FUNCTION_ARGS(TREE_TYPE (current_function_decl), type, args_iter)
18704 if (TREE_CODE (type) == VECTOR_TYPE
18705 && ALTIVEC_OR_VSX_VECTOR_MODE (TYPE_MODE (type)))
18712 /* Under the AIX ABI we can't allow calls to non-local functions,
18713 because the callee may have a different TOC pointer to the
18714 caller and there's no way to ensure we restore the TOC when we
18715 return. With the secure-plt SYSV ABI we can't make non-local
18716 calls when -fpic/PIC because the plt call stubs use r30. */
18717 if (DEFAULT_ABI == ABI_DARWIN
18718 || (DEFAULT_ABI == ABI_AIX
18720 && !DECL_EXTERNAL (decl)
18721 && (*targetm.binds_local_p) (decl))
18722 || (DEFAULT_ABI == ABI_V4
18723 && (!TARGET_SECURE_PLT
18726 && (*targetm.binds_local_p) (decl)))))
18728 tree attr_list = TYPE_ATTRIBUTES (fntype);
18730 if (!lookup_attribute ("longcall", attr_list)
18731 || lookup_attribute ("shortcall", attr_list))
18738 /* NULL if INSN insn is valid within a low-overhead loop.
18739 Otherwise return why doloop cannot be applied.
18740 PowerPC uses the COUNT register for branch on table instructions. */
18742 static const char *
18743 rs6000_invalid_within_doloop (const_rtx insn)
18746 return "Function call in the loop.";
18749 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
18750 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
18751 return "Computed branch in the loop.";
18757 rs6000_ra_ever_killed (void)
18763 if (cfun->is_thunk)
18766 if (cfun->machine->lr_save_state)
18767 return cfun->machine->lr_save_state - 1;
18769 /* regs_ever_live has LR marked as used if any sibcalls are present,
18770 but this should not force saving and restoring in the
18771 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
18772 clobbers LR, so that is inappropriate. */
18774 /* Also, the prologue can generate a store into LR that
18775 doesn't really count, like this:
18778 bcl to set PIC register
18782 When we're called from the epilogue, we need to avoid counting
18783 this as a store. */
18785 push_topmost_sequence ();
18786 top = get_insns ();
18787 pop_topmost_sequence ();
18788 reg = gen_rtx_REG (Pmode, LR_REGNO);
18790 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
18796 if (!SIBLING_CALL_P (insn))
18799 else if (find_regno_note (insn, REG_INC, LR_REGNO))
18801 else if (set_of (reg, insn) != NULL_RTX
18802 && !prologue_epilogue_contains (insn))
18809 /* Emit instructions needed to load the TOC register.
18810 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
18811 a constant pool; or for SVR4 -fpic. */
18814 rs6000_emit_load_toc_table (int fromprolog)
18817 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
18819 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
18822 rtx lab, tmp1, tmp2, got;
18824 lab = gen_label_rtx ();
18825 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (lab));
18826 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18828 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18830 got = rs6000_got_sym ();
18831 tmp1 = tmp2 = dest;
18834 tmp1 = gen_reg_rtx (Pmode);
18835 tmp2 = gen_reg_rtx (Pmode);
18837 emit_insn (gen_load_toc_v4_PIC_1 (lab));
18838 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
18839 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
18840 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
18842 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
18844 emit_insn (gen_load_toc_v4_pic_si ());
18845 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18847 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
18850 rtx temp0 = (fromprolog
18851 ? gen_rtx_REG (Pmode, 0)
18852 : gen_reg_rtx (Pmode));
18858 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
18859 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18861 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
18862 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18864 emit_insn (gen_load_toc_v4_PIC_1 (symF));
18865 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18866 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
18872 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18873 lab = gen_label_rtx ();
18874 emit_insn (gen_load_toc_v4_PIC_1b (tocsym, lab));
18875 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18876 if (TARGET_LINK_STACK)
18877 emit_insn (gen_addsi3 (dest, dest, GEN_INT (4)));
18878 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
18880 emit_insn (gen_addsi3 (dest, temp0, dest));
18882 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
18884 /* This is for AIX code running in non-PIC ELF32. */
18887 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
18888 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18890 emit_insn (gen_elf_high (dest, realsym));
18891 emit_insn (gen_elf_low (dest, dest, realsym));
18895 gcc_assert (DEFAULT_ABI == ABI_AIX);
18898 emit_insn (gen_load_toc_aix_si (dest));
18900 emit_insn (gen_load_toc_aix_di (dest));
18904 /* Emit instructions to restore the link register after determining where
18905 its value has been stored. */
18908 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
18910 rs6000_stack_t *info = rs6000_stack_info ();
18913 operands[0] = source;
18914 operands[1] = scratch;
18916 if (info->lr_save_p)
18918 rtx frame_rtx = stack_pointer_rtx;
18919 HOST_WIDE_INT sp_offset = 0;
18922 if (frame_pointer_needed
18923 || cfun->calls_alloca
18924 || info->total_size > 32767)
18926 tmp = gen_frame_mem (Pmode, frame_rtx);
18927 emit_move_insn (operands[1], tmp);
18928 frame_rtx = operands[1];
18930 else if (info->push_p)
18931 sp_offset = info->total_size;
18933 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
18934 tmp = gen_frame_mem (Pmode, tmp);
18935 emit_move_insn (tmp, operands[0]);
18938 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
18940 /* Freeze lr_save_p. We've just emitted rtl that depends on the
18941 state of lr_save_p so any change from here on would be a bug. In
18942 particular, stop rs6000_ra_ever_killed from considering the SET
18943 of lr we may have added just above. */
18944 cfun->machine->lr_save_state = info->lr_save_p + 1;
18947 static GTY(()) alias_set_type set = -1;
18950 get_TOC_alias_set (void)
18953 set = new_alias_set ();
18957 /* This returns nonzero if the current function uses the TOC. This is
18958 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
18959 is generated by the ABI_V4 load_toc_* patterns. */
18966 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
18969 rtx pat = PATTERN (insn);
18972 if (GET_CODE (pat) == PARALLEL)
18973 for (i = 0; i < XVECLEN (pat, 0); i++)
18975 rtx sub = XVECEXP (pat, 0, i);
18976 if (GET_CODE (sub) == USE)
18978 sub = XEXP (sub, 0);
18979 if (GET_CODE (sub) == UNSPEC
18980 && XINT (sub, 1) == UNSPEC_TOC)
18990 create_TOC_reference (rtx symbol, rtx largetoc_reg)
18992 rtx tocrel, tocreg;
18994 if (TARGET_DEBUG_ADDR)
18996 if (GET_CODE (symbol) == SYMBOL_REF)
18997 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
19001 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
19002 GET_RTX_NAME (GET_CODE (symbol)));
19003 debug_rtx (symbol);
19007 if (!can_create_pseudo_p ())
19008 df_set_regs_ever_live (TOC_REGISTER, true);
19010 tocrel = gen_rtx_CONST (Pmode,
19011 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol),
19013 tocreg = gen_rtx_REG (Pmode, TOC_REGISTER);
19014 if (TARGET_CMODEL != CMODEL_SMALL)
19016 rtx hi = gen_rtx_CONST (Pmode,
19017 gen_rtx_PLUS (Pmode, tocreg,
19018 gen_rtx_HIGH (Pmode, tocrel)));
19019 if (largetoc_reg != NULL)
19021 emit_move_insn (largetoc_reg, hi);
19024 return gen_rtx_LO_SUM (Pmode, hi, copy_rtx (tocrel));
19027 return gen_rtx_PLUS (Pmode, tocreg, tocrel);
19030 /* Issue assembly directives that create a reference to the given DWARF
19031 FRAME_TABLE_LABEL from the current function section. */
19033 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
19035 fprintf (asm_out_file, "\t.ref %s\n",
19036 TARGET_STRIP_NAME_ENCODING (frame_table_label));
19039 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
19040 and the change to the stack pointer. */
19043 rs6000_emit_stack_tie (void)
19045 rtx mem = gen_frame_mem (BLKmode,
19046 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
19048 emit_insn (gen_stack_tie (mem));
19051 /* Emit the correct code for allocating stack space, as insns.
19052 If COPY_REG, make sure a copy of the old frame is left there.
19053 The generated code may use hard register 0 as a temporary. */
19056 rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg)
19059 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19060 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
19061 rtx todec = gen_int_mode (-size, Pmode);
19064 if (INTVAL (todec) != -size)
19066 warning (0, "stack frame too large");
19067 emit_insn (gen_trap ());
19071 if (crtl->limit_stack)
19073 if (REG_P (stack_limit_rtx)
19074 && REGNO (stack_limit_rtx) > 1
19075 && REGNO (stack_limit_rtx) <= 31)
19077 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
19078 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19081 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
19083 && DEFAULT_ABI == ABI_V4)
19085 rtx toload = gen_rtx_CONST (VOIDmode,
19086 gen_rtx_PLUS (Pmode,
19090 emit_insn (gen_elf_high (tmp_reg, toload));
19091 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
19092 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19096 warning (0, "stack limit expression is not supported");
19100 emit_move_insn (copy_reg, stack_reg);
19104 /* Need a note here so that try_split doesn't get confused. */
19105 if (get_last_insn () == NULL_RTX)
19106 emit_note (NOTE_INSN_DELETED);
19107 insn = emit_move_insn (tmp_reg, todec);
19108 try_split (PATTERN (insn), insn, 0);
19112 insn = emit_insn (TARGET_32BIT
19113 ? gen_movsi_update_stack (stack_reg, stack_reg,
19115 : gen_movdi_di_update_stack (stack_reg, stack_reg,
19116 todec, stack_reg));
19117 /* Since we didn't use gen_frame_mem to generate the MEM, grab
19118 it now and set the alias set/attributes. The above gen_*_update
19119 calls will generate a PARALLEL with the MEM set being the first
19121 par = PATTERN (insn);
19122 gcc_assert (GET_CODE (par) == PARALLEL);
19123 set = XVECEXP (par, 0, 0);
19124 gcc_assert (GET_CODE (set) == SET);
19125 mem = SET_DEST (set);
19126 gcc_assert (MEM_P (mem));
19127 MEM_NOTRAP_P (mem) = 1;
19128 set_mem_alias_set (mem, get_frame_alias_set ());
19130 RTX_FRAME_RELATED_P (insn) = 1;
19131 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
19132 gen_rtx_SET (VOIDmode, stack_reg,
19133 gen_rtx_PLUS (Pmode, stack_reg,
19134 GEN_INT (-size))));
19137 #define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
19139 #if PROBE_INTERVAL > 32768
19140 #error Cannot use indexed addressing mode for stack probing
19143 /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
19144 inclusive. These are offsets from the current stack pointer. */
19147 rs6000_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size)
19149 /* See if we have a constant small number of probes to generate. If so,
19150 that's the easy case. */
19151 if (first + size <= 32768)
19155 /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
19156 it exceeds SIZE. If only one probe is needed, this will not
19157 generate any code. Then probe at FIRST + SIZE. */
19158 for (i = PROBE_INTERVAL; i < size; i += PROBE_INTERVAL)
19159 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + i)));
19161 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + size)));
19164 /* Otherwise, do the same as above, but in a loop. Note that we must be
19165 extra careful with variables wrapping around because we might be at
19166 the very top (or the very bottom) of the address space and we have
19167 to be able to handle this case properly; in particular, we use an
19168 equality test for the loop condition. */
19171 HOST_WIDE_INT rounded_size;
19172 rtx r12 = gen_rtx_REG (Pmode, 12);
19173 rtx r0 = gen_rtx_REG (Pmode, 0);
19175 /* Sanity check for the addressing mode we're going to use. */
19176 gcc_assert (first <= 32768);
19178 /* Step 1: round SIZE to the previous multiple of the interval. */
19180 rounded_size = size & -PROBE_INTERVAL;
19183 /* Step 2: compute initial and final value of the loop counter. */
19185 /* TEST_ADDR = SP + FIRST. */
19186 emit_insn (gen_rtx_SET (VOIDmode, r12,
19187 plus_constant (stack_pointer_rtx, -first)));
19189 /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE. */
19190 if (rounded_size > 32768)
19192 emit_move_insn (r0, GEN_INT (-rounded_size));
19193 emit_insn (gen_rtx_SET (VOIDmode, r0,
19194 gen_rtx_PLUS (Pmode, r12, r0)));
19197 emit_insn (gen_rtx_SET (VOIDmode, r0,
19198 plus_constant (r12, -rounded_size)));
19201 /* Step 3: the loop
19203 while (TEST_ADDR != LAST_ADDR)
19205 TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
19209 probes at FIRST + N * PROBE_INTERVAL for values of N from 1
19210 until it is equal to ROUNDED_SIZE. */
19213 emit_insn (gen_probe_stack_rangedi (r12, r12, r0));
19215 emit_insn (gen_probe_stack_rangesi (r12, r12, r0));
19218 /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
19219 that SIZE is equal to ROUNDED_SIZE. */
19221 if (size != rounded_size)
19222 emit_stack_probe (plus_constant (r12, rounded_size - size));
19226 /* Probe a range of stack addresses from REG1 to REG2 inclusive. These are
19227 absolute addresses. */
19230 output_probe_stack_range (rtx reg1, rtx reg2)
19232 static int labelno = 0;
19233 char loop_lab[32], end_lab[32];
19236 ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno);
19237 ASM_GENERATE_INTERNAL_LABEL (end_lab, "LPSRE", labelno++);
19239 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
19241 /* Jump to END_LAB if TEST_ADDR == LAST_ADDR. */
19245 output_asm_insn ("{cmp|cmpd} 0,%0,%1", xops);
19247 output_asm_insn ("{cmp|cmpw} 0,%0,%1", xops);
19249 fputs ("\tbeq 0,", asm_out_file);
19250 assemble_name_raw (asm_out_file, end_lab);
19251 fputc ('\n', asm_out_file);
19253 /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */
19254 xops[1] = GEN_INT (-PROBE_INTERVAL);
19255 output_asm_insn ("{cal %0,%1(%0)|addi %0,%0,%1}", xops);
19257 /* Probe at TEST_ADDR and branch. */
19258 xops[1] = gen_rtx_REG (Pmode, 0);
19259 output_asm_insn ("{st|stw} %1,0(%0)", xops);
19260 fprintf (asm_out_file, "\tb ");
19261 assemble_name_raw (asm_out_file, loop_lab);
19262 fputc ('\n', asm_out_file);
19264 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, end_lab);
19269 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
19270 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
19271 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
19272 deduce these equivalences by itself so it wasn't necessary to hold
19273 its hand so much. */
19276 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
19277 rtx reg2, rtx rreg)
19281 /* copy_rtx will not make unique copies of registers, so we need to
19282 ensure we don't have unwanted sharing here. */
19284 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19287 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19289 real = copy_rtx (PATTERN (insn));
19291 if (reg2 != NULL_RTX)
19292 real = replace_rtx (real, reg2, rreg);
19294 real = replace_rtx (real, reg,
19295 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
19296 STACK_POINTER_REGNUM),
19299 /* We expect that 'real' is either a SET or a PARALLEL containing
19300 SETs (and possibly other stuff). In a PARALLEL, all the SETs
19301 are important so they all have to be marked RTX_FRAME_RELATED_P. */
19303 if (GET_CODE (real) == SET)
19307 temp = simplify_rtx (SET_SRC (set));
19309 SET_SRC (set) = temp;
19310 temp = simplify_rtx (SET_DEST (set));
19312 SET_DEST (set) = temp;
19313 if (GET_CODE (SET_DEST (set)) == MEM)
19315 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19317 XEXP (SET_DEST (set), 0) = temp;
19324 gcc_assert (GET_CODE (real) == PARALLEL);
19325 for (i = 0; i < XVECLEN (real, 0); i++)
19326 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
19328 rtx set = XVECEXP (real, 0, i);
19330 temp = simplify_rtx (SET_SRC (set));
19332 SET_SRC (set) = temp;
19333 temp = simplify_rtx (SET_DEST (set));
19335 SET_DEST (set) = temp;
19336 if (GET_CODE (SET_DEST (set)) == MEM)
19338 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19340 XEXP (SET_DEST (set), 0) = temp;
19342 RTX_FRAME_RELATED_P (set) = 1;
19346 RTX_FRAME_RELATED_P (insn) = 1;
19347 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
19352 /* Returns an insn that has a vrsave set operation with the
19353 appropriate CLOBBERs. */
19356 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
19359 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
19360 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19363 = gen_rtx_SET (VOIDmode,
19365 gen_rtx_UNSPEC_VOLATILE (SImode,
19366 gen_rtvec (2, reg, vrsave),
19367 UNSPECV_SET_VRSAVE));
19371 /* We need to clobber the registers in the mask so the scheduler
19372 does not move sets to VRSAVE before sets of AltiVec registers.
19374 However, if the function receives nonlocal gotos, reload will set
19375 all call saved registers live. We will end up with:
19377 (set (reg 999) (mem))
19378 (parallel [ (set (reg vrsave) (unspec blah))
19379 (clobber (reg 999))])
19381 The clobber will cause the store into reg 999 to be dead, and
19382 flow will attempt to delete an epilogue insn. In this case, we
19383 need an unspec use/set of the register. */
19385 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
19386 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19388 if (!epiloguep || call_used_regs [i])
19389 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
19390 gen_rtx_REG (V4SImode, i));
19393 rtx reg = gen_rtx_REG (V4SImode, i);
19396 = gen_rtx_SET (VOIDmode,
19398 gen_rtx_UNSPEC (V4SImode,
19399 gen_rtvec (1, reg), 27));
19403 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
19405 for (i = 0; i < nclobs; ++i)
19406 XVECEXP (insn, 0, i) = clobs[i];
19411 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
19412 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
19415 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
19416 unsigned int regno, int offset, HOST_WIDE_INT total_size)
19418 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
19419 rtx replacea, replaceb;
19421 int_rtx = GEN_INT (offset);
19423 /* Some cases that need register indexed addressing. */
19424 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
19425 || (TARGET_VSX && ALTIVEC_OR_VSX_VECTOR_MODE (mode))
19426 || (TARGET_E500_DOUBLE && mode == DFmode)
19428 && SPE_VECTOR_MODE (mode)
19429 && !SPE_CONST_OFFSET_OK (offset)))
19431 /* Whomever calls us must make sure r11 is available in the
19432 flow path of instructions in the prologue. */
19433 offset_rtx = gen_rtx_REG (Pmode, 11);
19434 emit_move_insn (offset_rtx, int_rtx);
19436 replacea = offset_rtx;
19437 replaceb = int_rtx;
19441 offset_rtx = int_rtx;
19442 replacea = NULL_RTX;
19443 replaceb = NULL_RTX;
19446 reg = gen_rtx_REG (mode, regno);
19447 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
19448 mem = gen_frame_mem (mode, addr);
19450 insn = emit_move_insn (mem, reg);
19452 return rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
19455 /* Emit an offset memory reference suitable for a frame store, while
19456 converting to a valid addressing mode. */
19459 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
19461 rtx int_rtx, offset_rtx;
19463 int_rtx = GEN_INT (offset);
19465 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
19466 || (TARGET_E500_DOUBLE && mode == DFmode))
19468 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
19469 emit_move_insn (offset_rtx, int_rtx);
19472 offset_rtx = int_rtx;
19474 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
19477 /* Look for user-defined global regs. We should not save and restore these,
19478 and cannot use stmw/lmw if there are any in its range. */
19481 no_global_regs_above (int first, bool gpr)
19484 int last = gpr ? 32 : 64;
19485 for (i = first; i < last; i++)
19486 if (global_regs[i])
19491 #ifndef TARGET_FIX_AND_CONTINUE
19492 #define TARGET_FIX_AND_CONTINUE 0
19495 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
19496 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
19497 #define LAST_SAVRES_REGISTER 31
19498 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
19500 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
19502 /* Temporary holding space for an out-of-line register save/restore
19504 static char savres_routine_name[30];
19506 /* Return the name for an out-of-line register save/restore routine.
19507 We are saving/restoring GPRs if GPR is true. */
19510 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
19511 bool savep, bool gpr, bool lr)
19513 const char *prefix = "";
19514 const char *suffix = "";
19516 /* Different targets are supposed to define
19517 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
19518 routine name could be defined with:
19520 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
19522 This is a nice idea in practice, but in reality, things are
19523 complicated in several ways:
19525 - ELF targets have save/restore routines for GPRs.
19527 - SPE targets use different prefixes for 32/64-bit registers, and
19528 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
19530 - PPC64 ELF targets have routines for save/restore of GPRs that
19531 differ in what they do with the link register, so having a set
19532 prefix doesn't work. (We only use one of the save routines at
19533 the moment, though.)
19535 - PPC32 elf targets have "exit" versions of the restore routines
19536 that restore the link register and can save some extra space.
19537 These require an extra suffix. (There are also "tail" versions
19538 of the restore routines and "GOT" versions of the save routines,
19539 but we don't generate those at present. Same problems apply,
19542 We deal with all this by synthesizing our own prefix/suffix and
19543 using that for the simple sprintf call shown above. */
19546 /* No floating point saves on the SPE. */
19550 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
19552 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
19557 else if (DEFAULT_ABI == ABI_V4)
19563 prefix = savep ? "_savegpr_" : "_restgpr_";
19565 prefix = savep ? "_savefpr_" : "_restfpr_";
19570 else if (DEFAULT_ABI == ABI_AIX)
19572 #ifndef POWERPC_LINUX
19573 /* No out-of-line save/restore routines for GPRs on AIX. */
19574 gcc_assert (!TARGET_AIX || !gpr);
19580 ? (lr ? "_savegpr0_" : "_savegpr1_")
19581 : (lr ? "_restgpr0_" : "_restgpr1_"));
19582 #ifdef POWERPC_LINUX
19584 prefix = (savep ? "_savefpr_" : "_restfpr_");
19588 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
19589 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
19593 if (DEFAULT_ABI == ABI_DARWIN)
19595 /* The Darwin approach is (slightly) different, in order to be
19596 compatible with code generated by the system toolchain. There is a
19597 single symbol for the start of save sequence, and the code here
19598 embeds an offset into that code on the basis of the first register
19600 prefix = savep ? "save" : "rest" ;
19602 sprintf (savres_routine_name, "*%sGPR%s%s%.0d ; %s r%d-r31",
19603 prefix, (lr ? "x" : ""), (regno == 13 ? "" : "+"),
19604 (regno-13) * 4, prefix, regno);
19606 sprintf (savres_routine_name, "*%sFP%s%.0d ; %s f%d-f31",
19607 prefix, (regno == 14 ? "" : "+"), (regno-14) * 4, prefix, regno);
19610 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
19612 return savres_routine_name;
19615 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
19616 We are saving/restoring GPRs if GPR is true. */
19619 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
19622 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
19624 int select = ((savep ? 1 : 0) << 2
19626 /* On the SPE, we never have any FPRs, but we do have
19627 32/64-bit versions of the routines. */
19628 ? (info->spe_64bit_regs_used ? 1 : 0)
19629 : (gpr ? 1 : 0)) << 1)
19632 /* Don't generate bogus routine names. */
19633 gcc_assert (FIRST_SAVRES_REGISTER <= regno
19634 && regno <= LAST_SAVRES_REGISTER);
19636 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
19642 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
19644 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
19645 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
19646 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
19652 /* Emit a sequence of insns, including a stack tie if needed, for
19653 resetting the stack pointer. If SAVRES is true, then don't reset the
19654 stack pointer, but move the base of the frame into r11 for use by
19655 out-of-line register restore routines. */
19658 rs6000_emit_stack_reset (rs6000_stack_t *info,
19659 rtx sp_reg_rtx, rtx frame_reg_rtx,
19660 int sp_offset, bool savres)
19662 /* This blockage is needed so that sched doesn't decide to move
19663 the sp change before the register restores. */
19664 if (frame_reg_rtx != sp_reg_rtx
19666 && info->spe_64bit_regs_used != 0
19667 && info->first_gp_reg_save != 32))
19668 rs6000_emit_stack_tie ();
19670 if (frame_reg_rtx != sp_reg_rtx)
19672 if (sp_offset != 0)
19674 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
19675 rtx insn = emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
19676 GEN_INT (sp_offset)));
19681 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
19683 else if (sp_offset != 0)
19685 /* If we are restoring registers out-of-line, we will be using the
19686 "exit" variants of the restore routines, which will reset the
19687 stack for us. But we do need to point r11 into the right place
19688 for those routines. */
19689 rtx dest_reg = (savres
19690 ? gen_rtx_REG (Pmode, 11)
19693 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
19694 GEN_INT (sp_offset)));
19701 /* Construct a parallel rtx describing the effect of a call to an
19702 out-of-line register save/restore routine, and emit the insn
19703 or jump_insn as appropriate. */
19706 rs6000_emit_savres_rtx (rs6000_stack_t *info,
19707 rtx frame_reg_rtx, int save_area_offset,
19708 enum machine_mode reg_mode,
19709 bool savep, bool gpr, bool lr)
19712 int offset, start_reg, end_reg, n_regs, use_reg;
19713 int reg_size = GET_MODE_SIZE (reg_mode);
19720 ? info->first_gp_reg_save
19721 : info->first_fp_reg_save);
19722 end_reg = gpr ? 32 : 64;
19723 n_regs = end_reg - start_reg;
19724 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
19727 RTVEC_ELT (p, offset++) = ret_rtx;
19729 RTVEC_ELT (p, offset++)
19730 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, LR_REGNO));
19732 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
19733 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
19734 use_reg = DEFAULT_ABI == ABI_AIX ? (gpr && !lr ? 12 : 1)
19735 : DEFAULT_ABI == ABI_DARWIN && !gpr ? 1
19737 RTVEC_ELT (p, offset++)
19738 = gen_rtx_USE (VOIDmode,
19739 gen_rtx_REG (Pmode, use_reg));
19741 for (i = 0; i < end_reg - start_reg; i++)
19743 rtx addr, reg, mem;
19744 reg = gen_rtx_REG (reg_mode, start_reg + i);
19745 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19746 GEN_INT (save_area_offset + reg_size*i));
19747 mem = gen_frame_mem (reg_mode, addr);
19749 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
19751 savep ? reg : mem);
19756 rtx addr, reg, mem;
19757 reg = gen_rtx_REG (Pmode, 0);
19758 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19759 GEN_INT (info->lr_save_offset));
19760 mem = gen_frame_mem (Pmode, addr);
19761 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
19764 par = gen_rtx_PARALLEL (VOIDmode, p);
19768 insn = emit_jump_insn (par);
19769 JUMP_LABEL (insn) = ret_rtx;
19772 insn = emit_insn (par);
19776 /* Determine whether the gp REG is really used. */
19779 rs6000_reg_live_or_pic_offset_p (int reg)
19781 /* If the function calls eh_return, claim used all the registers that would
19782 be checked for liveness otherwise. This is required for the PIC offset
19783 register with -mminimal-toc on AIX, as it is advertised as "fixed" for
19784 register allocation purposes in this case. */
19786 return (((crtl->calls_eh_return || df_regs_ever_live_p (reg))
19787 && (!call_used_regs[reg]
19788 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
19789 && !TARGET_SINGLE_PIC_BASE
19790 && TARGET_TOC && TARGET_MINIMAL_TOC)))
19791 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
19792 && !TARGET_SINGLE_PIC_BASE
19793 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
19794 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
19797 /* Emit function prologue as insns. */
19800 rs6000_emit_prologue (void)
19802 rs6000_stack_t *info = rs6000_stack_info ();
19803 enum machine_mode reg_mode = Pmode;
19804 int reg_size = TARGET_32BIT ? 4 : 8;
19805 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19806 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
19807 rtx frame_reg_rtx = sp_reg_rtx;
19808 rtx cr_save_rtx = NULL_RTX;
19811 int saving_FPRs_inline;
19812 int saving_GPRs_inline;
19813 int using_store_multiple;
19814 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
19815 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
19816 && call_used_regs[STATIC_CHAIN_REGNUM]);
19817 HOST_WIDE_INT sp_offset = 0;
19819 if (flag_stack_usage_info)
19820 current_function_static_stack_size = info->total_size;
19822 if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK && info->total_size)
19823 rs6000_emit_probe_stack_range (STACK_CHECK_PROTECT, info->total_size);
19825 if (TARGET_FIX_AND_CONTINUE)
19827 /* gdb on darwin arranges to forward a function from the old
19828 address by modifying the first 5 instructions of the function
19829 to branch to the overriding function. This is necessary to
19830 permit function pointers that point to the old function to
19831 actually forward to the new function. */
19832 emit_insn (gen_nop ());
19833 emit_insn (gen_nop ());
19834 emit_insn (gen_nop ());
19835 emit_insn (gen_nop ());
19836 emit_insn (gen_nop ());
19839 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19841 reg_mode = V2SImode;
19845 strategy = info->savres_strategy;
19846 using_store_multiple = strategy & SAVRES_MULTIPLE;
19847 saving_FPRs_inline = strategy & SAVE_INLINE_FPRS;
19848 saving_GPRs_inline = strategy & SAVE_INLINE_GPRS;
19850 /* For V.4, update stack before we do any saving and set back pointer. */
19851 if (! WORLD_SAVE_P (info)
19853 && (DEFAULT_ABI == ABI_V4
19854 || crtl->calls_eh_return))
19856 bool need_r11 = (TARGET_SPE
19857 ? (!saving_GPRs_inline
19858 && info->spe_64bit_regs_used == 0)
19859 : (!saving_FPRs_inline || !saving_GPRs_inline));
19860 rtx copy_reg = need_r11 ? gen_rtx_REG (Pmode, 11) : NULL;
19862 if (info->total_size < 32767)
19863 sp_offset = info->total_size;
19865 frame_reg_rtx = copy_reg;
19866 else if (info->cr_save_p
19868 || info->first_fp_reg_save < 64
19869 || info->first_gp_reg_save < 32
19870 || info->altivec_size != 0
19871 || info->vrsave_mask != 0
19872 || crtl->calls_eh_return)
19874 copy_reg = frame_ptr_rtx;
19875 frame_reg_rtx = copy_reg;
19879 /* The prologue won't be saving any regs so there is no need
19880 to set up a frame register to access any frame save area.
19881 We also won't be using sp_offset anywhere below, but set
19882 the correct value anyway to protect against future
19883 changes to this function. */
19884 sp_offset = info->total_size;
19886 rs6000_emit_allocate_stack (info->total_size, copy_reg);
19887 if (frame_reg_rtx != sp_reg_rtx)
19888 rs6000_emit_stack_tie ();
19891 /* Handle world saves specially here. */
19892 if (WORLD_SAVE_P (info))
19899 /* save_world expects lr in r0. */
19900 reg0 = gen_rtx_REG (Pmode, 0);
19901 if (info->lr_save_p)
19903 insn = emit_move_insn (reg0,
19904 gen_rtx_REG (Pmode, LR_REGNO));
19905 RTX_FRAME_RELATED_P (insn) = 1;
19908 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
19909 assumptions about the offsets of various bits of the stack
19911 gcc_assert (info->gp_save_offset == -220
19912 && info->fp_save_offset == -144
19913 && info->lr_save_offset == 8
19914 && info->cr_save_offset == 4
19917 && (!crtl->calls_eh_return
19918 || info->ehrd_offset == -432)
19919 && info->vrsave_save_offset == -224
19920 && info->altivec_save_offset == -416);
19922 treg = gen_rtx_REG (SImode, 11);
19923 emit_move_insn (treg, GEN_INT (-info->total_size));
19925 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
19926 in R11. It also clobbers R12, so beware! */
19928 /* Preserve CR2 for save_world prologues */
19930 sz += 32 - info->first_gp_reg_save;
19931 sz += 64 - info->first_fp_reg_save;
19932 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
19933 p = rtvec_alloc (sz);
19935 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
19936 gen_rtx_REG (SImode,
19938 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
19939 gen_rtx_SYMBOL_REF (Pmode,
19941 /* We do floats first so that the instruction pattern matches
19943 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
19945 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19946 ? DFmode : SFmode),
19947 info->first_fp_reg_save + i);
19948 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19949 GEN_INT (info->fp_save_offset
19950 + sp_offset + 8 * i));
19951 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19952 ? DFmode : SFmode), addr);
19954 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19956 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
19958 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
19959 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19960 GEN_INT (info->altivec_save_offset
19961 + sp_offset + 16 * i));
19962 rtx mem = gen_frame_mem (V4SImode, addr);
19964 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19966 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19968 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19969 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19970 GEN_INT (info->gp_save_offset
19971 + sp_offset + reg_size * i));
19972 rtx mem = gen_frame_mem (reg_mode, addr);
19974 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19978 /* CR register traditionally saved as CR2. */
19979 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
19980 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19981 GEN_INT (info->cr_save_offset
19983 rtx mem = gen_frame_mem (reg_mode, addr);
19985 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19987 /* Explain about use of R0. */
19988 if (info->lr_save_p)
19990 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19991 GEN_INT (info->lr_save_offset
19993 rtx mem = gen_frame_mem (reg_mode, addr);
19995 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
19997 /* Explain what happens to the stack pointer. */
19999 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
20000 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
20003 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20004 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20005 treg, GEN_INT (-info->total_size));
20006 sp_offset = info->total_size;
20009 /* If we use the link register, get it into r0. */
20010 if (!WORLD_SAVE_P (info) && info->lr_save_p)
20012 rtx addr, reg, mem;
20014 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
20015 gen_rtx_REG (Pmode, LR_REGNO));
20016 RTX_FRAME_RELATED_P (insn) = 1;
20018 if (!(strategy & (SAVE_NOINLINE_GPRS_SAVES_LR
20019 | SAVE_NOINLINE_FPRS_SAVES_LR)))
20021 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20022 GEN_INT (info->lr_save_offset + sp_offset));
20023 reg = gen_rtx_REG (Pmode, 0);
20024 mem = gen_rtx_MEM (Pmode, addr);
20025 /* This should not be of rs6000_sr_alias_set, because of
20026 __builtin_return_address. */
20028 insn = emit_move_insn (mem, reg);
20029 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20030 NULL_RTX, NULL_RTX);
20034 /* If we need to save CR, put it into r12 or r11. */
20035 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
20040 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
20042 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20043 RTX_FRAME_RELATED_P (insn) = 1;
20044 /* Now, there's no way that dwarf2out_frame_debug_expr is going
20045 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
20046 But that's OK. All we have to do is specify that _one_ condition
20047 code register is saved in this stack slot. The thrower's epilogue
20048 will then restore all the call-saved registers.
20049 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
20050 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
20051 gen_rtx_REG (SImode, CR2_REGNO));
20052 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20055 /* Do any required saving of fpr's. If only one or two to save, do
20056 it ourselves. Otherwise, call function. */
20057 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
20060 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20061 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
20062 && ! call_used_regs[info->first_fp_reg_save+i]))
20063 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
20064 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20066 info->first_fp_reg_save + i,
20067 info->fp_save_offset + sp_offset + 8 * i,
20070 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
20072 insn = rs6000_emit_savres_rtx (info, frame_reg_rtx,
20073 info->fp_save_offset + sp_offset,
20075 /*savep=*/true, /*gpr=*/false,
20077 & SAVE_NOINLINE_FPRS_SAVES_LR)
20079 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20080 NULL_RTX, NULL_RTX);
20083 /* Save GPRs. This is done as a PARALLEL if we are using
20084 the store-multiple instructions. */
20085 if (!WORLD_SAVE_P (info)
20087 && info->spe_64bit_regs_used != 0
20088 && info->first_gp_reg_save != 32)
20091 rtx spe_save_area_ptr;
20093 /* Determine whether we can address all of the registers that need
20094 to be saved with an offset from the stack pointer that fits in
20095 the small const field for SPE memory instructions. */
20096 int spe_regs_addressable_via_sp
20097 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
20098 + (32 - info->first_gp_reg_save - 1) * reg_size)
20099 && saving_GPRs_inline);
20102 if (spe_regs_addressable_via_sp)
20104 spe_save_area_ptr = frame_reg_rtx;
20105 spe_offset = info->spe_gp_save_offset + sp_offset;
20109 /* Make r11 point to the start of the SPE save area. We need
20110 to be careful here if r11 is holding the static chain. If
20111 it is, then temporarily save it in r0. We would use r0 as
20112 our base register here, but using r0 as a base register in
20113 loads and stores means something different from what we
20115 int ool_adjust = (saving_GPRs_inline
20117 : (info->first_gp_reg_save
20118 - (FIRST_SAVRES_REGISTER+1))*8);
20119 HOST_WIDE_INT offset = (info->spe_gp_save_offset
20120 + sp_offset - ool_adjust);
20122 if (using_static_chain_p)
20124 rtx r0 = gen_rtx_REG (Pmode, 0);
20125 gcc_assert (info->first_gp_reg_save > 11);
20127 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
20130 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
20131 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
20133 GEN_INT (offset)));
20134 /* We need to make sure the move to r11 gets noted for
20135 properly outputting unwind information. */
20136 if (!saving_GPRs_inline)
20137 rs6000_frame_related (insn, frame_reg_rtx, offset,
20138 NULL_RTX, NULL_RTX);
20142 if (saving_GPRs_inline)
20144 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20145 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20147 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20148 rtx offset, addr, mem;
20150 /* We're doing all this to ensure that the offset fits into
20151 the immediate offset of 'evstdd'. */
20152 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
20154 offset = GEN_INT (reg_size * i + spe_offset);
20155 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
20156 mem = gen_rtx_MEM (V2SImode, addr);
20158 insn = emit_move_insn (mem, reg);
20160 rs6000_frame_related (insn, spe_save_area_ptr,
20161 info->spe_gp_save_offset
20162 + sp_offset + reg_size * i,
20163 offset, const0_rtx);
20168 insn = rs6000_emit_savres_rtx (info, gen_rtx_REG (Pmode, 11),
20170 /*savep=*/true, /*gpr=*/true,
20172 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20173 NULL_RTX, NULL_RTX);
20177 /* Move the static chain pointer back. */
20178 if (using_static_chain_p && !spe_regs_addressable_via_sp)
20179 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
20181 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
20183 if (DEFAULT_ABI == ABI_DARWIN)
20185 rtx dest_reg = gen_rtx_REG (reg_mode, 11);
20186 if (info->first_fp_reg_save == 64)
20187 /* we only need a copy, no fprs were saved. */
20188 emit_move_insn (dest_reg, frame_reg_rtx);
20191 rtx offset = GEN_INT (sp_offset
20192 + (-8 * (64-info->first_fp_reg_save)));
20193 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
20196 /* Need to adjust r11 (r12) if we saved any FPRs. */
20197 else if (info->first_fp_reg_save != 64)
20199 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
20201 rtx offset = GEN_INT (sp_offset
20202 + (-8 * (64-info->first_fp_reg_save)));
20203 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
20206 insn = rs6000_emit_savres_rtx (info, frame_reg_rtx,
20207 info->gp_save_offset + sp_offset,
20209 /*savep=*/true, /*gpr=*/true,
20211 & SAVE_NOINLINE_GPRS_SAVES_LR)
20213 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20214 NULL_RTX, NULL_RTX);
20216 else if (!WORLD_SAVE_P (info) && using_store_multiple)
20220 p = rtvec_alloc (32 - info->first_gp_reg_save);
20221 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20223 rtx addr, reg, mem;
20224 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20225 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20226 GEN_INT (info->gp_save_offset
20229 mem = gen_frame_mem (reg_mode, addr);
20231 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
20233 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20234 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20235 NULL_RTX, NULL_RTX);
20237 else if (!WORLD_SAVE_P (info))
20240 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20241 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20243 rtx addr, reg, mem;
20244 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20246 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20247 GEN_INT (info->gp_save_offset
20250 mem = gen_frame_mem (reg_mode, addr);
20252 insn = emit_move_insn (mem, reg);
20253 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20254 NULL_RTX, NULL_RTX);
20258 /* ??? There's no need to emit actual instructions here, but it's the
20259 easiest way to get the frame unwind information emitted. */
20260 if (crtl->calls_eh_return)
20262 unsigned int i, regno;
20266 regno = EH_RETURN_DATA_REGNO (i);
20267 if (regno == INVALID_REGNUM)
20270 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
20271 info->ehrd_offset + sp_offset
20272 + reg_size * (int) i,
20277 /* In AIX ABI we need to make sure r2 is really saved. */
20278 if (TARGET_AIX && crtl->calls_eh_return)
20280 rtx tmp_reg, tmp_reg_si, hi, lo, compare_result, toc_save_done, jump;
20281 rtx save_insn, join_insn, note;
20282 long toc_restore_insn;
20284 gcc_assert (frame_reg_rtx == frame_ptr_rtx
20285 || frame_reg_rtx == sp_reg_rtx);
20286 tmp_reg = gen_rtx_REG (Pmode, 11);
20287 tmp_reg_si = gen_rtx_REG (SImode, 11);
20288 if (using_static_chain_p)
20289 emit_move_insn (gen_rtx_REG (Pmode, 0), tmp_reg);
20290 gcc_assert (saving_GPRs_inline && saving_FPRs_inline);
20291 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, LR_REGNO));
20292 /* Peek at instruction to which this function returns. If it's
20293 restoring r2, then we know we've already saved r2. We can't
20294 unconditionally save r2 because the value we have will already
20295 be updated if we arrived at this function via a plt call or
20296 toc adjusting stub. */
20297 emit_move_insn (tmp_reg_si, gen_rtx_MEM (SImode, tmp_reg));
20298 toc_restore_insn = TARGET_32BIT ? 0x80410014 : 0xE8410028;
20299 hi = gen_int_mode (toc_restore_insn & ~0xffff, SImode);
20300 emit_insn (gen_xorsi3 (tmp_reg_si, tmp_reg_si, hi));
20301 compare_result = gen_rtx_REG (CCUNSmode, CR0_REGNO);
20302 validate_condition_mode (EQ, CCUNSmode);
20303 lo = gen_int_mode (toc_restore_insn & 0xffff, SImode);
20304 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
20305 gen_rtx_COMPARE (CCUNSmode, tmp_reg_si, lo)));
20306 toc_save_done = gen_label_rtx ();
20307 jump = gen_rtx_IF_THEN_ELSE (VOIDmode,
20308 gen_rtx_EQ (VOIDmode, compare_result,
20310 gen_rtx_LABEL_REF (VOIDmode, toc_save_done),
20312 jump = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, jump));
20313 JUMP_LABEL (jump) = toc_save_done;
20314 LABEL_NUSES (toc_save_done) += 1;
20316 save_insn = emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode,
20317 TOC_REGNUM, sp_offset + 5 * reg_size,
20320 emit_label (toc_save_done);
20322 /* ??? If we leave SAVE_INSN as marked as saving R2, then we'll
20323 have a CFG that has different saves along different paths.
20324 Move the note to a dummy blockage insn, which describes that
20325 R2 is unconditionally saved after the label. */
20326 /* ??? An alternate representation might be a special insn pattern
20327 containing both the branch and the store. That might let the
20328 code that minimizes the number of DW_CFA_advance opcodes better
20329 freedom in placing the annotations. */
20330 note = find_reg_note (save_insn, REG_FRAME_RELATED_EXPR, NULL);
20332 remove_note (save_insn, note);
20333 RTX_FRAME_RELATED_P (save_insn) = 0;
20335 join_insn = emit_insn (gen_blockage ());
20336 REG_NOTES (join_insn) = note;
20337 RTX_FRAME_RELATED_P (join_insn) = 1;
20339 if (using_static_chain_p)
20340 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, 0));
20343 /* Save CR if we use any that must be preserved. */
20344 if (!WORLD_SAVE_P (info) && info->cr_save_p)
20346 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20347 GEN_INT (info->cr_save_offset + sp_offset));
20348 rtx mem = gen_frame_mem (SImode, addr);
20349 /* See the large comment above about why CR2_REGNO is used. */
20350 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
20352 /* If r12 was used to hold the original sp, copy cr into r0 now
20354 if (REGNO (frame_reg_rtx) == 12)
20358 cr_save_rtx = gen_rtx_REG (SImode, 0);
20359 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20360 RTX_FRAME_RELATED_P (insn) = 1;
20361 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
20362 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20364 insn = emit_move_insn (mem, cr_save_rtx);
20366 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20367 NULL_RTX, NULL_RTX);
20370 /* Update stack and set back pointer unless this is V.4,
20371 for which it was done previously. */
20372 if (!WORLD_SAVE_P (info) && info->push_p
20373 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
20375 rtx copy_reg = NULL;
20377 if (info->total_size < 32767)
20378 sp_offset = info->total_size;
20379 else if (info->altivec_size != 0
20380 || info->vrsave_mask != 0)
20382 copy_reg = frame_ptr_rtx;
20383 frame_reg_rtx = copy_reg;
20386 sp_offset = info->total_size;
20387 rs6000_emit_allocate_stack (info->total_size, copy_reg);
20388 if (frame_reg_rtx != sp_reg_rtx)
20389 rs6000_emit_stack_tie ();
20392 /* Set frame pointer, if needed. */
20393 if (frame_pointer_needed)
20395 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
20397 RTX_FRAME_RELATED_P (insn) = 1;
20400 /* Save AltiVec registers if needed. Save here because the red zone does
20401 not include AltiVec registers. */
20402 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
20406 /* There should be a non inline version of this, for when we
20407 are saving lots of vector registers. */
20408 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20409 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20411 rtx areg, savereg, mem;
20414 offset = info->altivec_save_offset + sp_offset
20415 + 16 * (i - info->first_altivec_reg_save);
20417 savereg = gen_rtx_REG (V4SImode, i);
20419 areg = gen_rtx_REG (Pmode, 0);
20420 emit_move_insn (areg, GEN_INT (offset));
20422 /* AltiVec addressing mode is [reg+reg]. */
20423 mem = gen_frame_mem (V4SImode,
20424 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
20426 insn = emit_move_insn (mem, savereg);
20428 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20429 areg, GEN_INT (offset));
20433 /* VRSAVE is a bit vector representing which AltiVec registers
20434 are used. The OS uses this to determine which vector
20435 registers to save on a context switch. We need to save
20436 VRSAVE on the stack frame, add whatever AltiVec registers we
20437 used in this function, and do the corresponding magic in the
20440 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
20441 && info->vrsave_mask != 0)
20443 rtx reg, mem, vrsave;
20446 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
20447 as frame_reg_rtx and r11 as the static chain pointer for
20448 nested functions. */
20449 reg = gen_rtx_REG (SImode, 0);
20450 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
20452 emit_insn (gen_get_vrsave_internal (reg));
20454 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
20456 if (!WORLD_SAVE_P (info))
20459 offset = info->vrsave_save_offset + sp_offset;
20460 mem = gen_frame_mem (SImode,
20461 gen_rtx_PLUS (Pmode, frame_reg_rtx,
20462 GEN_INT (offset)));
20463 insn = emit_move_insn (mem, reg);
20466 /* Include the registers in the mask. */
20467 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
20469 insn = emit_insn (generate_set_vrsave (reg, info, 0));
20472 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
20473 if (!TARGET_SINGLE_PIC_BASE
20474 && ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
20475 || (DEFAULT_ABI == ABI_V4
20476 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
20477 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))))
20479 /* If emit_load_toc_table will use the link register, we need to save
20480 it. We use R12 for this purpose because emit_load_toc_table
20481 can use register 0. This allows us to use a plain 'blr' to return
20482 from the procedure more often. */
20483 int save_LR_around_toc_setup = (TARGET_ELF
20484 && DEFAULT_ABI != ABI_AIX
20486 && ! info->lr_save_p
20487 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
20488 if (save_LR_around_toc_setup)
20490 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
20492 insn = emit_move_insn (frame_ptr_rtx, lr);
20493 RTX_FRAME_RELATED_P (insn) = 1;
20495 rs6000_emit_load_toc_table (TRUE);
20497 insn = emit_move_insn (lr, frame_ptr_rtx);
20498 add_reg_note (insn, REG_CFA_RESTORE, lr);
20499 RTX_FRAME_RELATED_P (insn) = 1;
20502 rs6000_emit_load_toc_table (TRUE);
20506 if (!TARGET_SINGLE_PIC_BASE
20507 && DEFAULT_ABI == ABI_DARWIN
20508 && flag_pic && crtl->uses_pic_offset_table)
20510 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
20511 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
20513 /* Save and restore LR locally around this call (in R0). */
20514 if (!info->lr_save_p)
20515 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
20517 emit_insn (gen_load_macho_picbase (src));
20519 emit_move_insn (gen_rtx_REG (Pmode,
20520 RS6000_PIC_OFFSET_TABLE_REGNUM),
20523 if (!info->lr_save_p)
20524 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
20528 /* If we need to, save the TOC register after doing the stack setup.
20529 Do not emit eh frame info for this save. The unwinder wants info,
20530 conceptually attached to instructions in this function, about
20531 register values in the caller of this function. This R2 may have
20532 already been changed from the value in the caller.
20533 We don't attempt to write accurate DWARF EH frame info for R2
20534 because code emitted by gcc for a (non-pointer) function call
20535 doesn't save and restore R2. Instead, R2 is managed out-of-line
20536 by a linker generated plt call stub when the function resides in
20537 a shared library. This behaviour is costly to describe in DWARF,
20538 both in terms of the size of DWARF info and the time taken in the
20539 unwinder to interpret it. R2 changes, apart from the
20540 calls_eh_return case earlier in this function, are handled by
20541 linux-unwind.h frob_update_context. */
20542 if (rs6000_save_toc_in_prologue_p ())
20544 rtx addr = gen_rtx_PLUS (Pmode, sp_reg_rtx, GEN_INT (5 * reg_size));
20545 rtx mem = gen_frame_mem (reg_mode, addr);
20546 emit_move_insn (mem, gen_rtx_REG (reg_mode, TOC_REGNUM));
20550 /* Write function prologue. */
20553 rs6000_output_function_prologue (FILE *file,
20554 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
20556 rs6000_stack_t *info = rs6000_stack_info ();
20558 if (TARGET_DEBUG_STACK)
20559 debug_stack_info (info);
20561 /* Write .extern for any function we will call to save and restore
20563 if (info->first_fp_reg_save < 64
20567 int regno = info->first_fp_reg_save - 32;
20569 if ((info->savres_strategy & SAVE_INLINE_FPRS) == 0)
20571 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
20572 /*gpr=*/false, /*lr=*/false);
20573 fprintf (file, "\t.extern %s\n", name);
20575 if ((info->savres_strategy & REST_INLINE_FPRS) == 0)
20577 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
20578 /*gpr=*/false, /*lr=*/true);
20579 fprintf (file, "\t.extern %s\n", name);
20583 /* Write .extern for AIX common mode routines, if needed. */
20584 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
20586 fputs ("\t.extern __mulh\n", file);
20587 fputs ("\t.extern __mull\n", file);
20588 fputs ("\t.extern __divss\n", file);
20589 fputs ("\t.extern __divus\n", file);
20590 fputs ("\t.extern __quoss\n", file);
20591 fputs ("\t.extern __quous\n", file);
20592 common_mode_defined = 1;
20595 rs6000_pic_labelno++;
20598 /* Non-zero if vmx regs are restored before the frame pop, zero if
20599 we restore after the pop when possible. */
20600 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
20602 /* Reload CR from REG. */
20605 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
20610 if (using_mfcr_multiple)
20612 for (i = 0; i < 8; i++)
20613 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20615 gcc_assert (count);
20618 if (using_mfcr_multiple && count > 1)
20623 p = rtvec_alloc (count);
20626 for (i = 0; i < 8; i++)
20627 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20629 rtvec r = rtvec_alloc (2);
20630 RTVEC_ELT (r, 0) = reg;
20631 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
20632 RTVEC_ELT (p, ndx) =
20633 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
20634 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
20637 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20638 gcc_assert (ndx == count);
20641 for (i = 0; i < 8; i++)
20642 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20644 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
20650 /* Return true if OFFSET from stack pointer can be clobbered by signals.
20651 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
20652 below stack pointer not cloberred by signals. */
20655 offset_below_red_zone_p (HOST_WIDE_INT offset)
20657 return offset < (DEFAULT_ABI == ABI_V4
20659 : TARGET_32BIT ? -220 : -288);
20662 /* Append CFA_RESTORES to any existing REG_NOTES on the last insn. */
20665 emit_cfa_restores (rtx cfa_restores)
20667 rtx insn = get_last_insn ();
20668 rtx *loc = ®_NOTES (insn);
20671 loc = &XEXP (*loc, 1);
20672 *loc = cfa_restores;
20673 RTX_FRAME_RELATED_P (insn) = 1;
20676 /* Emit function epilogue as insns. */
20679 rs6000_emit_epilogue (int sibcall)
20681 rs6000_stack_t *info;
20682 int restoring_GPRs_inline;
20683 int restoring_FPRs_inline;
20684 int using_load_multiple;
20685 int using_mtcr_multiple;
20686 int use_backchain_to_restore_sp;
20690 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
20691 rtx frame_reg_rtx = sp_reg_rtx;
20692 rtx cfa_restores = NULL_RTX;
20694 rtx cr_save_reg = NULL_RTX;
20695 enum machine_mode reg_mode = Pmode;
20696 int reg_size = TARGET_32BIT ? 4 : 8;
20699 info = rs6000_stack_info ();
20701 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
20703 reg_mode = V2SImode;
20707 strategy = info->savres_strategy;
20708 using_load_multiple = strategy & SAVRES_MULTIPLE;
20709 restoring_FPRs_inline = sibcall || (strategy & REST_INLINE_FPRS);
20710 restoring_GPRs_inline = sibcall || (strategy & REST_INLINE_GPRS);
20711 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
20712 || rs6000_cpu == PROCESSOR_PPC603
20713 || rs6000_cpu == PROCESSOR_PPC750
20715 /* Restore via the backchain when we have a large frame, since this
20716 is more efficient than an addis, addi pair. The second condition
20717 here will not trigger at the moment; We don't actually need a
20718 frame pointer for alloca, but the generic parts of the compiler
20719 give us one anyway. */
20720 use_backchain_to_restore_sp = (info->total_size > 32767 - info->lr_save_offset
20721 || (cfun->calls_alloca
20722 && !frame_pointer_needed));
20723 restore_lr = (info->lr_save_p
20724 && (restoring_FPRs_inline
20725 || (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR))
20726 && (restoring_GPRs_inline
20727 || info->first_fp_reg_save < 64));
20729 if (WORLD_SAVE_P (info))
20733 const char *alloc_rname;
20736 /* eh_rest_world_r10 will return to the location saved in the LR
20737 stack slot (which is not likely to be our caller.)
20738 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
20739 rest_world is similar, except any R10 parameter is ignored.
20740 The exception-handling stuff that was here in 2.95 is no
20741 longer necessary. */
20745 + 32 - info->first_gp_reg_save
20746 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
20747 + 63 + 1 - info->first_fp_reg_save);
20749 strcpy (rname, ((crtl->calls_eh_return) ?
20750 "*eh_rest_world_r10" : "*rest_world"));
20751 alloc_rname = ggc_strdup (rname);
20754 RTVEC_ELT (p, j++) = ret_rtx;
20755 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
20756 gen_rtx_REG (Pmode,
20759 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
20760 /* The instruction pattern requires a clobber here;
20761 it is shared with the restVEC helper. */
20763 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
20766 /* CR register traditionally saved as CR2. */
20767 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
20768 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20769 GEN_INT (info->cr_save_offset));
20770 rtx mem = gen_frame_mem (reg_mode, addr);
20772 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20774 if (flag_shrink_wrap)
20776 cfa_restores = alloc_reg_note (REG_CFA_RESTORE,
20777 gen_rtx_REG (Pmode, LR_REGNO),
20779 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores);
20783 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20785 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20786 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20787 GEN_INT (info->gp_save_offset
20789 rtx mem = gen_frame_mem (reg_mode, addr);
20791 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20792 if (flag_shrink_wrap)
20793 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores);
20795 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
20797 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
20798 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20799 GEN_INT (info->altivec_save_offset
20801 rtx mem = gen_frame_mem (V4SImode, addr);
20803 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20804 if (flag_shrink_wrap)
20805 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores);
20807 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
20809 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20810 ? DFmode : SFmode),
20811 info->first_fp_reg_save + i);
20812 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20813 GEN_INT (info->fp_save_offset
20815 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20816 ? DFmode : SFmode), addr);
20818 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20819 if (flag_shrink_wrap)
20820 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores);
20823 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
20825 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
20827 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
20829 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
20831 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
20832 insn = emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
20834 if (flag_shrink_wrap)
20836 REG_NOTES (insn) = cfa_restores;
20837 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
20838 RTX_FRAME_RELATED_P (insn) = 1;
20843 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
20845 sp_offset = info->total_size;
20847 /* Restore AltiVec registers if we must do so before adjusting the
20849 if (TARGET_ALTIVEC_ABI
20850 && info->altivec_size != 0
20851 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20852 || (DEFAULT_ABI != ABI_V4
20853 && offset_below_red_zone_p (info->altivec_save_offset))))
20857 if (use_backchain_to_restore_sp)
20859 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20860 emit_move_insn (frame_reg_rtx,
20861 gen_rtx_MEM (Pmode, sp_reg_rtx));
20864 else if (frame_pointer_needed)
20865 frame_reg_rtx = hard_frame_pointer_rtx;
20867 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20868 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20870 rtx addr, areg, mem, reg;
20872 areg = gen_rtx_REG (Pmode, 0);
20874 (areg, GEN_INT (info->altivec_save_offset
20876 + 16 * (i - info->first_altivec_reg_save)));
20878 /* AltiVec addressing mode is [reg+reg]. */
20879 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
20880 mem = gen_frame_mem (V4SImode, addr);
20882 reg = gen_rtx_REG (V4SImode, i);
20883 emit_move_insn (reg, mem);
20884 if (flag_shrink_wrap
20885 || offset_below_red_zone_p (info->altivec_save_offset
20886 + (i - info->first_altivec_reg_save)
20888 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20893 /* Restore VRSAVE if we must do so before adjusting the stack. */
20895 && TARGET_ALTIVEC_VRSAVE
20896 && info->vrsave_mask != 0
20897 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20898 || (DEFAULT_ABI != ABI_V4
20899 && offset_below_red_zone_p (info->vrsave_save_offset))))
20901 rtx addr, mem, reg;
20903 if (frame_reg_rtx == sp_reg_rtx)
20905 if (use_backchain_to_restore_sp)
20907 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20908 emit_move_insn (frame_reg_rtx,
20909 gen_rtx_MEM (Pmode, sp_reg_rtx));
20912 else if (frame_pointer_needed)
20913 frame_reg_rtx = hard_frame_pointer_rtx;
20916 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20917 GEN_INT (info->vrsave_save_offset + sp_offset));
20918 mem = gen_frame_mem (SImode, addr);
20919 reg = gen_rtx_REG (SImode, 12);
20920 emit_move_insn (reg, mem);
20922 emit_insn (generate_set_vrsave (reg, info, 1));
20926 /* If we have a large stack frame, restore the old stack pointer
20927 using the backchain. */
20928 if (use_backchain_to_restore_sp)
20930 if (frame_reg_rtx == sp_reg_rtx)
20932 /* Under V.4, don't reset the stack pointer until after we're done
20933 loading the saved registers. */
20934 if (DEFAULT_ABI == ABI_V4)
20935 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20937 insn = emit_move_insn (frame_reg_rtx,
20938 gen_rtx_MEM (Pmode, sp_reg_rtx));
20941 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20942 && DEFAULT_ABI == ABI_V4)
20943 /* frame_reg_rtx has been set up by the altivec restore. */
20947 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
20948 frame_reg_rtx = sp_reg_rtx;
20951 /* If we have a frame pointer, we can restore the old stack pointer
20953 else if (frame_pointer_needed)
20955 frame_reg_rtx = sp_reg_rtx;
20956 if (DEFAULT_ABI == ABI_V4)
20957 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20958 /* Prevent reordering memory accesses against stack pointer restore. */
20959 else if (cfun->calls_alloca
20960 || offset_below_red_zone_p (-info->total_size))
20962 rtx mem1 = gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx);
20963 rtx mem2 = gen_rtx_MEM (BLKmode, sp_reg_rtx);
20964 MEM_NOTRAP_P (mem1) = 1;
20965 MEM_NOTRAP_P (mem2) = 1;
20966 emit_insn (gen_frame_tie (mem1, mem2));
20969 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
20970 GEN_INT (info->total_size)));
20973 else if (info->push_p
20974 && DEFAULT_ABI != ABI_V4
20975 && !crtl->calls_eh_return)
20977 /* Prevent reordering memory accesses against stack pointer restore. */
20978 if (cfun->calls_alloca
20979 || offset_below_red_zone_p (-info->total_size))
20981 rtx mem = gen_rtx_MEM (BLKmode, sp_reg_rtx);
20982 MEM_NOTRAP_P (mem) = 1;
20983 emit_insn (gen_stack_tie (mem));
20985 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
20986 GEN_INT (info->total_size)));
20989 if (insn && frame_reg_rtx == sp_reg_rtx)
20993 REG_NOTES (insn) = cfa_restores;
20994 cfa_restores = NULL_RTX;
20996 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
20997 RTX_FRAME_RELATED_P (insn) = 1;
21000 /* Restore AltiVec registers if we have not done so already. */
21001 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21002 && TARGET_ALTIVEC_ABI
21003 && info->altivec_size != 0
21004 && (DEFAULT_ABI == ABI_V4
21005 || !offset_below_red_zone_p (info->altivec_save_offset)))
21009 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
21010 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
21012 rtx addr, areg, mem, reg;
21014 areg = gen_rtx_REG (Pmode, 0);
21016 (areg, GEN_INT (info->altivec_save_offset
21018 + 16 * (i - info->first_altivec_reg_save)));
21020 /* AltiVec addressing mode is [reg+reg]. */
21021 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
21022 mem = gen_frame_mem (V4SImode, addr);
21024 reg = gen_rtx_REG (V4SImode, i);
21025 emit_move_insn (reg, mem);
21026 if (DEFAULT_ABI == ABI_V4 || flag_shrink_wrap)
21027 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21032 /* Restore VRSAVE if we have not done so already. */
21033 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21035 && TARGET_ALTIVEC_VRSAVE
21036 && info->vrsave_mask != 0
21037 && (DEFAULT_ABI == ABI_V4
21038 || !offset_below_red_zone_p (info->vrsave_save_offset)))
21040 rtx addr, mem, reg;
21042 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21043 GEN_INT (info->vrsave_save_offset + sp_offset));
21044 mem = gen_frame_mem (SImode, addr);
21045 reg = gen_rtx_REG (SImode, 12);
21046 emit_move_insn (reg, mem);
21048 emit_insn (generate_set_vrsave (reg, info, 1));
21051 /* Get the old lr if we saved it. If we are restoring registers
21052 out-of-line, then the out-of-line routines can do this for us. */
21053 if (restore_lr && restoring_GPRs_inline)
21055 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21056 info->lr_save_offset + sp_offset);
21058 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21061 /* Get the old cr if we saved it. */
21062 if (info->cr_save_p)
21064 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21065 GEN_INT (info->cr_save_offset + sp_offset));
21066 rtx mem = gen_frame_mem (SImode, addr);
21068 cr_save_reg = gen_rtx_REG (SImode,
21069 DEFAULT_ABI == ABI_AIX
21070 && !restoring_GPRs_inline
21071 && info->first_fp_reg_save < 64
21073 emit_move_insn (cr_save_reg, mem);
21076 /* Set LR here to try to overlap restores below. */
21077 if (restore_lr && restoring_GPRs_inline)
21078 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21079 gen_rtx_REG (Pmode, 0));
21081 /* Load exception handler data registers, if needed. */
21082 if (crtl->calls_eh_return)
21084 unsigned int i, regno;
21088 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21089 GEN_INT (sp_offset + 5 * reg_size));
21090 rtx mem = gen_frame_mem (reg_mode, addr);
21092 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
21099 regno = EH_RETURN_DATA_REGNO (i);
21100 if (regno == INVALID_REGNUM)
21103 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
21104 info->ehrd_offset + sp_offset
21105 + reg_size * (int) i);
21107 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
21111 /* Restore GPRs. This is done as a PARALLEL if we are using
21112 the load-multiple instructions. */
21114 && info->spe_64bit_regs_used
21115 && info->first_gp_reg_save != 32)
21117 /* Determine whether we can address all of the registers that need
21118 to be saved with an offset from the stack pointer that fits in
21119 the small const field for SPE memory instructions. */
21120 int spe_regs_addressable_via_sp
21121 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
21122 + (32 - info->first_gp_reg_save - 1) * reg_size)
21123 && restoring_GPRs_inline);
21126 if (spe_regs_addressable_via_sp)
21127 spe_offset = info->spe_gp_save_offset + sp_offset;
21130 rtx old_frame_reg_rtx = frame_reg_rtx;
21131 /* Make r11 point to the start of the SPE save area. We worried about
21132 not clobbering it when we were saving registers in the prologue.
21133 There's no need to worry here because the static chain is passed
21134 anew to every function. */
21135 int ool_adjust = (restoring_GPRs_inline
21137 : (info->first_gp_reg_save
21138 - (FIRST_SAVRES_REGISTER + 1)) * 8);
21140 if (frame_reg_rtx == sp_reg_rtx)
21141 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21142 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
21143 GEN_INT (info->spe_gp_save_offset
21146 /* Keep the invariant that frame_reg_rtx + sp_offset points
21147 at the top of the stack frame. */
21148 sp_offset = -info->spe_gp_save_offset;
21153 if (restoring_GPRs_inline)
21155 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21156 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21158 rtx offset, addr, mem, reg;
21160 /* We're doing all this to ensure that the immediate offset
21161 fits into the immediate field of 'evldd'. */
21162 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
21164 offset = GEN_INT (spe_offset + reg_size * i);
21165 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
21166 mem = gen_rtx_MEM (V2SImode, addr);
21167 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21169 emit_move_insn (reg, mem);
21173 rs6000_emit_savres_rtx (info, gen_rtx_REG (Pmode, 11),
21175 /*savep=*/false, /*gpr=*/true,
21178 else if (!restoring_GPRs_inline)
21180 /* We are jumping to an out-of-line function. */
21181 bool can_use_exit = info->first_fp_reg_save == 64;
21183 /* Emit stack reset code if we need it. */
21186 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21187 sp_offset, can_use_exit);
21188 if (DEFAULT_ABI == ABI_DARWIN)
21189 /* we only need a copy, no fprs were saved. */
21190 emit_move_insn (gen_rtx_REG (reg_mode, 11), frame_reg_rtx);
21192 if (info->cr_save_p)
21193 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21197 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
21200 GEN_INT (sp_offset - info->fp_size)));
21201 if (REGNO (frame_reg_rtx) == 11)
21202 sp_offset += info->fp_size;
21205 rs6000_emit_savres_rtx (info, frame_reg_rtx,
21206 info->gp_save_offset, reg_mode,
21207 /*savep=*/false, /*gpr=*/true,
21208 /*lr=*/can_use_exit);
21210 else if (using_load_multiple)
21213 p = rtvec_alloc (32 - info->first_gp_reg_save);
21214 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21216 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21217 GEN_INT (info->gp_save_offset
21220 rtx mem = gen_frame_mem (reg_mode, addr);
21221 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21223 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
21225 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
21229 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21230 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21232 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21233 GEN_INT (info->gp_save_offset
21236 rtx mem = gen_frame_mem (reg_mode, addr);
21237 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21239 emit_move_insn (reg, mem);
21243 if (DEFAULT_ABI == ABI_V4 || flag_shrink_wrap)
21245 /* If the frame pointer was used then we can't delay emitting
21246 a REG_CFA_DEF_CFA note. This must happen on the insn that
21247 restores the frame pointer, r31. We may have already emitted
21248 a REG_CFA_DEF_CFA note, but that's OK; A duplicate is
21249 discarded by dwarf2cfi.c/dwarf2out.c, and in any case would
21250 be harmless if emitted. */
21251 if (frame_pointer_needed)
21253 insn = get_last_insn ();
21254 add_reg_note (insn, REG_CFA_DEF_CFA,
21255 plus_constant (frame_reg_rtx, sp_offset));
21256 RTX_FRAME_RELATED_P (insn) = 1;
21259 /* Set up cfa_restores. We always need these when
21260 shrink-wrapping. If not shrink-wrapping then we only need
21261 the cfa_restore when the stack location is no longer valid.
21262 The cfa_restores must be emitted on or before the insn that
21263 invalidates the stack, and of course must not be emitted
21264 before the insn that actually does the restore. The latter
21265 is why the LR cfa_restore condition below is a little
21266 complicated. It's also why it is a bad idea to emit the
21267 cfa_restores as a group on the last instruction here that
21268 actually does a restore: That insn may be reordered with
21269 respect to others doing restores. */
21270 if (info->cr_save_p)
21271 cfa_restores = alloc_reg_note (REG_CFA_RESTORE,
21272 gen_rtx_REG (SImode, CR2_REGNO),
21274 if (flag_shrink_wrap
21276 || (info->lr_save_p
21277 && !restoring_GPRs_inline
21278 && info->first_fp_reg_save == 64)))
21279 cfa_restores = alloc_reg_note (REG_CFA_RESTORE,
21280 gen_rtx_REG (Pmode, LR_REGNO),
21283 for (i = info->first_gp_reg_save; i < 32; i++)
21284 if (!restoring_GPRs_inline
21285 || using_load_multiple
21286 || rs6000_reg_live_or_pic_offset_p (i))
21288 rtx reg = gen_rtx_REG (reg_mode, i);
21290 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores);
21294 if (!restoring_GPRs_inline
21295 && info->first_fp_reg_save == 64)
21297 /* We are jumping to an out-of-line function. */
21299 emit_cfa_restores (cfa_restores);
21303 if (restore_lr && !restoring_GPRs_inline)
21305 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21306 info->lr_save_offset + sp_offset);
21308 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21309 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21310 gen_rtx_REG (Pmode, 0));
21313 /* Restore fpr's if we need to do it without calling a function. */
21314 if (restoring_FPRs_inline)
21315 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21316 if ((df_regs_ever_live_p (info->first_fp_reg_save + i)
21317 && !call_used_regs[info->first_fp_reg_save + i]))
21319 rtx addr, mem, reg;
21320 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21321 GEN_INT (info->fp_save_offset
21324 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21325 ? DFmode : SFmode), addr);
21326 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21327 ? DFmode : SFmode),
21328 info->first_fp_reg_save + i);
21330 emit_move_insn (reg, mem);
21331 if (DEFAULT_ABI == ABI_V4 || flag_shrink_wrap)
21332 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores);
21335 /* If we saved cr, restore it here. Just those that were used. */
21336 if (info->cr_save_p)
21337 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21339 /* If this is V.4, unwind the stack pointer after all of the loads
21341 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21342 sp_offset, !restoring_FPRs_inline);
21347 REG_NOTES (insn) = cfa_restores;
21348 cfa_restores = NULL_RTX;
21350 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
21351 RTX_FRAME_RELATED_P (insn) = 1;
21354 if (crtl->calls_eh_return)
21356 rtx sa = EH_RETURN_STACKADJ_RTX;
21357 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
21363 bool lr = (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
21364 if (! restoring_FPRs_inline)
21366 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
21367 RTVEC_ELT (p, 0) = ret_rtx;
21373 /* We can't hang the cfa_restores off a simple return,
21374 since the shrink-wrap code sometimes uses an existing
21375 return. This means there might be a path from
21376 pre-prologue code to this return, and dwarf2cfi code
21377 wants the eh_frame unwinder state to be the same on
21378 all paths to any point. So we need to emit the
21379 cfa_restores before the return. For -m64 we really
21380 don't need epilogue cfa_restores at all, except for
21381 this irritating dwarf2cfi with shrink-wrap
21382 requirement; The stack red-zone means eh_frame info
21383 from the prologue telling the unwinder to restore
21384 from the stack is perfectly good right to the end of
21386 emit_insn (gen_blockage ());
21387 emit_cfa_restores (cfa_restores);
21388 cfa_restores = NULL_RTX;
21390 p = rtvec_alloc (2);
21391 RTVEC_ELT (p, 0) = simple_return_rtx;
21394 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
21395 ? gen_rtx_USE (VOIDmode,
21396 gen_rtx_REG (Pmode, LR_REGNO))
21397 : gen_rtx_CLOBBER (VOIDmode,
21398 gen_rtx_REG (Pmode, LR_REGNO)));
21400 /* If we have to restore more than two FP registers, branch to the
21401 restore function. It will return to our caller. */
21402 if (! restoring_FPRs_inline)
21407 if ((DEFAULT_ABI == ABI_V4 || flag_shrink_wrap)
21409 cfa_restores = alloc_reg_note (REG_CFA_RESTORE,
21410 gen_rtx_REG (Pmode, LR_REGNO),
21413 sym = rs6000_savres_routine_sym (info,
21417 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
21418 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
21419 gen_rtx_REG (Pmode,
21420 DEFAULT_ABI == ABI_AIX
21422 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21424 rtx addr, mem, reg;
21426 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
21427 GEN_INT (info->fp_save_offset + 8 * i));
21428 mem = gen_frame_mem (DFmode, addr);
21429 reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
21431 RTVEC_ELT (p, i + 4) = gen_rtx_SET (VOIDmode, reg, mem);
21432 if (DEFAULT_ABI == ABI_V4 || flag_shrink_wrap)
21433 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21438 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
21444 /* Ensure the cfa_restores are hung off an insn that won't
21445 be reordered above other restores. */
21446 emit_insn (gen_blockage ());
21448 emit_cfa_restores (cfa_restores);
21452 /* Write function epilogue. */
21455 rs6000_output_function_epilogue (FILE *file,
21456 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
21459 macho_branch_islands ();
21460 /* Mach-O doesn't support labels at the end of objects, so if
21461 it looks like we might want one, insert a NOP. */
21463 rtx insn = get_last_insn ();
21464 rtx deleted_debug_label = NULL_RTX;
21467 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
21469 /* Don't insert a nop for NOTE_INSN_DELETED_DEBUG_LABEL
21470 notes only, instead set their CODE_LABEL_NUMBER to -1,
21471 otherwise there would be code generation differences
21472 in between -g and -g0. */
21473 if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_DELETED_DEBUG_LABEL)
21474 deleted_debug_label = insn;
21475 insn = PREV_INSN (insn);
21480 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
21481 fputs ("\tnop\n", file);
21482 else if (deleted_debug_label)
21483 for (insn = deleted_debug_label; insn; insn = NEXT_INSN (insn))
21484 if (NOTE_KIND (insn) == NOTE_INSN_DELETED_DEBUG_LABEL)
21485 CODE_LABEL_NUMBER (insn) = -1;
21489 /* Output a traceback table here. See /usr/include/sys/debug.h for info
21492 We don't output a traceback table if -finhibit-size-directive was
21493 used. The documentation for -finhibit-size-directive reads
21494 ``don't output a @code{.size} assembler directive, or anything
21495 else that would cause trouble if the function is split in the
21496 middle, and the two halves are placed at locations far apart in
21497 memory.'' The traceback table has this property, since it
21498 includes the offset from the start of the function to the
21499 traceback table itself.
21501 System V.4 Powerpc's (and the embedded ABI derived from it) use a
21502 different traceback table. */
21503 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
21504 && rs6000_traceback != traceback_none && !cfun->is_thunk)
21506 const char *fname = NULL;
21507 const char *language_string = lang_hooks.name;
21508 int fixed_parms = 0, float_parms = 0, parm_info = 0;
21510 int optional_tbtab;
21511 rs6000_stack_t *info = rs6000_stack_info ();
21513 if (rs6000_traceback == traceback_full)
21514 optional_tbtab = 1;
21515 else if (rs6000_traceback == traceback_part)
21516 optional_tbtab = 0;
21518 optional_tbtab = !optimize_size && !TARGET_ELF;
21520 if (optional_tbtab)
21522 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
21523 while (*fname == '.') /* V.4 encodes . in the name */
21526 /* Need label immediately before tbtab, so we can compute
21527 its offset from the function start. */
21528 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
21529 ASM_OUTPUT_LABEL (file, fname);
21532 /* The .tbtab pseudo-op can only be used for the first eight
21533 expressions, since it can't handle the possibly variable
21534 length fields that follow. However, if you omit the optional
21535 fields, the assembler outputs zeros for all optional fields
21536 anyways, giving each variable length field is minimum length
21537 (as defined in sys/debug.h). Thus we can not use the .tbtab
21538 pseudo-op at all. */
21540 /* An all-zero word flags the start of the tbtab, for debuggers
21541 that have to find it by searching forward from the entry
21542 point or from the current pc. */
21543 fputs ("\t.long 0\n", file);
21545 /* Tbtab format type. Use format type 0. */
21546 fputs ("\t.byte 0,", file);
21548 /* Language type. Unfortunately, there does not seem to be any
21549 official way to discover the language being compiled, so we
21550 use language_string.
21551 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
21552 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
21553 a number, so for now use 9. LTO and Go aren't assigned numbers
21554 either, so for now use 0. */
21555 if (! strcmp (language_string, "GNU C")
21556 || ! strcmp (language_string, "GNU GIMPLE")
21557 || ! strcmp (language_string, "GNU Go"))
21559 else if (! strcmp (language_string, "GNU F77")
21560 || ! strcmp (language_string, "GNU Fortran"))
21562 else if (! strcmp (language_string, "GNU Pascal"))
21564 else if (! strcmp (language_string, "GNU Ada"))
21566 else if (! strcmp (language_string, "GNU C++")
21567 || ! strcmp (language_string, "GNU Objective-C++"))
21569 else if (! strcmp (language_string, "GNU Java"))
21571 else if (! strcmp (language_string, "GNU Objective-C"))
21574 gcc_unreachable ();
21575 fprintf (file, "%d,", i);
21577 /* 8 single bit fields: global linkage (not set for C extern linkage,
21578 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
21579 from start of procedure stored in tbtab, internal function, function
21580 has controlled storage, function has no toc, function uses fp,
21581 function logs/aborts fp operations. */
21582 /* Assume that fp operations are used if any fp reg must be saved. */
21583 fprintf (file, "%d,",
21584 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
21586 /* 6 bitfields: function is interrupt handler, name present in
21587 proc table, function calls alloca, on condition directives
21588 (controls stack walks, 3 bits), saves condition reg, saves
21590 /* The `function calls alloca' bit seems to be set whenever reg 31 is
21591 set up as a frame pointer, even when there is no alloca call. */
21592 fprintf (file, "%d,",
21593 ((optional_tbtab << 6)
21594 | ((optional_tbtab & frame_pointer_needed) << 5)
21595 | (info->cr_save_p << 1)
21596 | (info->lr_save_p)));
21598 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
21600 fprintf (file, "%d,",
21601 (info->push_p << 7) | (64 - info->first_fp_reg_save));
21603 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
21604 fprintf (file, "%d,", (32 - first_reg_to_save ()));
21606 if (optional_tbtab)
21608 /* Compute the parameter info from the function decl argument
21611 int next_parm_info_bit = 31;
21613 for (decl = DECL_ARGUMENTS (current_function_decl);
21614 decl; decl = DECL_CHAIN (decl))
21616 rtx parameter = DECL_INCOMING_RTL (decl);
21617 enum machine_mode mode = GET_MODE (parameter);
21619 if (GET_CODE (parameter) == REG)
21621 if (SCALAR_FLOAT_MODE_P (mode))
21642 gcc_unreachable ();
21645 /* If only one bit will fit, don't or in this entry. */
21646 if (next_parm_info_bit > 0)
21647 parm_info |= (bits << (next_parm_info_bit - 1));
21648 next_parm_info_bit -= 2;
21652 fixed_parms += ((GET_MODE_SIZE (mode)
21653 + (UNITS_PER_WORD - 1))
21655 next_parm_info_bit -= 1;
21661 /* Number of fixed point parameters. */
21662 /* This is actually the number of words of fixed point parameters; thus
21663 an 8 byte struct counts as 2; and thus the maximum value is 8. */
21664 fprintf (file, "%d,", fixed_parms);
21666 /* 2 bitfields: number of floating point parameters (7 bits), parameters
21668 /* This is actually the number of fp registers that hold parameters;
21669 and thus the maximum value is 13. */
21670 /* Set parameters on stack bit if parameters are not in their original
21671 registers, regardless of whether they are on the stack? Xlc
21672 seems to set the bit when not optimizing. */
21673 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
21675 if (! optional_tbtab)
21678 /* Optional fields follow. Some are variable length. */
21680 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
21681 11 double float. */
21682 /* There is an entry for each parameter in a register, in the order that
21683 they occur in the parameter list. Any intervening arguments on the
21684 stack are ignored. If the list overflows a long (max possible length
21685 34 bits) then completely leave off all elements that don't fit. */
21686 /* Only emit this long if there was at least one parameter. */
21687 if (fixed_parms || float_parms)
21688 fprintf (file, "\t.long %d\n", parm_info);
21690 /* Offset from start of code to tb table. */
21691 fputs ("\t.long ", file);
21692 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
21693 RS6000_OUTPUT_BASENAME (file, fname);
21695 rs6000_output_function_entry (file, fname);
21698 /* Interrupt handler mask. */
21699 /* Omit this long, since we never set the interrupt handler bit
21702 /* Number of CTL (controlled storage) anchors. */
21703 /* Omit this long, since the has_ctl bit is never set above. */
21705 /* Displacement into stack of each CTL anchor. */
21706 /* Omit this list of longs, because there are no CTL anchors. */
21708 /* Length of function name. */
21711 fprintf (file, "\t.short %d\n", (int) strlen (fname));
21713 /* Function name. */
21714 assemble_string (fname, strlen (fname));
21716 /* Register for alloca automatic storage; this is always reg 31.
21717 Only emit this if the alloca bit was set above. */
21718 if (frame_pointer_needed)
21719 fputs ("\t.byte 31\n", file);
21721 fputs ("\t.align 2\n", file);
21725 /* A C compound statement that outputs the assembler code for a thunk
21726 function, used to implement C++ virtual function calls with
21727 multiple inheritance. The thunk acts as a wrapper around a virtual
21728 function, adjusting the implicit object parameter before handing
21729 control off to the real function.
21731 First, emit code to add the integer DELTA to the location that
21732 contains the incoming first argument. Assume that this argument
21733 contains a pointer, and is the one used to pass the `this' pointer
21734 in C++. This is the incoming argument *before* the function
21735 prologue, e.g. `%o0' on a sparc. The addition must preserve the
21736 values of all other incoming arguments.
21738 After the addition, emit code to jump to FUNCTION, which is a
21739 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
21740 not touch the return address. Hence returning from FUNCTION will
21741 return to whoever called the current `thunk'.
21743 The effect must be as if FUNCTION had been called directly with the
21744 adjusted first argument. This macro is responsible for emitting
21745 all of the code for a thunk function; output_function_prologue()
21746 and output_function_epilogue() are not invoked.
21748 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
21749 been extracted from it.) It might possibly be useful on some
21750 targets, but probably not.
21752 If you do not define this macro, the target-independent code in the
21753 C++ frontend will generate a less efficient heavyweight thunk that
21754 calls FUNCTION instead of jumping to it. The generic approach does
21755 not support varargs. */
21758 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
21759 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
21762 rtx this_rtx, insn, funexp;
21764 reload_completed = 1;
21765 epilogue_completed = 1;
21767 /* Mark the end of the (empty) prologue. */
21768 emit_note (NOTE_INSN_PROLOGUE_END);
21770 /* Find the "this" pointer. If the function returns a structure,
21771 the structure return pointer is in r3. */
21772 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
21773 this_rtx = gen_rtx_REG (Pmode, 4);
21775 this_rtx = gen_rtx_REG (Pmode, 3);
21777 /* Apply the constant offset, if required. */
21779 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
21781 /* Apply the offset from the vtable, if required. */
21784 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
21785 rtx tmp = gen_rtx_REG (Pmode, 12);
21787 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
21788 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
21790 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
21791 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
21795 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
21797 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
21799 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
21802 /* Generate a tail call to the target function. */
21803 if (!TREE_USED (function))
21805 assemble_external (function);
21806 TREE_USED (function) = 1;
21808 funexp = XEXP (DECL_RTL (function), 0);
21809 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
21812 if (MACHOPIC_INDIRECT)
21813 funexp = machopic_indirect_call_target (funexp);
21816 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
21817 generate sibcall RTL explicitly. */
21818 insn = emit_call_insn (
21819 gen_rtx_PARALLEL (VOIDmode,
21821 gen_rtx_CALL (VOIDmode,
21822 funexp, const0_rtx),
21823 gen_rtx_USE (VOIDmode, const0_rtx),
21824 gen_rtx_USE (VOIDmode,
21825 gen_rtx_REG (SImode,
21827 simple_return_rtx)));
21828 SIBLING_CALL_P (insn) = 1;
21831 /* Run just enough of rest_of_compilation to get the insns emitted.
21832 There's not really enough bulk here to make other passes such as
21833 instruction scheduling worth while. Note that use_thunk calls
21834 assemble_start_function and assemble_end_function. */
21835 insn = get_insns ();
21836 insn_locators_alloc ();
21837 shorten_branches (insn);
21838 final_start_function (insn, file, 1);
21839 final (insn, file, 1);
21840 final_end_function ();
21842 reload_completed = 0;
21843 epilogue_completed = 0;
21846 /* A quick summary of the various types of 'constant-pool tables'
21849 Target Flags Name One table per
21850 AIX (none) AIX TOC object file
21851 AIX -mfull-toc AIX TOC object file
21852 AIX -mminimal-toc AIX minimal TOC translation unit
21853 SVR4/EABI (none) SVR4 SDATA object file
21854 SVR4/EABI -fpic SVR4 pic object file
21855 SVR4/EABI -fPIC SVR4 PIC translation unit
21856 SVR4/EABI -mrelocatable EABI TOC function
21857 SVR4/EABI -maix AIX TOC object file
21858 SVR4/EABI -maix -mminimal-toc
21859 AIX minimal TOC translation unit
21861 Name Reg. Set by entries contains:
21862 made by addrs? fp? sum?
21864 AIX TOC 2 crt0 as Y option option
21865 AIX minimal TOC 30 prolog gcc Y Y option
21866 SVR4 SDATA 13 crt0 gcc N Y N
21867 SVR4 pic 30 prolog ld Y not yet N
21868 SVR4 PIC 30 prolog gcc Y option option
21869 EABI TOC 30 prolog gcc Y option option
21873 /* Hash functions for the hash table. */
21876 rs6000_hash_constant (rtx k)
21878 enum rtx_code code = GET_CODE (k);
21879 enum machine_mode mode = GET_MODE (k);
21880 unsigned result = (code << 3) ^ mode;
21881 const char *format;
21884 format = GET_RTX_FORMAT (code);
21885 flen = strlen (format);
21891 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
21894 if (mode != VOIDmode)
21895 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
21907 for (; fidx < flen; fidx++)
21908 switch (format[fidx])
21913 const char *str = XSTR (k, fidx);
21914 len = strlen (str);
21915 result = result * 613 + len;
21916 for (i = 0; i < len; i++)
21917 result = result * 613 + (unsigned) str[i];
21922 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
21926 result = result * 613 + (unsigned) XINT (k, fidx);
21929 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
21930 result = result * 613 + (unsigned) XWINT (k, fidx);
21934 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
21935 result = result * 613 + (unsigned) (XWINT (k, fidx)
21942 gcc_unreachable ();
21949 toc_hash_function (const void *hash_entry)
21951 const struct toc_hash_struct *thc =
21952 (const struct toc_hash_struct *) hash_entry;
21953 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
21956 /* Compare H1 and H2 for equivalence. */
21959 toc_hash_eq (const void *h1, const void *h2)
21961 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
21962 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
21964 if (((const struct toc_hash_struct *) h1)->key_mode
21965 != ((const struct toc_hash_struct *) h2)->key_mode)
21968 return rtx_equal_p (r1, r2);
21971 /* These are the names given by the C++ front-end to vtables, and
21972 vtable-like objects. Ideally, this logic should not be here;
21973 instead, there should be some programmatic way of inquiring as
21974 to whether or not an object is a vtable. */
21976 #define VTABLE_NAME_P(NAME) \
21977 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
21978 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
21979 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
21980 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
21981 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
21983 #ifdef NO_DOLLAR_IN_LABEL
21984 /* Return a GGC-allocated character string translating dollar signs in
21985 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
21988 rs6000_xcoff_strip_dollar (const char *name)
21994 q = (const char *) strchr (name, '$');
21996 if (q == 0 || q == name)
21999 len = strlen (name);
22000 strip = XALLOCAVEC (char, len + 1);
22001 strcpy (strip, name);
22002 p = strip + (q - name);
22006 p = strchr (p + 1, '$');
22009 return ggc_alloc_string (strip, len);
22014 rs6000_output_symbol_ref (FILE *file, rtx x)
22016 /* Currently C++ toc references to vtables can be emitted before it
22017 is decided whether the vtable is public or private. If this is
22018 the case, then the linker will eventually complain that there is
22019 a reference to an unknown section. Thus, for vtables only,
22020 we emit the TOC reference to reference the symbol and not the
22022 const char *name = XSTR (x, 0);
22024 if (VTABLE_NAME_P (name))
22026 RS6000_OUTPUT_BASENAME (file, name);
22029 assemble_name (file, name);
22032 /* Output a TOC entry. We derive the entry name from what is being
22036 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
22039 const char *name = buf;
22041 HOST_WIDE_INT offset = 0;
22043 gcc_assert (!TARGET_NO_TOC);
22045 /* When the linker won't eliminate them, don't output duplicate
22046 TOC entries (this happens on AIX if there is any kind of TOC,
22047 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
22049 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
22051 struct toc_hash_struct *h;
22054 /* Create toc_hash_table. This can't be done at TARGET_OPTION_OVERRIDE
22055 time because GGC is not initialized at that point. */
22056 if (toc_hash_table == NULL)
22057 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
22058 toc_hash_eq, NULL);
22060 h = ggc_alloc_toc_hash_struct ();
22062 h->key_mode = mode;
22063 h->labelno = labelno;
22065 found = htab_find_slot (toc_hash_table, h, INSERT);
22066 if (*found == NULL)
22068 else /* This is indeed a duplicate.
22069 Set this label equal to that label. */
22071 fputs ("\t.set ", file);
22072 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22073 fprintf (file, "%d,", labelno);
22074 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22075 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
22081 /* If we're going to put a double constant in the TOC, make sure it's
22082 aligned properly when strict alignment is on. */
22083 if (GET_CODE (x) == CONST_DOUBLE
22084 && STRICT_ALIGNMENT
22085 && GET_MODE_BITSIZE (mode) >= 64
22086 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
22087 ASM_OUTPUT_ALIGN (file, 3);
22090 (*targetm.asm_out.internal_label) (file, "LC", labelno);
22092 /* Handle FP constants specially. Note that if we have a minimal
22093 TOC, things we put here aren't actually in the TOC, so we can allow
22095 if (GET_CODE (x) == CONST_DOUBLE &&
22096 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
22098 REAL_VALUE_TYPE rv;
22101 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22102 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22103 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
22105 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
22109 if (TARGET_MINIMAL_TOC)
22110 fputs (DOUBLE_INT_ASM_OP, file);
22112 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22113 k[0] & 0xffffffff, k[1] & 0xffffffff,
22114 k[2] & 0xffffffff, k[3] & 0xffffffff);
22115 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
22116 k[0] & 0xffffffff, k[1] & 0xffffffff,
22117 k[2] & 0xffffffff, k[3] & 0xffffffff);
22122 if (TARGET_MINIMAL_TOC)
22123 fputs ("\t.long ", file);
22125 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22126 k[0] & 0xffffffff, k[1] & 0xffffffff,
22127 k[2] & 0xffffffff, k[3] & 0xffffffff);
22128 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
22129 k[0] & 0xffffffff, k[1] & 0xffffffff,
22130 k[2] & 0xffffffff, k[3] & 0xffffffff);
22134 else if (GET_CODE (x) == CONST_DOUBLE &&
22135 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
22137 REAL_VALUE_TYPE rv;
22140 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22142 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22143 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
22145 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
22149 if (TARGET_MINIMAL_TOC)
22150 fputs (DOUBLE_INT_ASM_OP, file);
22152 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22153 k[0] & 0xffffffff, k[1] & 0xffffffff);
22154 fprintf (file, "0x%lx%08lx\n",
22155 k[0] & 0xffffffff, k[1] & 0xffffffff);
22160 if (TARGET_MINIMAL_TOC)
22161 fputs ("\t.long ", file);
22163 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22164 k[0] & 0xffffffff, k[1] & 0xffffffff);
22165 fprintf (file, "0x%lx,0x%lx\n",
22166 k[0] & 0xffffffff, k[1] & 0xffffffff);
22170 else if (GET_CODE (x) == CONST_DOUBLE &&
22171 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
22173 REAL_VALUE_TYPE rv;
22176 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22177 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22178 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
22180 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
22184 if (TARGET_MINIMAL_TOC)
22185 fputs (DOUBLE_INT_ASM_OP, file);
22187 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22188 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
22193 if (TARGET_MINIMAL_TOC)
22194 fputs ("\t.long ", file);
22196 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22197 fprintf (file, "0x%lx\n", l & 0xffffffff);
22201 else if (GET_MODE (x) == VOIDmode
22202 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
22204 unsigned HOST_WIDE_INT low;
22205 HOST_WIDE_INT high;
22207 if (GET_CODE (x) == CONST_DOUBLE)
22209 low = CONST_DOUBLE_LOW (x);
22210 high = CONST_DOUBLE_HIGH (x);
22213 #if HOST_BITS_PER_WIDE_INT == 32
22216 high = (low & 0x80000000) ? ~0 : 0;
22220 low = INTVAL (x) & 0xffffffff;
22221 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
22225 /* TOC entries are always Pmode-sized, but since this
22226 is a bigendian machine then if we're putting smaller
22227 integer constants in the TOC we have to pad them.
22228 (This is still a win over putting the constants in
22229 a separate constant pool, because then we'd have
22230 to have both a TOC entry _and_ the actual constant.)
22232 For a 32-bit target, CONST_INT values are loaded and shifted
22233 entirely within `low' and can be stored in one TOC entry. */
22235 /* It would be easy to make this work, but it doesn't now. */
22236 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
22238 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
22240 #if HOST_BITS_PER_WIDE_INT == 32
22241 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
22242 POINTER_SIZE, &low, &high, 0);
22245 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
22246 high = (HOST_WIDE_INT) low >> 32;
22253 if (TARGET_MINIMAL_TOC)
22254 fputs (DOUBLE_INT_ASM_OP, file);
22256 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22257 (long) high & 0xffffffff, (long) low & 0xffffffff);
22258 fprintf (file, "0x%lx%08lx\n",
22259 (long) high & 0xffffffff, (long) low & 0xffffffff);
22264 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
22266 if (TARGET_MINIMAL_TOC)
22267 fputs ("\t.long ", file);
22269 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22270 (long) high & 0xffffffff, (long) low & 0xffffffff);
22271 fprintf (file, "0x%lx,0x%lx\n",
22272 (long) high & 0xffffffff, (long) low & 0xffffffff);
22276 if (TARGET_MINIMAL_TOC)
22277 fputs ("\t.long ", file);
22279 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
22280 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
22286 if (GET_CODE (x) == CONST)
22288 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
22289 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
22291 base = XEXP (XEXP (x, 0), 0);
22292 offset = INTVAL (XEXP (XEXP (x, 0), 1));
22295 switch (GET_CODE (base))
22298 name = XSTR (base, 0);
22302 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
22303 CODE_LABEL_NUMBER (XEXP (base, 0)));
22307 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
22311 gcc_unreachable ();
22314 if (TARGET_MINIMAL_TOC)
22315 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
22318 fputs ("\t.tc ", file);
22319 RS6000_OUTPUT_BASENAME (file, name);
22322 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
22324 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
22326 fputs ("[TC],", file);
22329 /* Currently C++ toc references to vtables can be emitted before it
22330 is decided whether the vtable is public or private. If this is
22331 the case, then the linker will eventually complain that there is
22332 a TOC reference to an unknown section. Thus, for vtables only,
22333 we emit the TOC reference to reference the symbol and not the
22335 if (VTABLE_NAME_P (name))
22337 RS6000_OUTPUT_BASENAME (file, name);
22339 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
22340 else if (offset > 0)
22341 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
22344 output_addr_const (file, x);
22348 /* Output an assembler pseudo-op to write an ASCII string of N characters
22349 starting at P to FILE.
22351 On the RS/6000, we have to do this using the .byte operation and
22352 write out special characters outside the quoted string.
22353 Also, the assembler is broken; very long strings are truncated,
22354 so we must artificially break them up early. */
22357 output_ascii (FILE *file, const char *p, int n)
22360 int i, count_string;
22361 const char *for_string = "\t.byte \"";
22362 const char *for_decimal = "\t.byte ";
22363 const char *to_close = NULL;
22366 for (i = 0; i < n; i++)
22369 if (c >= ' ' && c < 0177)
22372 fputs (for_string, file);
22375 /* Write two quotes to get one. */
22383 for_decimal = "\"\n\t.byte ";
22387 if (count_string >= 512)
22389 fputs (to_close, file);
22391 for_string = "\t.byte \"";
22392 for_decimal = "\t.byte ";
22400 fputs (for_decimal, file);
22401 fprintf (file, "%d", c);
22403 for_string = "\n\t.byte \"";
22404 for_decimal = ", ";
22410 /* Now close the string if we have written one. Then end the line. */
22412 fputs (to_close, file);
22415 /* Generate a unique section name for FILENAME for a section type
22416 represented by SECTION_DESC. Output goes into BUF.
22418 SECTION_DESC can be any string, as long as it is different for each
22419 possible section type.
22421 We name the section in the same manner as xlc. The name begins with an
22422 underscore followed by the filename (after stripping any leading directory
22423 names) with the last period replaced by the string SECTION_DESC. If
22424 FILENAME does not contain a period, SECTION_DESC is appended to the end of
22428 rs6000_gen_section_name (char **buf, const char *filename,
22429 const char *section_desc)
22431 const char *q, *after_last_slash, *last_period = 0;
22435 after_last_slash = filename;
22436 for (q = filename; *q; q++)
22439 after_last_slash = q + 1;
22440 else if (*q == '.')
22444 len = strlen (after_last_slash) + strlen (section_desc) + 2;
22445 *buf = (char *) xmalloc (len);
22450 for (q = after_last_slash; *q; q++)
22452 if (q == last_period)
22454 strcpy (p, section_desc);
22455 p += strlen (section_desc);
22459 else if (ISALNUM (*q))
22463 if (last_period == 0)
22464 strcpy (p, section_desc);
22469 /* Emit profile function. */
22472 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
22474 /* Non-standard profiling for kernels, which just saves LR then calls
22475 _mcount without worrying about arg saves. The idea is to change
22476 the function prologue as little as possible as it isn't easy to
22477 account for arg save/restore code added just for _mcount. */
22478 if (TARGET_PROFILE_KERNEL)
22481 if (DEFAULT_ABI == ABI_AIX)
22483 #ifndef NO_PROFILE_COUNTERS
22484 # define NO_PROFILE_COUNTERS 0
22486 if (NO_PROFILE_COUNTERS)
22487 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22488 LCT_NORMAL, VOIDmode, 0);
22492 const char *label_name;
22495 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
22496 label_name = ggc_strdup ((*targetm.strip_name_encoding) (buf));
22497 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
22499 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22500 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
22503 else if (DEFAULT_ABI == ABI_DARWIN)
22505 const char *mcount_name = RS6000_MCOUNT;
22506 int caller_addr_regno = LR_REGNO;
22508 /* Be conservative and always set this, at least for now. */
22509 crtl->uses_pic_offset_table = 1;
22512 /* For PIC code, set up a stub and collect the caller's address
22513 from r0, which is where the prologue puts it. */
22514 if (MACHOPIC_INDIRECT
22515 && crtl->uses_pic_offset_table)
22516 caller_addr_regno = 0;
22518 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
22519 LCT_NORMAL, VOIDmode, 1,
22520 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
22524 /* Write function profiler code. */
22527 output_function_profiler (FILE *file, int labelno)
22531 switch (DEFAULT_ABI)
22534 gcc_unreachable ();
22539 warning (0, "no profiling of 64-bit code for this ABI");
22542 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
22543 fprintf (file, "\tmflr %s\n", reg_names[0]);
22544 if (NO_PROFILE_COUNTERS)
22546 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22547 reg_names[0], reg_names[1]);
22549 else if (TARGET_SECURE_PLT && flag_pic)
22551 if (TARGET_LINK_STACK)
22554 get_ppc476_thunk_name (name);
22555 asm_fprintf (file, "\tbl %s\n", name);
22558 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n");
22559 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22560 reg_names[0], reg_names[1]);
22561 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
22562 asm_fprintf (file, "\t{cau|addis} %s,%s,",
22563 reg_names[12], reg_names[12]);
22564 assemble_name (file, buf);
22565 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
22566 assemble_name (file, buf);
22567 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
22569 else if (flag_pic == 1)
22571 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
22572 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22573 reg_names[0], reg_names[1]);
22574 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
22575 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
22576 assemble_name (file, buf);
22577 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
22579 else if (flag_pic > 1)
22581 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22582 reg_names[0], reg_names[1]);
22583 /* Now, we need to get the address of the label. */
22584 if (TARGET_LINK_STACK)
22587 get_ppc476_thunk_name (name);
22588 asm_fprintf (file, "\tbl %s\n\tb 1f\n\t.long ", name);
22589 assemble_name (file, buf);
22590 fputs ("-.\n1:", file);
22591 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
22592 asm_fprintf (file, "\taddi %s,%s,4\n",
22593 reg_names[11], reg_names[11]);
22597 fputs ("\tbcl 20,31,1f\n\t.long ", file);
22598 assemble_name (file, buf);
22599 fputs ("-.\n1:", file);
22600 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
22602 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
22603 reg_names[0], reg_names[11]);
22604 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
22605 reg_names[0], reg_names[0], reg_names[11]);
22609 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
22610 assemble_name (file, buf);
22611 fputs ("@ha\n", file);
22612 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22613 reg_names[0], reg_names[1]);
22614 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
22615 assemble_name (file, buf);
22616 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
22619 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
22620 fprintf (file, "\tbl %s%s\n",
22621 RS6000_MCOUNT, flag_pic ? "@plt" : "");
22626 if (!TARGET_PROFILE_KERNEL)
22628 /* Don't do anything, done in output_profile_hook (). */
22632 gcc_assert (!TARGET_32BIT);
22634 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
22635 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
22637 if (cfun->static_chain_decl != NULL)
22639 asm_fprintf (file, "\tstd %s,24(%s)\n",
22640 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
22641 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
22642 asm_fprintf (file, "\tld %s,24(%s)\n",
22643 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
22646 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
22654 /* The following variable value is the last issued insn. */
22656 static rtx last_scheduled_insn;
22658 /* The following variable helps to balance issuing of load and
22659 store instructions */
22661 static int load_store_pendulum;
22663 /* Power4 load update and store update instructions are cracked into a
22664 load or store and an integer insn which are executed in the same cycle.
22665 Branches have their own dispatch slot which does not count against the
22666 GCC issue rate, but it changes the program flow so there are no other
22667 instructions to issue in this cycle. */
22670 rs6000_variable_issue_1 (rtx insn, int more)
22672 last_scheduled_insn = insn;
22673 if (GET_CODE (PATTERN (insn)) == USE
22674 || GET_CODE (PATTERN (insn)) == CLOBBER)
22676 cached_can_issue_more = more;
22677 return cached_can_issue_more;
22680 if (insn_terminates_group_p (insn, current_group))
22682 cached_can_issue_more = 0;
22683 return cached_can_issue_more;
22686 /* If no reservation, but reach here */
22687 if (recog_memoized (insn) < 0)
22690 if (rs6000_sched_groups)
22692 if (is_microcoded_insn (insn))
22693 cached_can_issue_more = 0;
22694 else if (is_cracked_insn (insn))
22695 cached_can_issue_more = more > 2 ? more - 2 : 0;
22697 cached_can_issue_more = more - 1;
22699 return cached_can_issue_more;
22702 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
22705 cached_can_issue_more = more - 1;
22706 return cached_can_issue_more;
22710 rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more)
22712 int r = rs6000_variable_issue_1 (insn, more);
22714 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r);
22718 /* Adjust the cost of a scheduling dependency. Return the new cost of
22719 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
22722 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
22724 enum attr_type attr_type;
22726 if (! recog_memoized (insn))
22729 switch (REG_NOTE_KIND (link))
22733 /* Data dependency; DEP_INSN writes a register that INSN reads
22734 some cycles later. */
22736 /* Separate a load from a narrower, dependent store. */
22737 if (rs6000_sched_groups
22738 && GET_CODE (PATTERN (insn)) == SET
22739 && GET_CODE (PATTERN (dep_insn)) == SET
22740 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
22741 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
22742 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
22743 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
22746 attr_type = get_attr_type (insn);
22751 /* Tell the first scheduling pass about the latency between
22752 a mtctr and bctr (and mtlr and br/blr). The first
22753 scheduling pass will not know about this latency since
22754 the mtctr instruction, which has the latency associated
22755 to it, will be generated by reload. */
22756 return TARGET_POWER ? 5 : 4;
22758 /* Leave some extra cycles between a compare and its
22759 dependent branch, to inhibit expensive mispredicts. */
22760 if ((rs6000_cpu_attr == CPU_PPC603
22761 || rs6000_cpu_attr == CPU_PPC604
22762 || rs6000_cpu_attr == CPU_PPC604E
22763 || rs6000_cpu_attr == CPU_PPC620
22764 || rs6000_cpu_attr == CPU_PPC630
22765 || rs6000_cpu_attr == CPU_PPC750
22766 || rs6000_cpu_attr == CPU_PPC7400
22767 || rs6000_cpu_attr == CPU_PPC7450
22768 || rs6000_cpu_attr == CPU_POWER4
22769 || rs6000_cpu_attr == CPU_POWER5
22770 || rs6000_cpu_attr == CPU_POWER7
22771 || rs6000_cpu_attr == CPU_CELL)
22772 && recog_memoized (dep_insn)
22773 && (INSN_CODE (dep_insn) >= 0))
22775 switch (get_attr_type (dep_insn))
22779 case TYPE_DELAYED_COMPARE:
22780 case TYPE_IMUL_COMPARE:
22781 case TYPE_LMUL_COMPARE:
22782 case TYPE_FPCOMPARE:
22783 case TYPE_CR_LOGICAL:
22784 case TYPE_DELAYED_CR:
22793 case TYPE_STORE_UX:
22795 case TYPE_FPSTORE_U:
22796 case TYPE_FPSTORE_UX:
22797 if ((rs6000_cpu == PROCESSOR_POWER6)
22798 && recog_memoized (dep_insn)
22799 && (INSN_CODE (dep_insn) >= 0))
22802 if (GET_CODE (PATTERN (insn)) != SET)
22803 /* If this happens, we have to extend this to schedule
22804 optimally. Return default for now. */
22807 /* Adjust the cost for the case where the value written
22808 by a fixed point operation is used as the address
22809 gen value on a store. */
22810 switch (get_attr_type (dep_insn))
22817 if (! store_data_bypass_p (dep_insn, insn))
22821 case TYPE_LOAD_EXT:
22822 case TYPE_LOAD_EXT_U:
22823 case TYPE_LOAD_EXT_UX:
22824 case TYPE_VAR_SHIFT_ROTATE:
22825 case TYPE_VAR_DELAYED_COMPARE:
22827 if (! store_data_bypass_p (dep_insn, insn))
22833 case TYPE_FAST_COMPARE:
22836 case TYPE_INSERT_WORD:
22837 case TYPE_INSERT_DWORD:
22838 case TYPE_FPLOAD_U:
22839 case TYPE_FPLOAD_UX:
22841 case TYPE_STORE_UX:
22842 case TYPE_FPSTORE_U:
22843 case TYPE_FPSTORE_UX:
22845 if (! store_data_bypass_p (dep_insn, insn))
22853 case TYPE_IMUL_COMPARE:
22854 case TYPE_LMUL_COMPARE:
22856 if (! store_data_bypass_p (dep_insn, insn))
22862 if (! store_data_bypass_p (dep_insn, insn))
22868 if (! store_data_bypass_p (dep_insn, insn))
22881 case TYPE_LOAD_EXT:
22882 case TYPE_LOAD_EXT_U:
22883 case TYPE_LOAD_EXT_UX:
22884 if ((rs6000_cpu == PROCESSOR_POWER6)
22885 && recog_memoized (dep_insn)
22886 && (INSN_CODE (dep_insn) >= 0))
22889 /* Adjust the cost for the case where the value written
22890 by a fixed point instruction is used within the address
22891 gen portion of a subsequent load(u)(x) */
22892 switch (get_attr_type (dep_insn))
22899 if (set_to_load_agen (dep_insn, insn))
22903 case TYPE_LOAD_EXT:
22904 case TYPE_LOAD_EXT_U:
22905 case TYPE_LOAD_EXT_UX:
22906 case TYPE_VAR_SHIFT_ROTATE:
22907 case TYPE_VAR_DELAYED_COMPARE:
22909 if (set_to_load_agen (dep_insn, insn))
22915 case TYPE_FAST_COMPARE:
22918 case TYPE_INSERT_WORD:
22919 case TYPE_INSERT_DWORD:
22920 case TYPE_FPLOAD_U:
22921 case TYPE_FPLOAD_UX:
22923 case TYPE_STORE_UX:
22924 case TYPE_FPSTORE_U:
22925 case TYPE_FPSTORE_UX:
22927 if (set_to_load_agen (dep_insn, insn))
22935 case TYPE_IMUL_COMPARE:
22936 case TYPE_LMUL_COMPARE:
22938 if (set_to_load_agen (dep_insn, insn))
22944 if (set_to_load_agen (dep_insn, insn))
22950 if (set_to_load_agen (dep_insn, insn))
22961 if ((rs6000_cpu == PROCESSOR_POWER6)
22962 && recog_memoized (dep_insn)
22963 && (INSN_CODE (dep_insn) >= 0)
22964 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
22971 /* Fall out to return default cost. */
22975 case REG_DEP_OUTPUT:
22976 /* Output dependency; DEP_INSN writes a register that INSN writes some
22978 if ((rs6000_cpu == PROCESSOR_POWER6)
22979 && recog_memoized (dep_insn)
22980 && (INSN_CODE (dep_insn) >= 0))
22982 attr_type = get_attr_type (insn);
22987 if (get_attr_type (dep_insn) == TYPE_FP)
22991 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
22999 /* Anti dependency; DEP_INSN reads a register that INSN writes some
23004 gcc_unreachable ();
23010 /* Debug version of rs6000_adjust_cost. */
23013 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
23015 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
23021 switch (REG_NOTE_KIND (link))
23023 default: dep = "unknown depencency"; break;
23024 case REG_DEP_TRUE: dep = "data dependency"; break;
23025 case REG_DEP_OUTPUT: dep = "output dependency"; break;
23026 case REG_DEP_ANTI: dep = "anti depencency"; break;
23030 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
23031 "%s, insn:\n", ret, cost, dep);
23039 /* The function returns a true if INSN is microcoded.
23040 Return false otherwise. */
23043 is_microcoded_insn (rtx insn)
23045 if (!insn || !NONDEBUG_INSN_P (insn)
23046 || GET_CODE (PATTERN (insn)) == USE
23047 || GET_CODE (PATTERN (insn)) == CLOBBER)
23050 if (rs6000_cpu_attr == CPU_CELL)
23051 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
23053 if (rs6000_sched_groups)
23055 enum attr_type type = get_attr_type (insn);
23056 if (type == TYPE_LOAD_EXT_U
23057 || type == TYPE_LOAD_EXT_UX
23058 || type == TYPE_LOAD_UX
23059 || type == TYPE_STORE_UX
23060 || type == TYPE_MFCR)
23067 /* The function returns true if INSN is cracked into 2 instructions
23068 by the processor (and therefore occupies 2 issue slots). */
23071 is_cracked_insn (rtx insn)
23073 if (!insn || !NONDEBUG_INSN_P (insn)
23074 || GET_CODE (PATTERN (insn)) == USE
23075 || GET_CODE (PATTERN (insn)) == CLOBBER)
23078 if (rs6000_sched_groups)
23080 enum attr_type type = get_attr_type (insn);
23081 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
23082 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
23083 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
23084 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
23085 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
23086 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
23087 || type == TYPE_IDIV || type == TYPE_LDIV
23088 || type == TYPE_INSERT_WORD)
23095 /* The function returns true if INSN can be issued only from
23096 the branch slot. */
23099 is_branch_slot_insn (rtx insn)
23101 if (!insn || !NONDEBUG_INSN_P (insn)
23102 || GET_CODE (PATTERN (insn)) == USE
23103 || GET_CODE (PATTERN (insn)) == CLOBBER)
23106 if (rs6000_sched_groups)
23108 enum attr_type type = get_attr_type (insn);
23109 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
23117 /* The function returns true if out_inst sets a value that is
23118 used in the address generation computation of in_insn */
23120 set_to_load_agen (rtx out_insn, rtx in_insn)
23122 rtx out_set, in_set;
23124 /* For performance reasons, only handle the simple case where
23125 both loads are a single_set. */
23126 out_set = single_set (out_insn);
23129 in_set = single_set (in_insn);
23131 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
23137 /* The function returns true if the target storage location of
23138 out_insn is adjacent to the target storage location of in_insn */
23139 /* Return 1 if memory locations are adjacent. */
23142 adjacent_mem_locations (rtx insn1, rtx insn2)
23145 rtx a = get_store_dest (PATTERN (insn1));
23146 rtx b = get_store_dest (PATTERN (insn2));
23148 if ((GET_CODE (XEXP (a, 0)) == REG
23149 || (GET_CODE (XEXP (a, 0)) == PLUS
23150 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
23151 && (GET_CODE (XEXP (b, 0)) == REG
23152 || (GET_CODE (XEXP (b, 0)) == PLUS
23153 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
23155 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
23158 if (GET_CODE (XEXP (a, 0)) == PLUS)
23160 reg0 = XEXP (XEXP (a, 0), 0);
23161 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
23164 reg0 = XEXP (a, 0);
23166 if (GET_CODE (XEXP (b, 0)) == PLUS)
23168 reg1 = XEXP (XEXP (b, 0), 0);
23169 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
23172 reg1 = XEXP (b, 0);
23174 val_diff = val1 - val0;
23176 return ((REGNO (reg0) == REGNO (reg1))
23177 && ((MEM_SIZE_KNOWN_P (a) && val_diff == MEM_SIZE (a))
23178 || (MEM_SIZE_KNOWN_P (b) && val_diff == -MEM_SIZE (b))));
23184 /* A C statement (sans semicolon) to update the integer scheduling
23185 priority INSN_PRIORITY (INSN). Increase the priority to execute the
23186 INSN earlier, reduce the priority to execute INSN later. Do not
23187 define this macro if you do not need to adjust the scheduling
23188 priorities of insns. */
23191 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
23193 /* On machines (like the 750) which have asymmetric integer units,
23194 where one integer unit can do multiply and divides and the other
23195 can't, reduce the priority of multiply/divide so it is scheduled
23196 before other integer operations. */
23199 if (! INSN_P (insn))
23202 if (GET_CODE (PATTERN (insn)) == USE)
23205 switch (rs6000_cpu_attr) {
23207 switch (get_attr_type (insn))
23214 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
23215 priority, priority);
23216 if (priority >= 0 && priority < 0x01000000)
23223 if (insn_must_be_first_in_group (insn)
23224 && reload_completed
23225 && current_sched_info->sched_max_insns_priority
23226 && rs6000_sched_restricted_insns_priority)
23229 /* Prioritize insns that can be dispatched only in the first
23231 if (rs6000_sched_restricted_insns_priority == 1)
23232 /* Attach highest priority to insn. This means that in
23233 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
23234 precede 'priority' (critical path) considerations. */
23235 return current_sched_info->sched_max_insns_priority;
23236 else if (rs6000_sched_restricted_insns_priority == 2)
23237 /* Increase priority of insn by a minimal amount. This means that in
23238 haifa-sched.c:ready_sort(), only 'priority' (critical path)
23239 considerations precede dispatch-slot restriction considerations. */
23240 return (priority + 1);
23243 if (rs6000_cpu == PROCESSOR_POWER6
23244 && ((load_store_pendulum == -2 && is_load_insn (insn))
23245 || (load_store_pendulum == 2 && is_store_insn (insn))))
23246 /* Attach highest priority to insn if the scheduler has just issued two
23247 stores and this instruction is a load, or two loads and this instruction
23248 is a store. Power6 wants loads and stores scheduled alternately
23250 return current_sched_info->sched_max_insns_priority;
23255 /* Return true if the instruction is nonpipelined on the Cell. */
23257 is_nonpipeline_insn (rtx insn)
23259 enum attr_type type;
23260 if (!insn || !NONDEBUG_INSN_P (insn)
23261 || GET_CODE (PATTERN (insn)) == USE
23262 || GET_CODE (PATTERN (insn)) == CLOBBER)
23265 type = get_attr_type (insn);
23266 if (type == TYPE_IMUL
23267 || type == TYPE_IMUL2
23268 || type == TYPE_IMUL3
23269 || type == TYPE_LMUL
23270 || type == TYPE_IDIV
23271 || type == TYPE_LDIV
23272 || type == TYPE_SDIV
23273 || type == TYPE_DDIV
23274 || type == TYPE_SSQRT
23275 || type == TYPE_DSQRT
23276 || type == TYPE_MFCR
23277 || type == TYPE_MFCRF
23278 || type == TYPE_MFJMPR)
23286 /* Return how many instructions the machine can issue per cycle. */
23289 rs6000_issue_rate (void)
23291 /* Unless scheduling for register pressure, use issue rate of 1 for
23292 first scheduling pass to decrease degradation. */
23293 if (!reload_completed && !flag_sched_pressure)
23296 switch (rs6000_cpu_attr) {
23297 case CPU_RIOS1: /* ? */
23299 case CPU_PPC601: /* ? */
23308 case CPU_PPCE300C2:
23309 case CPU_PPCE300C3:
23310 case CPU_PPCE500MC:
23311 case CPU_PPCE500MC64:
23331 /* Return how many instructions to look ahead for better insn
23335 rs6000_use_sched_lookahead (void)
23337 if (rs6000_cpu_attr == CPU_PPC8540)
23339 if (rs6000_cpu_attr == CPU_CELL)
23340 return (reload_completed ? 8 : 0);
23344 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
23346 rs6000_use_sched_lookahead_guard (rtx insn)
23348 if (rs6000_cpu_attr != CPU_CELL)
23351 if (insn == NULL_RTX || !INSN_P (insn))
23354 if (!reload_completed
23355 || is_nonpipeline_insn (insn)
23356 || is_microcoded_insn (insn))
23362 /* Determine is PAT refers to memory. */
23365 is_mem_ref (rtx pat)
23371 /* stack_tie does not produce any real memory traffic. */
23372 if (GET_CODE (pat) == UNSPEC
23373 && XINT (pat, 1) == UNSPEC_TIE)
23376 if (GET_CODE (pat) == MEM)
23379 /* Recursively process the pattern. */
23380 fmt = GET_RTX_FORMAT (GET_CODE (pat));
23382 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
23385 ret |= is_mem_ref (XEXP (pat, i));
23386 else if (fmt[i] == 'E')
23387 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
23388 ret |= is_mem_ref (XVECEXP (pat, i, j));
23394 /* Determine if PAT is a PATTERN of a load insn. */
23397 is_load_insn1 (rtx pat)
23399 if (!pat || pat == NULL_RTX)
23402 if (GET_CODE (pat) == SET)
23403 return is_mem_ref (SET_SRC (pat));
23405 if (GET_CODE (pat) == PARALLEL)
23409 for (i = 0; i < XVECLEN (pat, 0); i++)
23410 if (is_load_insn1 (XVECEXP (pat, 0, i)))
23417 /* Determine if INSN loads from memory. */
23420 is_load_insn (rtx insn)
23422 if (!insn || !INSN_P (insn))
23425 if (GET_CODE (insn) == CALL_INSN)
23428 return is_load_insn1 (PATTERN (insn));
23431 /* Determine if PAT is a PATTERN of a store insn. */
23434 is_store_insn1 (rtx pat)
23436 if (!pat || pat == NULL_RTX)
23439 if (GET_CODE (pat) == SET)
23440 return is_mem_ref (SET_DEST (pat));
23442 if (GET_CODE (pat) == PARALLEL)
23446 for (i = 0; i < XVECLEN (pat, 0); i++)
23447 if (is_store_insn1 (XVECEXP (pat, 0, i)))
23454 /* Determine if INSN stores to memory. */
23457 is_store_insn (rtx insn)
23459 if (!insn || !INSN_P (insn))
23462 return is_store_insn1 (PATTERN (insn));
23465 /* Return the dest of a store insn. */
23468 get_store_dest (rtx pat)
23470 gcc_assert (is_store_insn1 (pat));
23472 if (GET_CODE (pat) == SET)
23473 return SET_DEST (pat);
23474 else if (GET_CODE (pat) == PARALLEL)
23478 for (i = 0; i < XVECLEN (pat, 0); i++)
23480 rtx inner_pat = XVECEXP (pat, 0, i);
23481 if (GET_CODE (inner_pat) == SET
23482 && is_mem_ref (SET_DEST (inner_pat)))
23486 /* We shouldn't get here, because we should have either a simple
23487 store insn or a store with update which are covered above. */
23491 /* Returns whether the dependence between INSN and NEXT is considered
23492 costly by the given target. */
23495 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
23500 /* If the flag is not enabled - no dependence is considered costly;
23501 allow all dependent insns in the same group.
23502 This is the most aggressive option. */
23503 if (rs6000_sched_costly_dep == no_dep_costly)
23506 /* If the flag is set to 1 - a dependence is always considered costly;
23507 do not allow dependent instructions in the same group.
23508 This is the most conservative option. */
23509 if (rs6000_sched_costly_dep == all_deps_costly)
23512 insn = DEP_PRO (dep);
23513 next = DEP_CON (dep);
23515 if (rs6000_sched_costly_dep == store_to_load_dep_costly
23516 && is_load_insn (next)
23517 && is_store_insn (insn))
23518 /* Prevent load after store in the same group. */
23521 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
23522 && is_load_insn (next)
23523 && is_store_insn (insn)
23524 && DEP_TYPE (dep) == REG_DEP_TRUE)
23525 /* Prevent load after store in the same group if it is a true
23529 /* The flag is set to X; dependences with latency >= X are considered costly,
23530 and will not be scheduled in the same group. */
23531 if (rs6000_sched_costly_dep <= max_dep_latency
23532 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
23538 /* Return the next insn after INSN that is found before TAIL is reached,
23539 skipping any "non-active" insns - insns that will not actually occupy
23540 an issue slot. Return NULL_RTX if such an insn is not found. */
23543 get_next_active_insn (rtx insn, rtx tail)
23545 if (insn == NULL_RTX || insn == tail)
23550 insn = NEXT_INSN (insn);
23551 if (insn == NULL_RTX || insn == tail)
23556 || (NONJUMP_INSN_P (insn)
23557 && GET_CODE (PATTERN (insn)) != USE
23558 && GET_CODE (PATTERN (insn)) != CLOBBER
23559 && INSN_CODE (insn) != CODE_FOR_stack_tie))
23565 /* We are about to begin issuing insns for this clock cycle. */
23568 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
23569 rtx *ready ATTRIBUTE_UNUSED,
23570 int *pn_ready ATTRIBUTE_UNUSED,
23571 int clock_var ATTRIBUTE_UNUSED)
23573 int n_ready = *pn_ready;
23576 fprintf (dump, "// rs6000_sched_reorder :\n");
23578 /* Reorder the ready list, if the second to last ready insn
23579 is a nonepipeline insn. */
23580 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
23582 if (is_nonpipeline_insn (ready[n_ready - 1])
23583 && (recog_memoized (ready[n_ready - 2]) > 0))
23584 /* Simply swap first two insns. */
23586 rtx tmp = ready[n_ready - 1];
23587 ready[n_ready - 1] = ready[n_ready - 2];
23588 ready[n_ready - 2] = tmp;
23592 if (rs6000_cpu == PROCESSOR_POWER6)
23593 load_store_pendulum = 0;
23595 return rs6000_issue_rate ();
23598 /* Like rs6000_sched_reorder, but called after issuing each insn. */
23601 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
23602 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
23605 fprintf (dump, "// rs6000_sched_reorder2 :\n");
23607 /* For Power6, we need to handle some special cases to try and keep the
23608 store queue from overflowing and triggering expensive flushes.
23610 This code monitors how load and store instructions are being issued
23611 and skews the ready list one way or the other to increase the likelihood
23612 that a desired instruction is issued at the proper time.
23614 A couple of things are done. First, we maintain a "load_store_pendulum"
23615 to track the current state of load/store issue.
23617 - If the pendulum is at zero, then no loads or stores have been
23618 issued in the current cycle so we do nothing.
23620 - If the pendulum is 1, then a single load has been issued in this
23621 cycle and we attempt to locate another load in the ready list to
23624 - If the pendulum is -2, then two stores have already been
23625 issued in this cycle, so we increase the priority of the first load
23626 in the ready list to increase it's likelihood of being chosen first
23629 - If the pendulum is -1, then a single store has been issued in this
23630 cycle and we attempt to locate another store in the ready list to
23631 issue with it, preferring a store to an adjacent memory location to
23632 facilitate store pairing in the store queue.
23634 - If the pendulum is 2, then two loads have already been
23635 issued in this cycle, so we increase the priority of the first store
23636 in the ready list to increase it's likelihood of being chosen first
23639 - If the pendulum < -2 or > 2, then do nothing.
23641 Note: This code covers the most common scenarios. There exist non
23642 load/store instructions which make use of the LSU and which
23643 would need to be accounted for to strictly model the behavior
23644 of the machine. Those instructions are currently unaccounted
23645 for to help minimize compile time overhead of this code.
23647 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
23653 if (is_store_insn (last_scheduled_insn))
23654 /* Issuing a store, swing the load_store_pendulum to the left */
23655 load_store_pendulum--;
23656 else if (is_load_insn (last_scheduled_insn))
23657 /* Issuing a load, swing the load_store_pendulum to the right */
23658 load_store_pendulum++;
23660 return cached_can_issue_more;
23662 /* If the pendulum is balanced, or there is only one instruction on
23663 the ready list, then all is well, so return. */
23664 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
23665 return cached_can_issue_more;
23667 if (load_store_pendulum == 1)
23669 /* A load has been issued in this cycle. Scan the ready list
23670 for another load to issue with it */
23675 if (is_load_insn (ready[pos]))
23677 /* Found a load. Move it to the head of the ready list,
23678 and adjust it's priority so that it is more likely to
23681 for (i=pos; i<*pn_ready-1; i++)
23682 ready[i] = ready[i + 1];
23683 ready[*pn_ready-1] = tmp;
23685 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23686 INSN_PRIORITY (tmp)++;
23692 else if (load_store_pendulum == -2)
23694 /* Two stores have been issued in this cycle. Increase the
23695 priority of the first load in the ready list to favor it for
23696 issuing in the next cycle. */
23701 if (is_load_insn (ready[pos])
23703 && INSN_PRIORITY_KNOWN (ready[pos]))
23705 INSN_PRIORITY (ready[pos])++;
23707 /* Adjust the pendulum to account for the fact that a load
23708 was found and increased in priority. This is to prevent
23709 increasing the priority of multiple loads */
23710 load_store_pendulum--;
23717 else if (load_store_pendulum == -1)
23719 /* A store has been issued in this cycle. Scan the ready list for
23720 another store to issue with it, preferring a store to an adjacent
23722 int first_store_pos = -1;
23728 if (is_store_insn (ready[pos]))
23730 /* Maintain the index of the first store found on the
23732 if (first_store_pos == -1)
23733 first_store_pos = pos;
23735 if (is_store_insn (last_scheduled_insn)
23736 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
23738 /* Found an adjacent store. Move it to the head of the
23739 ready list, and adjust it's priority so that it is
23740 more likely to stay there */
23742 for (i=pos; i<*pn_ready-1; i++)
23743 ready[i] = ready[i + 1];
23744 ready[*pn_ready-1] = tmp;
23746 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23747 INSN_PRIORITY (tmp)++;
23749 first_store_pos = -1;
23757 if (first_store_pos >= 0)
23759 /* An adjacent store wasn't found, but a non-adjacent store was,
23760 so move the non-adjacent store to the front of the ready
23761 list, and adjust its priority so that it is more likely to
23763 tmp = ready[first_store_pos];
23764 for (i=first_store_pos; i<*pn_ready-1; i++)
23765 ready[i] = ready[i + 1];
23766 ready[*pn_ready-1] = tmp;
23767 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23768 INSN_PRIORITY (tmp)++;
23771 else if (load_store_pendulum == 2)
23773 /* Two loads have been issued in this cycle. Increase the priority
23774 of the first store in the ready list to favor it for issuing in
23780 if (is_store_insn (ready[pos])
23782 && INSN_PRIORITY_KNOWN (ready[pos]))
23784 INSN_PRIORITY (ready[pos])++;
23786 /* Adjust the pendulum to account for the fact that a store
23787 was found and increased in priority. This is to prevent
23788 increasing the priority of multiple stores */
23789 load_store_pendulum++;
23798 return cached_can_issue_more;
23801 /* Return whether the presence of INSN causes a dispatch group termination
23802 of group WHICH_GROUP.
23804 If WHICH_GROUP == current_group, this function will return true if INSN
23805 causes the termination of the current group (i.e, the dispatch group to
23806 which INSN belongs). This means that INSN will be the last insn in the
23807 group it belongs to.
23809 If WHICH_GROUP == previous_group, this function will return true if INSN
23810 causes the termination of the previous group (i.e, the dispatch group that
23811 precedes the group to which INSN belongs). This means that INSN will be
23812 the first insn in the group it belongs to). */
23815 insn_terminates_group_p (rtx insn, enum group_termination which_group)
23822 first = insn_must_be_first_in_group (insn);
23823 last = insn_must_be_last_in_group (insn);
23828 if (which_group == current_group)
23830 else if (which_group == previous_group)
23838 insn_must_be_first_in_group (rtx insn)
23840 enum attr_type type;
23843 || GET_CODE (insn) == NOTE
23844 || DEBUG_INSN_P (insn)
23845 || GET_CODE (PATTERN (insn)) == USE
23846 || GET_CODE (PATTERN (insn)) == CLOBBER)
23849 switch (rs6000_cpu)
23851 case PROCESSOR_POWER5:
23852 if (is_cracked_insn (insn))
23854 case PROCESSOR_POWER4:
23855 if (is_microcoded_insn (insn))
23858 if (!rs6000_sched_groups)
23861 type = get_attr_type (insn);
23868 case TYPE_DELAYED_CR:
23869 case TYPE_CR_LOGICAL:
23883 case PROCESSOR_POWER6:
23884 type = get_attr_type (insn);
23888 case TYPE_INSERT_DWORD:
23892 case TYPE_VAR_SHIFT_ROTATE:
23899 case TYPE_INSERT_WORD:
23900 case TYPE_DELAYED_COMPARE:
23901 case TYPE_IMUL_COMPARE:
23902 case TYPE_LMUL_COMPARE:
23903 case TYPE_FPCOMPARE:
23914 case TYPE_LOAD_EXT_UX:
23916 case TYPE_STORE_UX:
23917 case TYPE_FPLOAD_U:
23918 case TYPE_FPLOAD_UX:
23919 case TYPE_FPSTORE_U:
23920 case TYPE_FPSTORE_UX:
23926 case PROCESSOR_POWER7:
23927 type = get_attr_type (insn);
23931 case TYPE_CR_LOGICAL:
23938 case TYPE_DELAYED_COMPARE:
23939 case TYPE_VAR_DELAYED_COMPARE:
23945 case TYPE_LOAD_EXT:
23946 case TYPE_LOAD_EXT_U:
23947 case TYPE_LOAD_EXT_UX:
23949 case TYPE_STORE_UX:
23950 case TYPE_FPLOAD_U:
23951 case TYPE_FPLOAD_UX:
23952 case TYPE_FPSTORE_U:
23953 case TYPE_FPSTORE_UX:
23969 insn_must_be_last_in_group (rtx insn)
23971 enum attr_type type;
23974 || GET_CODE (insn) == NOTE
23975 || DEBUG_INSN_P (insn)
23976 || GET_CODE (PATTERN (insn)) == USE
23977 || GET_CODE (PATTERN (insn)) == CLOBBER)
23980 switch (rs6000_cpu) {
23981 case PROCESSOR_POWER4:
23982 case PROCESSOR_POWER5:
23983 if (is_microcoded_insn (insn))
23986 if (is_branch_slot_insn (insn))
23990 case PROCESSOR_POWER6:
23991 type = get_attr_type (insn);
23998 case TYPE_VAR_SHIFT_ROTATE:
24005 case TYPE_DELAYED_COMPARE:
24006 case TYPE_IMUL_COMPARE:
24007 case TYPE_LMUL_COMPARE:
24008 case TYPE_FPCOMPARE:
24022 case PROCESSOR_POWER7:
24023 type = get_attr_type (insn);
24031 case TYPE_LOAD_EXT_U:
24032 case TYPE_LOAD_EXT_UX:
24033 case TYPE_STORE_UX:
24046 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
24047 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
24050 is_costly_group (rtx *group_insns, rtx next_insn)
24053 int issue_rate = rs6000_issue_rate ();
24055 for (i = 0; i < issue_rate; i++)
24057 sd_iterator_def sd_it;
24059 rtx insn = group_insns[i];
24064 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
24066 rtx next = DEP_CON (dep);
24068 if (next == next_insn
24069 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
24077 /* Utility of the function redefine_groups.
24078 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
24079 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
24080 to keep it "far" (in a separate group) from GROUP_INSNS, following
24081 one of the following schemes, depending on the value of the flag
24082 -minsert_sched_nops = X:
24083 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
24084 in order to force NEXT_INSN into a separate group.
24085 (2) X < sched_finish_regroup_exact: insert exactly X nops.
24086 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
24087 insertion (has a group just ended, how many vacant issue slots remain in the
24088 last group, and how many dispatch groups were encountered so far). */
24091 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
24092 rtx next_insn, bool *group_end, int can_issue_more,
24097 int issue_rate = rs6000_issue_rate ();
24098 bool end = *group_end;
24101 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
24102 return can_issue_more;
24104 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
24105 return can_issue_more;
24107 force = is_costly_group (group_insns, next_insn);
24109 return can_issue_more;
24111 if (sched_verbose > 6)
24112 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
24113 *group_count ,can_issue_more);
24115 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
24118 can_issue_more = 0;
24120 /* Since only a branch can be issued in the last issue_slot, it is
24121 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
24122 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
24123 in this case the last nop will start a new group and the branch
24124 will be forced to the new group. */
24125 if (can_issue_more && !is_branch_slot_insn (next_insn))
24128 while (can_issue_more > 0)
24131 emit_insn_before (nop, next_insn);
24139 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
24141 int n_nops = rs6000_sched_insert_nops;
24143 /* Nops can't be issued from the branch slot, so the effective
24144 issue_rate for nops is 'issue_rate - 1'. */
24145 if (can_issue_more == 0)
24146 can_issue_more = issue_rate;
24148 if (can_issue_more == 0)
24150 can_issue_more = issue_rate - 1;
24153 for (i = 0; i < issue_rate; i++)
24155 group_insns[i] = 0;
24162 emit_insn_before (nop, next_insn);
24163 if (can_issue_more == issue_rate - 1) /* new group begins */
24166 if (can_issue_more == 0)
24168 can_issue_more = issue_rate - 1;
24171 for (i = 0; i < issue_rate; i++)
24173 group_insns[i] = 0;
24179 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
24182 /* Is next_insn going to start a new group? */
24185 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24186 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24187 || (can_issue_more < issue_rate &&
24188 insn_terminates_group_p (next_insn, previous_group)));
24189 if (*group_end && end)
24192 if (sched_verbose > 6)
24193 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
24194 *group_count, can_issue_more);
24195 return can_issue_more;
24198 return can_issue_more;
24201 /* This function tries to synch the dispatch groups that the compiler "sees"
24202 with the dispatch groups that the processor dispatcher is expected to
24203 form in practice. It tries to achieve this synchronization by forcing the
24204 estimated processor grouping on the compiler (as opposed to the function
24205 'pad_goups' which tries to force the scheduler's grouping on the processor).
24207 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
24208 examines the (estimated) dispatch groups that will be formed by the processor
24209 dispatcher. It marks these group boundaries to reflect the estimated
24210 processor grouping, overriding the grouping that the scheduler had marked.
24211 Depending on the value of the flag '-minsert-sched-nops' this function can
24212 force certain insns into separate groups or force a certain distance between
24213 them by inserting nops, for example, if there exists a "costly dependence"
24216 The function estimates the group boundaries that the processor will form as
24217 follows: It keeps track of how many vacant issue slots are available after
24218 each insn. A subsequent insn will start a new group if one of the following
24220 - no more vacant issue slots remain in the current dispatch group.
24221 - only the last issue slot, which is the branch slot, is vacant, but the next
24222 insn is not a branch.
24223 - only the last 2 or less issue slots, including the branch slot, are vacant,
24224 which means that a cracked insn (which occupies two issue slots) can't be
24225 issued in this group.
24226 - less than 'issue_rate' slots are vacant, and the next insn always needs to
24227 start a new group. */
24230 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24232 rtx insn, next_insn;
24234 int can_issue_more;
24237 int group_count = 0;
24241 issue_rate = rs6000_issue_rate ();
24242 group_insns = XALLOCAVEC (rtx, issue_rate);
24243 for (i = 0; i < issue_rate; i++)
24245 group_insns[i] = 0;
24247 can_issue_more = issue_rate;
24249 insn = get_next_active_insn (prev_head_insn, tail);
24252 while (insn != NULL_RTX)
24254 slot = (issue_rate - can_issue_more);
24255 group_insns[slot] = insn;
24257 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24258 if (insn_terminates_group_p (insn, current_group))
24259 can_issue_more = 0;
24261 next_insn = get_next_active_insn (insn, tail);
24262 if (next_insn == NULL_RTX)
24263 return group_count + 1;
24265 /* Is next_insn going to start a new group? */
24267 = (can_issue_more == 0
24268 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24269 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24270 || (can_issue_more < issue_rate &&
24271 insn_terminates_group_p (next_insn, previous_group)));
24273 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
24274 next_insn, &group_end, can_issue_more,
24280 can_issue_more = 0;
24281 for (i = 0; i < issue_rate; i++)
24283 group_insns[i] = 0;
24287 if (GET_MODE (next_insn) == TImode && can_issue_more)
24288 PUT_MODE (next_insn, VOIDmode);
24289 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
24290 PUT_MODE (next_insn, TImode);
24293 if (can_issue_more == 0)
24294 can_issue_more = issue_rate;
24297 return group_count;
24300 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
24301 dispatch group boundaries that the scheduler had marked. Pad with nops
24302 any dispatch groups which have vacant issue slots, in order to force the
24303 scheduler's grouping on the processor dispatcher. The function
24304 returns the number of dispatch groups found. */
24307 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24309 rtx insn, next_insn;
24312 int can_issue_more;
24314 int group_count = 0;
24316 /* Initialize issue_rate. */
24317 issue_rate = rs6000_issue_rate ();
24318 can_issue_more = issue_rate;
24320 insn = get_next_active_insn (prev_head_insn, tail);
24321 next_insn = get_next_active_insn (insn, tail);
24323 while (insn != NULL_RTX)
24326 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24328 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
24330 if (next_insn == NULL_RTX)
24335 /* If the scheduler had marked group termination at this location
24336 (between insn and next_insn), and neither insn nor next_insn will
24337 force group termination, pad the group with nops to force group
24340 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
24341 && !insn_terminates_group_p (insn, current_group)
24342 && !insn_terminates_group_p (next_insn, previous_group))
24344 if (!is_branch_slot_insn (next_insn))
24347 while (can_issue_more)
24350 emit_insn_before (nop, next_insn);
24355 can_issue_more = issue_rate;
24360 next_insn = get_next_active_insn (insn, tail);
24363 return group_count;
24366 /* We're beginning a new block. Initialize data structures as necessary. */
24369 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
24370 int sched_verbose ATTRIBUTE_UNUSED,
24371 int max_ready ATTRIBUTE_UNUSED)
24373 last_scheduled_insn = NULL_RTX;
24374 load_store_pendulum = 0;
24377 /* The following function is called at the end of scheduling BB.
24378 After reload, it inserts nops at insn group bundling. */
24381 rs6000_sched_finish (FILE *dump, int sched_verbose)
24386 fprintf (dump, "=== Finishing schedule.\n");
24388 if (reload_completed && rs6000_sched_groups)
24390 /* Do not run sched_finish hook when selective scheduling enabled. */
24391 if (sel_sched_p ())
24394 if (rs6000_sched_insert_nops == sched_finish_none)
24397 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
24398 n_groups = pad_groups (dump, sched_verbose,
24399 current_sched_info->prev_head,
24400 current_sched_info->next_tail);
24402 n_groups = redefine_groups (dump, sched_verbose,
24403 current_sched_info->prev_head,
24404 current_sched_info->next_tail);
24406 if (sched_verbose >= 6)
24408 fprintf (dump, "ngroups = %d\n", n_groups);
24409 print_rtl (dump, current_sched_info->prev_head);
24410 fprintf (dump, "Done finish_sched\n");
24415 struct _rs6000_sched_context
24417 short cached_can_issue_more;
24418 rtx last_scheduled_insn;
24419 int load_store_pendulum;
24422 typedef struct _rs6000_sched_context rs6000_sched_context_def;
24423 typedef rs6000_sched_context_def *rs6000_sched_context_t;
24425 /* Allocate store for new scheduling context. */
24427 rs6000_alloc_sched_context (void)
24429 return xmalloc (sizeof (rs6000_sched_context_def));
24432 /* If CLEAN_P is true then initializes _SC with clean data,
24433 and from the global context otherwise. */
24435 rs6000_init_sched_context (void *_sc, bool clean_p)
24437 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24441 sc->cached_can_issue_more = 0;
24442 sc->last_scheduled_insn = NULL_RTX;
24443 sc->load_store_pendulum = 0;
24447 sc->cached_can_issue_more = cached_can_issue_more;
24448 sc->last_scheduled_insn = last_scheduled_insn;
24449 sc->load_store_pendulum = load_store_pendulum;
24453 /* Sets the global scheduling context to the one pointed to by _SC. */
24455 rs6000_set_sched_context (void *_sc)
24457 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24459 gcc_assert (sc != NULL);
24461 cached_can_issue_more = sc->cached_can_issue_more;
24462 last_scheduled_insn = sc->last_scheduled_insn;
24463 load_store_pendulum = sc->load_store_pendulum;
24468 rs6000_free_sched_context (void *_sc)
24470 gcc_assert (_sc != NULL);
24476 /* Length in units of the trampoline for entering a nested function. */
24479 rs6000_trampoline_size (void)
24483 switch (DEFAULT_ABI)
24486 gcc_unreachable ();
24489 ret = (TARGET_32BIT) ? 12 : 24;
24494 ret = (TARGET_32BIT) ? 40 : 48;
24501 /* Emit RTL insns to initialize the variable parts of a trampoline.
24502 FNADDR is an RTX for the address of the function's pure code.
24503 CXT is an RTX for the static chain value for the function. */
24506 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
24508 int regsize = (TARGET_32BIT) ? 4 : 8;
24509 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
24510 rtx ctx_reg = force_reg (Pmode, cxt);
24511 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
24513 switch (DEFAULT_ABI)
24516 gcc_unreachable ();
24518 /* Under AIX, just build the 3 word function descriptor */
24521 rtx fnmem, fn_reg, toc_reg;
24523 if (!TARGET_POINTERS_TO_NESTED_FUNCTIONS)
24524 error ("-mno-r11 must not be used if you have trampolines");
24526 fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
24527 fn_reg = gen_reg_rtx (Pmode);
24528 toc_reg = gen_reg_rtx (Pmode);
24530 /* Macro to shorten the code expansions below. */
24531 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
24533 m_tramp = replace_equiv_address (m_tramp, addr);
24535 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
24536 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
24537 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
24538 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
24539 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
24545 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
24548 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
24549 LCT_NORMAL, VOIDmode, 4,
24551 GEN_INT (rs6000_trampoline_size ()), SImode,
24559 /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
24560 identifier as an argument, so the front end shouldn't look it up. */
24563 rs6000_attribute_takes_identifier_p (const_tree attr_id)
24565 return is_attribute_p ("altivec", attr_id);
24568 /* Handle the "altivec" attribute. The attribute may have
24569 arguments as follows:
24571 __attribute__((altivec(vector__)))
24572 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
24573 __attribute__((altivec(bool__))) (always followed by 'unsigned')
24575 and may appear more than once (e.g., 'vector bool char') in a
24576 given declaration. */
24579 rs6000_handle_altivec_attribute (tree *node,
24580 tree name ATTRIBUTE_UNUSED,
24582 int flags ATTRIBUTE_UNUSED,
24583 bool *no_add_attrs)
24585 tree type = *node, result = NULL_TREE;
24586 enum machine_mode mode;
24589 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
24590 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
24591 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
24594 while (POINTER_TYPE_P (type)
24595 || TREE_CODE (type) == FUNCTION_TYPE
24596 || TREE_CODE (type) == METHOD_TYPE
24597 || TREE_CODE (type) == ARRAY_TYPE)
24598 type = TREE_TYPE (type);
24600 mode = TYPE_MODE (type);
24602 /* Check for invalid AltiVec type qualifiers. */
24603 if (type == long_double_type_node)
24604 error ("use of %<long double%> in AltiVec types is invalid");
24605 else if (type == boolean_type_node)
24606 error ("use of boolean types in AltiVec types is invalid");
24607 else if (TREE_CODE (type) == COMPLEX_TYPE)
24608 error ("use of %<complex%> in AltiVec types is invalid");
24609 else if (DECIMAL_FLOAT_MODE_P (mode))
24610 error ("use of decimal floating point types in AltiVec types is invalid");
24611 else if (!TARGET_VSX)
24613 if (type == long_unsigned_type_node || type == long_integer_type_node)
24616 error ("use of %<long%> in AltiVec types is invalid for "
24617 "64-bit code without -mvsx");
24618 else if (rs6000_warn_altivec_long)
24619 warning (0, "use of %<long%> in AltiVec types is deprecated; "
24622 else if (type == long_long_unsigned_type_node
24623 || type == long_long_integer_type_node)
24624 error ("use of %<long long%> in AltiVec types is invalid without "
24626 else if (type == double_type_node)
24627 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
24630 switch (altivec_type)
24633 unsigned_p = TYPE_UNSIGNED (type);
24637 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
24640 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
24643 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
24646 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
24648 case SFmode: result = V4SF_type_node; break;
24649 case DFmode: result = V2DF_type_node; break;
24650 /* If the user says 'vector int bool', we may be handed the 'bool'
24651 attribute _before_ the 'vector' attribute, and so select the
24652 proper type in the 'b' case below. */
24653 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
24654 case V2DImode: case V2DFmode:
24662 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
24663 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
24664 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
24665 case QImode: case V16QImode: result = bool_V16QI_type_node;
24672 case V8HImode: result = pixel_V8HI_type_node;
24678 /* Propagate qualifiers attached to the element type
24679 onto the vector type. */
24680 if (result && result != type && TYPE_QUALS (type))
24681 result = build_qualified_type (result, TYPE_QUALS (type));
24683 *no_add_attrs = true; /* No need to hang on to the attribute. */
24686 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
24691 /* AltiVec defines four built-in scalar types that serve as vector
24692 elements; we must teach the compiler how to mangle them. */
24694 static const char *
24695 rs6000_mangle_type (const_tree type)
24697 type = TYPE_MAIN_VARIANT (type);
24699 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
24700 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
24703 if (type == bool_char_type_node) return "U6__boolc";
24704 if (type == bool_short_type_node) return "U6__bools";
24705 if (type == pixel_type_node) return "u7__pixel";
24706 if (type == bool_int_type_node) return "U6__booli";
24707 if (type == bool_long_type_node) return "U6__booll";
24709 /* Mangle IBM extended float long double as `g' (__float128) on
24710 powerpc*-linux where long-double-64 previously was the default. */
24711 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
24713 && TARGET_LONG_DOUBLE_128
24714 && !TARGET_IEEEQUAD)
24717 /* For all other types, use normal C++ mangling. */
24721 /* Handle a "longcall" or "shortcall" attribute; arguments as in
24722 struct attribute_spec.handler. */
24725 rs6000_handle_longcall_attribute (tree *node, tree name,
24726 tree args ATTRIBUTE_UNUSED,
24727 int flags ATTRIBUTE_UNUSED,
24728 bool *no_add_attrs)
24730 if (TREE_CODE (*node) != FUNCTION_TYPE
24731 && TREE_CODE (*node) != FIELD_DECL
24732 && TREE_CODE (*node) != TYPE_DECL)
24734 warning (OPT_Wattributes, "%qE attribute only applies to functions",
24736 *no_add_attrs = true;
24742 /* Set longcall attributes on all functions declared when
24743 rs6000_default_long_calls is true. */
24745 rs6000_set_default_type_attributes (tree type)
24747 if (rs6000_default_long_calls
24748 && (TREE_CODE (type) == FUNCTION_TYPE
24749 || TREE_CODE (type) == METHOD_TYPE))
24750 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
24752 TYPE_ATTRIBUTES (type));
24755 darwin_set_default_type_attributes (type);
24759 /* Return a reference suitable for calling a function with the
24760 longcall attribute. */
24763 rs6000_longcall_ref (rtx call_ref)
24765 const char *call_name;
24768 if (GET_CODE (call_ref) != SYMBOL_REF)
24771 /* System V adds '.' to the internal name, so skip them. */
24772 call_name = XSTR (call_ref, 0);
24773 if (*call_name == '.')
24775 while (*call_name == '.')
24778 node = get_identifier (call_name);
24779 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
24782 return force_reg (Pmode, call_ref);
24785 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
24786 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
24789 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
24790 struct attribute_spec.handler. */
24792 rs6000_handle_struct_attribute (tree *node, tree name,
24793 tree args ATTRIBUTE_UNUSED,
24794 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
24797 if (DECL_P (*node))
24799 if (TREE_CODE (*node) == TYPE_DECL)
24800 type = &TREE_TYPE (*node);
24805 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
24806 || TREE_CODE (*type) == UNION_TYPE)))
24808 warning (OPT_Wattributes, "%qE attribute ignored", name);
24809 *no_add_attrs = true;
24812 else if ((is_attribute_p ("ms_struct", name)
24813 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
24814 || ((is_attribute_p ("gcc_struct", name)
24815 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
24817 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
24819 *no_add_attrs = true;
24826 rs6000_ms_bitfield_layout_p (const_tree record_type)
24828 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
24829 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
24830 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
24833 #ifdef USING_ELFOS_H
24835 /* A get_unnamed_section callback, used for switching to toc_section. */
24838 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
24840 if (DEFAULT_ABI == ABI_AIX
24841 && TARGET_MINIMAL_TOC
24842 && !TARGET_RELOCATABLE)
24844 if (!toc_initialized)
24846 toc_initialized = 1;
24847 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
24848 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
24849 fprintf (asm_out_file, "\t.tc ");
24850 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
24851 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24852 fprintf (asm_out_file, "\n");
24854 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24855 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24856 fprintf (asm_out_file, " = .+32768\n");
24859 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24861 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
24862 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
24865 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24866 if (!toc_initialized)
24868 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24869 fprintf (asm_out_file, " = .+32768\n");
24870 toc_initialized = 1;
24875 /* Implement TARGET_ASM_INIT_SECTIONS. */
24878 rs6000_elf_asm_init_sections (void)
24881 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
24884 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
24885 SDATA2_SECTION_ASM_OP);
24888 /* Implement TARGET_SELECT_RTX_SECTION. */
24891 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
24892 unsigned HOST_WIDE_INT align)
24894 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
24895 return toc_section;
24897 return default_elf_select_rtx_section (mode, x, align);
24900 /* For a SYMBOL_REF, set generic flags and then perform some
24901 target-specific processing.
24903 When the AIX ABI is requested on a non-AIX system, replace the
24904 function name with the real name (with a leading .) rather than the
24905 function descriptor name. This saves a lot of overriding code to
24906 read the prefixes. */
24909 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
24911 default_encode_section_info (decl, rtl, first);
24914 && TREE_CODE (decl) == FUNCTION_DECL
24916 && DEFAULT_ABI == ABI_AIX)
24918 rtx sym_ref = XEXP (rtl, 0);
24919 size_t len = strlen (XSTR (sym_ref, 0));
24920 char *str = XALLOCAVEC (char, len + 2);
24922 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
24923 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
24928 compare_section_name (const char *section, const char *templ)
24932 len = strlen (templ);
24933 return (strncmp (section, templ, len) == 0
24934 && (section[len] == 0 || section[len] == '.'));
24938 rs6000_elf_in_small_data_p (const_tree decl)
24940 if (rs6000_sdata == SDATA_NONE)
24943 /* We want to merge strings, so we never consider them small data. */
24944 if (TREE_CODE (decl) == STRING_CST)
24947 /* Functions are never in the small data area. */
24948 if (TREE_CODE (decl) == FUNCTION_DECL)
24951 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
24953 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
24954 if (compare_section_name (section, ".sdata")
24955 || compare_section_name (section, ".sdata2")
24956 || compare_section_name (section, ".gnu.linkonce.s")
24957 || compare_section_name (section, ".sbss")
24958 || compare_section_name (section, ".sbss2")
24959 || compare_section_name (section, ".gnu.linkonce.sb")
24960 || strcmp (section, ".PPC.EMB.sdata0") == 0
24961 || strcmp (section, ".PPC.EMB.sbss0") == 0)
24966 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
24969 && size <= g_switch_value
24970 /* If it's not public, and we're not going to reference it there,
24971 there's no need to put it in the small data section. */
24972 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
24979 #endif /* USING_ELFOS_H */
24981 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
24984 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
24986 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
24989 /* Return a REG that occurs in ADDR with coefficient 1.
24990 ADDR can be effectively incremented by incrementing REG.
24992 r0 is special and we must not select it as an address
24993 register by this routine since our caller will try to
24994 increment the returned register via an "la" instruction. */
24997 find_addr_reg (rtx addr)
24999 while (GET_CODE (addr) == PLUS)
25001 if (GET_CODE (XEXP (addr, 0)) == REG
25002 && REGNO (XEXP (addr, 0)) != 0)
25003 addr = XEXP (addr, 0);
25004 else if (GET_CODE (XEXP (addr, 1)) == REG
25005 && REGNO (XEXP (addr, 1)) != 0)
25006 addr = XEXP (addr, 1);
25007 else if (CONSTANT_P (XEXP (addr, 0)))
25008 addr = XEXP (addr, 1);
25009 else if (CONSTANT_P (XEXP (addr, 1)))
25010 addr = XEXP (addr, 0);
25012 gcc_unreachable ();
25014 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
25019 rs6000_fatal_bad_address (rtx op)
25021 fatal_insn ("bad address", op);
25026 typedef struct branch_island_d {
25027 tree function_name;
25032 DEF_VEC_O(branch_island);
25033 DEF_VEC_ALLOC_O(branch_island,gc);
25035 static VEC(branch_island,gc) *branch_islands;
25037 /* Remember to generate a branch island for far calls to the given
25041 add_compiler_branch_island (tree label_name, tree function_name,
25044 branch_island *bi = VEC_safe_push (branch_island, gc, branch_islands, NULL);
25046 bi->function_name = function_name;
25047 bi->label_name = label_name;
25048 bi->line_number = line_number;
25051 /* Generate far-jump branch islands for everything recorded in
25052 branch_islands. Invoked immediately after the last instruction of
25053 the epilogue has been emitted; the branch islands must be appended
25054 to, and contiguous with, the function body. Mach-O stubs are
25055 generated in machopic_output_stub(). */
25058 macho_branch_islands (void)
25062 while (!VEC_empty (branch_island, branch_islands))
25064 branch_island *bi = VEC_last (branch_island, branch_islands);
25065 const char *label = IDENTIFIER_POINTER (bi->label_name);
25066 const char *name = IDENTIFIER_POINTER (bi->function_name);
25067 char name_buf[512];
25068 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
25069 if (name[0] == '*' || name[0] == '&')
25070 strcpy (name_buf, name+1);
25074 strcpy (name_buf+1, name);
25076 strcpy (tmp_buf, "\n");
25077 strcat (tmp_buf, label);
25078 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25079 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25080 dbxout_stabd (N_SLINE, bi->line_number);
25081 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25084 if (TARGET_LINK_STACK)
25087 get_ppc476_thunk_name (name);
25088 strcat (tmp_buf, ":\n\tmflr r0\n\tbl ");
25089 strcat (tmp_buf, name);
25090 strcat (tmp_buf, "\n");
25091 strcat (tmp_buf, label);
25092 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
25096 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
25097 strcat (tmp_buf, label);
25098 strcat (tmp_buf, "_pic\n");
25099 strcat (tmp_buf, label);
25100 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
25103 strcat (tmp_buf, "\taddis r11,r11,ha16(");
25104 strcat (tmp_buf, name_buf);
25105 strcat (tmp_buf, " - ");
25106 strcat (tmp_buf, label);
25107 strcat (tmp_buf, "_pic)\n");
25109 strcat (tmp_buf, "\tmtlr r0\n");
25111 strcat (tmp_buf, "\taddi r12,r11,lo16(");
25112 strcat (tmp_buf, name_buf);
25113 strcat (tmp_buf, " - ");
25114 strcat (tmp_buf, label);
25115 strcat (tmp_buf, "_pic)\n");
25117 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
25121 strcat (tmp_buf, ":\nlis r12,hi16(");
25122 strcat (tmp_buf, name_buf);
25123 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
25124 strcat (tmp_buf, name_buf);
25125 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
25127 output_asm_insn (tmp_buf, 0);
25128 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25129 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25130 dbxout_stabd (N_SLINE, bi->line_number);
25131 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25132 VEC_pop (branch_island, branch_islands);
25136 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
25137 already there or not. */
25140 no_previous_def (tree function_name)
25145 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25146 if (function_name == bi->function_name)
25151 /* GET_PREV_LABEL gets the label name from the previous definition of
25155 get_prev_label (tree function_name)
25160 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25161 if (function_name == bi->function_name)
25162 return bi->label_name;
25166 /* INSN is either a function call or a millicode call. It may have an
25167 unconditional jump in its delay slot.
25169 CALL_DEST is the routine we are calling. */
25172 output_call (rtx insn, rtx *operands, int dest_operand_number,
25173 int cookie_operand_number)
25175 static char buf[256];
25176 if (darwin_emit_branch_islands
25177 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
25178 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
25181 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
25183 if (no_previous_def (funname))
25185 rtx label_rtx = gen_label_rtx ();
25186 char *label_buf, temp_buf[256];
25187 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
25188 CODE_LABEL_NUMBER (label_rtx));
25189 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
25190 labelname = get_identifier (label_buf);
25191 add_compiler_branch_island (labelname, funname, insn_line (insn));
25194 labelname = get_prev_label (funname);
25196 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
25197 instruction will reach 'foo', otherwise link as 'bl L42'".
25198 "L42" should be a 'branch island', that will do a far jump to
25199 'foo'. Branch islands are generated in
25200 macho_branch_islands(). */
25201 sprintf (buf, "jbsr %%z%d,%.246s",
25202 dest_operand_number, IDENTIFIER_POINTER (labelname));
25205 sprintf (buf, "bl %%z%d", dest_operand_number);
25209 /* Generate PIC and indirect symbol stubs. */
25212 machopic_output_stub (FILE *file, const char *symb, const char *stub)
25214 unsigned int length;
25215 char *symbol_name, *lazy_ptr_name;
25216 char *local_label_0;
25217 static int label = 0;
25219 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
25220 symb = (*targetm.strip_name_encoding) (symb);
25223 length = strlen (symb);
25224 symbol_name = XALLOCAVEC (char, length + 32);
25225 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
25227 lazy_ptr_name = XALLOCAVEC (char, length + 32);
25228 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
25231 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
25233 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
25237 fprintf (file, "\t.align 5\n");
25239 fprintf (file, "%s:\n", stub);
25240 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25243 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
25244 sprintf (local_label_0, "\"L%011d$spb\"", label);
25246 fprintf (file, "\tmflr r0\n");
25247 if (TARGET_LINK_STACK)
25250 get_ppc476_thunk_name (name);
25251 fprintf (file, "\tbl %s\n", name);
25252 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
25256 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
25257 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
25259 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
25260 lazy_ptr_name, local_label_0);
25261 fprintf (file, "\tmtlr r0\n");
25262 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
25263 (TARGET_64BIT ? "ldu" : "lwzu"),
25264 lazy_ptr_name, local_label_0);
25265 fprintf (file, "\tmtctr r12\n");
25266 fprintf (file, "\tbctr\n");
25270 fprintf (file, "\t.align 4\n");
25272 fprintf (file, "%s:\n", stub);
25273 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25275 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
25276 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
25277 (TARGET_64BIT ? "ldu" : "lwzu"),
25279 fprintf (file, "\tmtctr r12\n");
25280 fprintf (file, "\tbctr\n");
25283 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
25284 fprintf (file, "%s:\n", lazy_ptr_name);
25285 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25286 fprintf (file, "%sdyld_stub_binding_helper\n",
25287 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
25290 /* Legitimize PIC addresses. If the address is already
25291 position-independent, we return ORIG. Newly generated
25292 position-independent addresses go into a reg. This is REG if non
25293 zero, otherwise we allocate register(s) as necessary. */
25295 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
25298 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
25303 if (reg == NULL && ! reload_in_progress && ! reload_completed)
25304 reg = gen_reg_rtx (Pmode);
25306 if (GET_CODE (orig) == CONST)
25310 if (GET_CODE (XEXP (orig, 0)) == PLUS
25311 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
25314 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
25316 /* Use a different reg for the intermediate value, as
25317 it will be marked UNCHANGING. */
25318 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
25319 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
25322 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
25325 if (GET_CODE (offset) == CONST_INT)
25327 if (SMALL_INT (offset))
25328 return plus_constant (base, INTVAL (offset));
25329 else if (! reload_in_progress && ! reload_completed)
25330 offset = force_reg (Pmode, offset);
25333 rtx mem = force_const_mem (Pmode, orig);
25334 return machopic_legitimize_pic_address (mem, Pmode, reg);
25337 return gen_rtx_PLUS (Pmode, base, offset);
25340 /* Fall back on generic machopic code. */
25341 return machopic_legitimize_pic_address (orig, mode, reg);
25344 /* Output a .machine directive for the Darwin assembler, and call
25345 the generic start_file routine. */
25348 rs6000_darwin_file_start (void)
25350 static const struct
25356 { "ppc64", "ppc64", MASK_64BIT },
25357 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
25358 { "power4", "ppc970", 0 },
25359 { "G5", "ppc970", 0 },
25360 { "7450", "ppc7450", 0 },
25361 { "7400", "ppc7400", MASK_ALTIVEC },
25362 { "G4", "ppc7400", 0 },
25363 { "750", "ppc750", 0 },
25364 { "740", "ppc750", 0 },
25365 { "G3", "ppc750", 0 },
25366 { "604e", "ppc604e", 0 },
25367 { "604", "ppc604", 0 },
25368 { "603e", "ppc603", 0 },
25369 { "603", "ppc603", 0 },
25370 { "601", "ppc601", 0 },
25371 { NULL, "ppc", 0 } };
25372 const char *cpu_id = "";
25375 rs6000_file_start ();
25376 darwin_file_start ();
25378 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
25380 if (rs6000_default_cpu != 0 && rs6000_default_cpu[0] != '\0')
25381 cpu_id = rs6000_default_cpu;
25383 if (global_options_set.x_rs6000_cpu_index)
25384 cpu_id = processor_target_table[rs6000_cpu_index].name;
25386 /* Look through the mapping array. Pick the first name that either
25387 matches the argument, has a bit set in IF_SET that is also set
25388 in the target flags, or has a NULL name. */
25391 while (mapping[i].arg != NULL
25392 && strcmp (mapping[i].arg, cpu_id) != 0
25393 && (mapping[i].if_set & target_flags) == 0)
25396 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
25399 #endif /* TARGET_MACHO */
25403 rs6000_elf_reloc_rw_mask (void)
25407 else if (DEFAULT_ABI == ABI_AIX)
25413 /* Record an element in the table of global constructors. SYMBOL is
25414 a SYMBOL_REF of the function to be called; PRIORITY is a number
25415 between 0 and MAX_INIT_PRIORITY.
25417 This differs from default_named_section_asm_out_constructor in
25418 that we have special handling for -mrelocatable. */
25421 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
25423 const char *section = ".ctors";
25426 if (priority != DEFAULT_INIT_PRIORITY)
25428 sprintf (buf, ".ctors.%.5u",
25429 /* Invert the numbering so the linker puts us in the proper
25430 order; constructors are run from right to left, and the
25431 linker sorts in increasing order. */
25432 MAX_INIT_PRIORITY - priority);
25436 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25437 assemble_align (POINTER_SIZE);
25439 if (TARGET_RELOCATABLE)
25441 fputs ("\t.long (", asm_out_file);
25442 output_addr_const (asm_out_file, symbol);
25443 fputs (")@fixup\n", asm_out_file);
25446 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25450 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
25452 const char *section = ".dtors";
25455 if (priority != DEFAULT_INIT_PRIORITY)
25457 sprintf (buf, ".dtors.%.5u",
25458 /* Invert the numbering so the linker puts us in the proper
25459 order; constructors are run from right to left, and the
25460 linker sorts in increasing order. */
25461 MAX_INIT_PRIORITY - priority);
25465 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25466 assemble_align (POINTER_SIZE);
25468 if (TARGET_RELOCATABLE)
25470 fputs ("\t.long (", asm_out_file);
25471 output_addr_const (asm_out_file, symbol);
25472 fputs (")@fixup\n", asm_out_file);
25475 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25479 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
25483 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
25484 ASM_OUTPUT_LABEL (file, name);
25485 fputs (DOUBLE_INT_ASM_OP, file);
25486 rs6000_output_function_entry (file, name);
25487 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
25490 fputs ("\t.size\t", file);
25491 assemble_name (file, name);
25492 fputs (",24\n\t.type\t.", file);
25493 assemble_name (file, name);
25494 fputs (",@function\n", file);
25495 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
25497 fputs ("\t.globl\t.", file);
25498 assemble_name (file, name);
25503 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25504 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25505 rs6000_output_function_entry (file, name);
25506 fputs (":\n", file);
25510 if (TARGET_RELOCATABLE
25511 && !TARGET_SECURE_PLT
25512 && (get_pool_size () != 0 || crtl->profile)
25517 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
25519 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
25520 fprintf (file, "\t.long ");
25521 assemble_name (file, buf);
25523 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
25524 assemble_name (file, buf);
25528 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25529 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25531 if (DEFAULT_ABI == ABI_AIX)
25533 const char *desc_name, *orig_name;
25535 orig_name = (*targetm.strip_name_encoding) (name);
25536 desc_name = orig_name;
25537 while (*desc_name == '.')
25540 if (TREE_PUBLIC (decl))
25541 fprintf (file, "\t.globl %s\n", desc_name);
25543 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25544 fprintf (file, "%s:\n", desc_name);
25545 fprintf (file, "\t.long %s\n", orig_name);
25546 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
25547 if (DEFAULT_ABI == ABI_AIX)
25548 fputs ("\t.long 0\n", file);
25549 fprintf (file, "\t.previous\n");
25551 ASM_OUTPUT_LABEL (file, name);
25555 rs6000_elf_file_end (void)
25557 #ifdef HAVE_AS_GNU_ATTRIBUTE
25558 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
25560 if (rs6000_passes_float)
25561 fprintf (asm_out_file, "\t.gnu_attribute 4, %d\n",
25562 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
25563 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
25565 if (rs6000_passes_vector)
25566 fprintf (asm_out_file, "\t.gnu_attribute 8, %d\n",
25567 (TARGET_ALTIVEC_ABI ? 2
25568 : TARGET_SPE_ABI ? 3
25570 if (rs6000_returns_struct)
25571 fprintf (asm_out_file, "\t.gnu_attribute 12, %d\n",
25572 aix_struct_return ? 2 : 1);
25575 #ifdef POWERPC_LINUX
25577 file_end_indicate_exec_stack ();
25584 rs6000_xcoff_asm_output_anchor (rtx symbol)
25588 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
25589 SYMBOL_REF_BLOCK_OFFSET (symbol));
25590 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
25594 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
25596 fputs (GLOBAL_ASM_OP, stream);
25597 RS6000_OUTPUT_BASENAME (stream, name);
25598 putc ('\n', stream);
25601 /* A get_unnamed_decl callback, used for read-only sections. PTR
25602 points to the section string variable. */
25605 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
25607 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
25608 *(const char *const *) directive,
25609 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
25612 /* Likewise for read-write sections. */
25615 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
25617 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
25618 *(const char *const *) directive,
25619 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
25622 /* A get_unnamed_section callback, used for switching to toc_section. */
25625 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
25627 if (TARGET_MINIMAL_TOC)
25629 /* toc_section is always selected at least once from
25630 rs6000_xcoff_file_start, so this is guaranteed to
25631 always be defined once and only once in each file. */
25632 if (!toc_initialized)
25634 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
25635 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
25636 toc_initialized = 1;
25638 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
25639 (TARGET_32BIT ? "" : ",3"));
25642 fputs ("\t.toc\n", asm_out_file);
25645 /* Implement TARGET_ASM_INIT_SECTIONS. */
25648 rs6000_xcoff_asm_init_sections (void)
25650 read_only_data_section
25651 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
25652 &xcoff_read_only_section_name);
25654 private_data_section
25655 = get_unnamed_section (SECTION_WRITE,
25656 rs6000_xcoff_output_readwrite_section_asm_op,
25657 &xcoff_private_data_section_name);
25659 read_only_private_data_section
25660 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
25661 &xcoff_private_data_section_name);
25664 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
25666 readonly_data_section = read_only_data_section;
25667 exception_section = data_section;
25671 rs6000_xcoff_reloc_rw_mask (void)
25677 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
25678 tree decl ATTRIBUTE_UNUSED)
25681 static const char * const suffix[3] = { "PR", "RO", "RW" };
25683 if (flags & SECTION_CODE)
25685 else if (flags & SECTION_WRITE)
25690 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
25691 (flags & SECTION_CODE) ? "." : "",
25692 name, suffix[smclass], flags & SECTION_ENTSIZE);
25696 rs6000_xcoff_select_section (tree decl, int reloc,
25697 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
25699 if (decl_readonly_section (decl, reloc))
25701 if (TREE_PUBLIC (decl))
25702 return read_only_data_section;
25704 return read_only_private_data_section;
25708 if (TREE_PUBLIC (decl))
25709 return data_section;
25711 return private_data_section;
25716 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
25720 /* Use select_section for private and uninitialized data. */
25721 if (!TREE_PUBLIC (decl)
25722 || DECL_COMMON (decl)
25723 || DECL_INITIAL (decl) == NULL_TREE
25724 || DECL_INITIAL (decl) == error_mark_node
25725 || (flag_zero_initialized_in_bss
25726 && initializer_zerop (DECL_INITIAL (decl))))
25729 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
25730 name = (*targetm.strip_name_encoding) (name);
25731 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
25734 /* Select section for constant in constant pool.
25736 On RS/6000, all constants are in the private read-only data area.
25737 However, if this is being placed in the TOC it must be output as a
25741 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
25742 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
25744 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
25745 return toc_section;
25747 return read_only_private_data_section;
25750 /* Remove any trailing [DS] or the like from the symbol name. */
25752 static const char *
25753 rs6000_xcoff_strip_name_encoding (const char *name)
25758 len = strlen (name);
25759 if (name[len - 1] == ']')
25760 return ggc_alloc_string (name, len - 4);
25765 /* Section attributes. AIX is always PIC. */
25767 static unsigned int
25768 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
25770 unsigned int align;
25771 unsigned int flags = default_section_type_flags (decl, name, reloc);
25773 /* Align to at least UNIT size. */
25774 if (flags & SECTION_CODE)
25775 align = MIN_UNITS_PER_WORD;
25777 /* Increase alignment of large objects if not already stricter. */
25778 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
25779 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
25780 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
25782 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
25785 /* Output at beginning of assembler file.
25787 Initialize the section names for the RS/6000 at this point.
25789 Specify filename, including full path, to assembler.
25791 We want to go into the TOC section so at least one .toc will be emitted.
25792 Also, in order to output proper .bs/.es pairs, we need at least one static
25793 [RW] section emitted.
25795 Finally, declare mcount when profiling to make the assembler happy. */
25798 rs6000_xcoff_file_start (void)
25800 rs6000_gen_section_name (&xcoff_bss_section_name,
25801 main_input_filename, ".bss_");
25802 rs6000_gen_section_name (&xcoff_private_data_section_name,
25803 main_input_filename, ".rw_");
25804 rs6000_gen_section_name (&xcoff_read_only_section_name,
25805 main_input_filename, ".ro_");
25807 fputs ("\t.file\t", asm_out_file);
25808 output_quoted_string (asm_out_file, main_input_filename);
25809 fputc ('\n', asm_out_file);
25810 if (write_symbols != NO_DEBUG)
25811 switch_to_section (private_data_section);
25812 switch_to_section (text_section);
25814 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
25815 rs6000_file_start ();
25818 /* Output at end of assembler file.
25819 On the RS/6000, referencing data should automatically pull in text. */
25822 rs6000_xcoff_file_end (void)
25824 switch_to_section (text_section);
25825 fputs ("_section_.text:\n", asm_out_file);
25826 switch_to_section (data_section);
25827 fputs (TARGET_32BIT
25828 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
25831 #endif /* TARGET_XCOFF */
25833 /* Compute a (partial) cost for rtx X. Return true if the complete
25834 cost has been computed, and false if subexpressions should be
25835 scanned. In either case, *TOTAL contains the cost result. */
25838 rs6000_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
25839 int *total, bool speed)
25841 enum machine_mode mode = GET_MODE (x);
25845 /* On the RS/6000, if it is valid in the insn, it is free. */
25847 if (((outer_code == SET
25848 || outer_code == PLUS
25849 || outer_code == MINUS)
25850 && (satisfies_constraint_I (x)
25851 || satisfies_constraint_L (x)))
25852 || (outer_code == AND
25853 && (satisfies_constraint_K (x)
25855 ? satisfies_constraint_L (x)
25856 : satisfies_constraint_J (x))
25857 || mask_operand (x, mode)
25859 && mask64_operand (x, DImode))))
25860 || ((outer_code == IOR || outer_code == XOR)
25861 && (satisfies_constraint_K (x)
25863 ? satisfies_constraint_L (x)
25864 : satisfies_constraint_J (x))))
25865 || outer_code == ASHIFT
25866 || outer_code == ASHIFTRT
25867 || outer_code == LSHIFTRT
25868 || outer_code == ROTATE
25869 || outer_code == ROTATERT
25870 || outer_code == ZERO_EXTRACT
25871 || (outer_code == MULT
25872 && satisfies_constraint_I (x))
25873 || ((outer_code == DIV || outer_code == UDIV
25874 || outer_code == MOD || outer_code == UMOD)
25875 && exact_log2 (INTVAL (x)) >= 0)
25876 || (outer_code == COMPARE
25877 && (satisfies_constraint_I (x)
25878 || satisfies_constraint_K (x)))
25879 || ((outer_code == EQ || outer_code == NE)
25880 && (satisfies_constraint_I (x)
25881 || satisfies_constraint_K (x)
25883 ? satisfies_constraint_L (x)
25884 : satisfies_constraint_J (x))))
25885 || (outer_code == GTU
25886 && satisfies_constraint_I (x))
25887 || (outer_code == LTU
25888 && satisfies_constraint_P (x)))
25893 else if ((outer_code == PLUS
25894 && reg_or_add_cint_operand (x, VOIDmode))
25895 || (outer_code == MINUS
25896 && reg_or_sub_cint_operand (x, VOIDmode))
25897 || ((outer_code == SET
25898 || outer_code == IOR
25899 || outer_code == XOR)
25901 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
25903 *total = COSTS_N_INSNS (1);
25909 if (mode == DImode && code == CONST_DOUBLE)
25911 if ((outer_code == IOR || outer_code == XOR)
25912 && CONST_DOUBLE_HIGH (x) == 0
25913 && (CONST_DOUBLE_LOW (x)
25914 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
25919 else if ((outer_code == AND && and64_2_operand (x, DImode))
25920 || ((outer_code == SET
25921 || outer_code == IOR
25922 || outer_code == XOR)
25923 && CONST_DOUBLE_HIGH (x) == 0))
25925 *total = COSTS_N_INSNS (1);
25935 /* When optimizing for size, MEM should be slightly more expensive
25936 than generating address, e.g., (plus (reg) (const)).
25937 L1 cache latency is about two instructions. */
25938 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
25947 if (FLOAT_MODE_P (mode))
25948 *total = rs6000_cost->fp;
25950 *total = COSTS_N_INSNS (1);
25954 if (GET_CODE (XEXP (x, 1)) == CONST_INT
25955 && satisfies_constraint_I (XEXP (x, 1)))
25957 if (INTVAL (XEXP (x, 1)) >= -256
25958 && INTVAL (XEXP (x, 1)) <= 255)
25959 *total = rs6000_cost->mulsi_const9;
25961 *total = rs6000_cost->mulsi_const;
25963 else if (mode == SFmode)
25964 *total = rs6000_cost->fp;
25965 else if (FLOAT_MODE_P (mode))
25966 *total = rs6000_cost->dmul;
25967 else if (mode == DImode)
25968 *total = rs6000_cost->muldi;
25970 *total = rs6000_cost->mulsi;
25974 if (mode == SFmode)
25975 *total = rs6000_cost->fp;
25977 *total = rs6000_cost->dmul;
25982 if (FLOAT_MODE_P (mode))
25984 *total = mode == DFmode ? rs6000_cost->ddiv
25985 : rs6000_cost->sdiv;
25992 if (GET_CODE (XEXP (x, 1)) == CONST_INT
25993 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
25995 if (code == DIV || code == MOD)
25997 *total = COSTS_N_INSNS (2);
26000 *total = COSTS_N_INSNS (1);
26004 if (GET_MODE (XEXP (x, 1)) == DImode)
26005 *total = rs6000_cost->divdi;
26007 *total = rs6000_cost->divsi;
26009 /* Add in shift and subtract for MOD. */
26010 if (code == MOD || code == UMOD)
26011 *total += COSTS_N_INSNS (2);
26016 *total = COSTS_N_INSNS (4);
26020 *total = COSTS_N_INSNS (TARGET_POPCNTD ? 1 : 6);
26024 *total = COSTS_N_INSNS (TARGET_CMPB ? 2 : 6);
26028 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
26040 *total = COSTS_N_INSNS (1);
26048 /* Handle mul_highpart. */
26049 if (outer_code == TRUNCATE
26050 && GET_CODE (XEXP (x, 0)) == MULT)
26052 if (mode == DImode)
26053 *total = rs6000_cost->muldi;
26055 *total = rs6000_cost->mulsi;
26058 else if (outer_code == AND)
26061 *total = COSTS_N_INSNS (1);
26066 if (GET_CODE (XEXP (x, 0)) == MEM)
26069 *total = COSTS_N_INSNS (1);
26075 if (!FLOAT_MODE_P (mode))
26077 *total = COSTS_N_INSNS (1);
26083 case UNSIGNED_FLOAT:
26086 case FLOAT_TRUNCATE:
26087 *total = rs6000_cost->fp;
26091 if (mode == DFmode)
26094 *total = rs6000_cost->fp;
26098 switch (XINT (x, 1))
26101 *total = rs6000_cost->fp;
26113 *total = COSTS_N_INSNS (1);
26116 else if (FLOAT_MODE_P (mode)
26117 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
26119 *total = rs6000_cost->fp;
26127 /* Carry bit requires mode == Pmode.
26128 NEG or PLUS already counted so only add one. */
26130 && (outer_code == NEG || outer_code == PLUS))
26132 *total = COSTS_N_INSNS (1);
26135 if (outer_code == SET)
26137 if (XEXP (x, 1) == const0_rtx)
26139 if (TARGET_ISEL && !TARGET_MFCRF)
26140 *total = COSTS_N_INSNS (8);
26142 *total = COSTS_N_INSNS (2);
26145 else if (mode == Pmode)
26147 *total = COSTS_N_INSNS (3);
26156 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
26158 if (TARGET_ISEL && !TARGET_MFCRF)
26159 *total = COSTS_N_INSNS (8);
26161 *total = COSTS_N_INSNS (2);
26165 if (outer_code == COMPARE)
26179 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
26182 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int opno, int *total,
26185 bool ret = rs6000_rtx_costs (x, code, outer_code, opno, total, speed);
26188 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
26189 "opno = %d, total = %d, speed = %s, x:\n",
26190 ret ? "complete" : "scan inner",
26191 GET_RTX_NAME (code),
26192 GET_RTX_NAME (outer_code),
26195 speed ? "true" : "false");
26202 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
26205 rs6000_debug_address_cost (rtx x, bool speed)
26207 int ret = TARGET_ADDRESS_COST (x, speed);
26209 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
26210 ret, speed ? "true" : "false");
26217 /* A C expression returning the cost of moving data from a register of class
26218 CLASS1 to one of CLASS2. */
26221 rs6000_register_move_cost (enum machine_mode mode,
26222 reg_class_t from, reg_class_t to)
26226 if (TARGET_DEBUG_COST)
26229 /* Moves from/to GENERAL_REGS. */
26230 if (reg_classes_intersect_p (to, GENERAL_REGS)
26231 || reg_classes_intersect_p (from, GENERAL_REGS))
26233 reg_class_t rclass = from;
26235 if (! reg_classes_intersect_p (to, GENERAL_REGS))
26238 if (rclass == FLOAT_REGS || rclass == ALTIVEC_REGS || rclass == VSX_REGS)
26239 ret = (rs6000_memory_move_cost (mode, rclass, false)
26240 + rs6000_memory_move_cost (mode, GENERAL_REGS, false));
26242 /* It's more expensive to move CR_REGS than CR0_REGS because of the
26244 else if (rclass == CR_REGS)
26247 /* For those processors that have slow LR/CTR moves, make them more
26248 expensive than memory in order to bias spills to memory .*/
26249 else if ((rs6000_cpu == PROCESSOR_POWER6
26250 || rs6000_cpu == PROCESSOR_POWER7)
26251 && reg_classes_intersect_p (rclass, LINK_OR_CTR_REGS))
26252 ret = 6 * hard_regno_nregs[0][mode];
26255 /* A move will cost one instruction per GPR moved. */
26256 ret = 2 * hard_regno_nregs[0][mode];
26259 /* If we have VSX, we can easily move between FPR or Altivec registers. */
26260 else if (VECTOR_UNIT_VSX_P (mode)
26261 && reg_classes_intersect_p (to, VSX_REGS)
26262 && reg_classes_intersect_p (from, VSX_REGS))
26263 ret = 2 * hard_regno_nregs[32][mode];
26265 /* Moving between two similar registers is just one instruction. */
26266 else if (reg_classes_intersect_p (to, from))
26267 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
26269 /* Everything else has to go through GENERAL_REGS. */
26271 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
26272 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
26274 if (TARGET_DEBUG_COST)
26276 if (dbg_cost_ctrl == 1)
26278 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
26279 ret, GET_MODE_NAME (mode), reg_class_names[from],
26280 reg_class_names[to]);
26287 /* A C expressions returning the cost of moving data of MODE from a register to
26291 rs6000_memory_move_cost (enum machine_mode mode, reg_class_t rclass,
26292 bool in ATTRIBUTE_UNUSED)
26296 if (TARGET_DEBUG_COST)
26299 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
26300 ret = 4 * hard_regno_nregs[0][mode];
26301 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
26302 ret = 4 * hard_regno_nregs[32][mode];
26303 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
26304 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
26306 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
26308 if (TARGET_DEBUG_COST)
26310 if (dbg_cost_ctrl == 1)
26312 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
26313 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
26320 /* Returns a code for a target-specific builtin that implements
26321 reciprocal of the function, or NULL_TREE if not available. */
26324 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
26325 bool sqrt ATTRIBUTE_UNUSED)
26327 if (optimize_insn_for_size_p ())
26333 case VSX_BUILTIN_XVSQRTDP:
26334 if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode))
26337 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
26339 case VSX_BUILTIN_XVSQRTSP:
26340 if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode))
26343 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V4SF];
26352 case BUILT_IN_SQRT:
26353 if (!RS6000_RECIP_AUTO_RSQRTE_P (DFmode))
26356 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRT];
26358 case BUILT_IN_SQRTF:
26359 if (!RS6000_RECIP_AUTO_RSQRTE_P (SFmode))
26362 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
26369 /* Load up a constant. If the mode is a vector mode, splat the value across
26370 all of the vector elements. */
26373 rs6000_load_constant_and_splat (enum machine_mode mode, REAL_VALUE_TYPE dconst)
26377 if (mode == SFmode || mode == DFmode)
26379 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, mode);
26380 reg = force_reg (mode, d);
26382 else if (mode == V4SFmode)
26384 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, SFmode);
26385 rtvec v = gen_rtvec (4, d, d, d, d);
26386 reg = gen_reg_rtx (mode);
26387 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26389 else if (mode == V2DFmode)
26391 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, DFmode);
26392 rtvec v = gen_rtvec (2, d, d);
26393 reg = gen_reg_rtx (mode);
26394 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26397 gcc_unreachable ();
26402 /* Generate an FMA instruction. */
26405 rs6000_emit_madd (rtx target, rtx m1, rtx m2, rtx a)
26407 enum machine_mode mode = GET_MODE (target);
26410 dst = expand_ternary_op (mode, fma_optab, m1, m2, a, target, 0);
26411 gcc_assert (dst != NULL);
26414 emit_move_insn (target, dst);
26417 /* Generate a FMSUB instruction: dst = fma(m1, m2, -a). */
26420 rs6000_emit_msub (rtx target, rtx m1, rtx m2, rtx a)
26422 enum machine_mode mode = GET_MODE (target);
26425 /* Altivec does not support fms directly;
26426 generate in terms of fma in that case. */
26427 if (optab_handler (fms_optab, mode) != CODE_FOR_nothing)
26428 dst = expand_ternary_op (mode, fms_optab, m1, m2, a, target, 0);
26431 a = expand_unop (mode, neg_optab, a, NULL_RTX, 0);
26432 dst = expand_ternary_op (mode, fma_optab, m1, m2, a, target, 0);
26434 gcc_assert (dst != NULL);
26437 emit_move_insn (target, dst);
26440 /* Generate a FNMSUB instruction: dst = -fma(m1, m2, -a). */
26443 rs6000_emit_nmsub (rtx dst, rtx m1, rtx m2, rtx a)
26445 enum machine_mode mode = GET_MODE (dst);
26448 /* This is a tad more complicated, since the fnma_optab is for
26449 a different expression: fma(-m1, m2, a), which is the same
26450 thing except in the case of signed zeros.
26452 Fortunately we know that if FMA is supported that FNMSUB is
26453 also supported in the ISA. Just expand it directly. */
26455 gcc_assert (optab_handler (fma_optab, mode) != CODE_FOR_nothing);
26457 r = gen_rtx_NEG (mode, a);
26458 r = gen_rtx_FMA (mode, m1, m2, r);
26459 r = gen_rtx_NEG (mode, r);
26460 emit_insn (gen_rtx_SET (VOIDmode, dst, r));
26463 /* Newton-Raphson approximation of floating point divide with just 2 passes
26464 (either single precision floating point, or newer machines with higher
26465 accuracy estimates). Support both scalar and vector divide. Assumes no
26466 trapping math and finite arguments. */
26469 rs6000_emit_swdiv_high_precision (rtx dst, rtx n, rtx d)
26471 enum machine_mode mode = GET_MODE (dst);
26472 rtx x0, e0, e1, y1, u0, v0;
26473 enum insn_code code = optab_handler (smul_optab, mode);
26474 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26475 rtx one = rs6000_load_constant_and_splat (mode, dconst1);
26477 gcc_assert (code != CODE_FOR_nothing);
26479 /* x0 = 1./d estimate */
26480 x0 = gen_reg_rtx (mode);
26481 emit_insn (gen_rtx_SET (VOIDmode, x0,
26482 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26485 e0 = gen_reg_rtx (mode);
26486 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - (d * x0) */
26488 e1 = gen_reg_rtx (mode);
26489 rs6000_emit_madd (e1, e0, e0, e0); /* e1 = (e0 * e0) + e0 */
26491 y1 = gen_reg_rtx (mode);
26492 rs6000_emit_madd (y1, e1, x0, x0); /* y1 = (e1 * x0) + x0 */
26494 u0 = gen_reg_rtx (mode);
26495 emit_insn (gen_mul (u0, n, y1)); /* u0 = n * y1 */
26497 v0 = gen_reg_rtx (mode);
26498 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - (d * u0) */
26500 rs6000_emit_madd (dst, v0, y1, u0); /* dst = (v0 * y1) + u0 */
26503 /* Newton-Raphson approximation of floating point divide that has a low
26504 precision estimate. Assumes no trapping math and finite arguments. */
26507 rs6000_emit_swdiv_low_precision (rtx dst, rtx n, rtx d)
26509 enum machine_mode mode = GET_MODE (dst);
26510 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
26511 enum insn_code code = optab_handler (smul_optab, mode);
26512 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26514 gcc_assert (code != CODE_FOR_nothing);
26516 one = rs6000_load_constant_and_splat (mode, dconst1);
26518 /* x0 = 1./d estimate */
26519 x0 = gen_reg_rtx (mode);
26520 emit_insn (gen_rtx_SET (VOIDmode, x0,
26521 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26524 e0 = gen_reg_rtx (mode);
26525 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - d * x0 */
26527 y1 = gen_reg_rtx (mode);
26528 rs6000_emit_madd (y1, e0, x0, x0); /* y1 = x0 + e0 * x0 */
26530 e1 = gen_reg_rtx (mode);
26531 emit_insn (gen_mul (e1, e0, e0)); /* e1 = e0 * e0 */
26533 y2 = gen_reg_rtx (mode);
26534 rs6000_emit_madd (y2, e1, y1, y1); /* y2 = y1 + e1 * y1 */
26536 e2 = gen_reg_rtx (mode);
26537 emit_insn (gen_mul (e2, e1, e1)); /* e2 = e1 * e1 */
26539 y3 = gen_reg_rtx (mode);
26540 rs6000_emit_madd (y3, e2, y2, y2); /* y3 = y2 + e2 * y2 */
26542 u0 = gen_reg_rtx (mode);
26543 emit_insn (gen_mul (u0, n, y3)); /* u0 = n * y3 */
26545 v0 = gen_reg_rtx (mode);
26546 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - d * u0 */
26548 rs6000_emit_madd (dst, v0, y3, u0); /* dst = u0 + v0 * y3 */
26551 /* Newton-Raphson approximation of floating point divide DST = N/D. If NOTE_P,
26552 add a reg_note saying that this was a division. Support both scalar and
26553 vector divide. Assumes no trapping math and finite arguments. */
26556 rs6000_emit_swdiv (rtx dst, rtx n, rtx d, bool note_p)
26558 enum machine_mode mode = GET_MODE (dst);
26560 if (RS6000_RECIP_HIGH_PRECISION_P (mode))
26561 rs6000_emit_swdiv_high_precision (dst, n, d);
26563 rs6000_emit_swdiv_low_precision (dst, n, d);
26566 add_reg_note (get_last_insn (), REG_EQUAL, gen_rtx_DIV (mode, n, d));
26569 /* Newton-Raphson approximation of single/double-precision floating point
26570 rsqrt. Assumes no trapping math and finite arguments. */
26573 rs6000_emit_swrsqrt (rtx dst, rtx src)
26575 enum machine_mode mode = GET_MODE (src);
26576 rtx x0 = gen_reg_rtx (mode);
26577 rtx y = gen_reg_rtx (mode);
26578 int passes = (TARGET_RECIP_PRECISION) ? 2 : 3;
26579 REAL_VALUE_TYPE dconst3_2;
26582 enum insn_code code = optab_handler (smul_optab, mode);
26583 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26585 gcc_assert (code != CODE_FOR_nothing);
26587 /* Load up the constant 1.5 either as a scalar, or as a vector. */
26588 real_from_integer (&dconst3_2, VOIDmode, 3, 0, 0);
26589 SET_REAL_EXP (&dconst3_2, REAL_EXP (&dconst3_2) - 1);
26591 halfthree = rs6000_load_constant_and_splat (mode, dconst3_2);
26593 /* x0 = rsqrt estimate */
26594 emit_insn (gen_rtx_SET (VOIDmode, x0,
26595 gen_rtx_UNSPEC (mode, gen_rtvec (1, src),
26598 /* y = 0.5 * src = 1.5 * src - src -> fewer constants */
26599 rs6000_emit_msub (y, src, halfthree, src);
26601 for (i = 0; i < passes; i++)
26603 rtx x1 = gen_reg_rtx (mode);
26604 rtx u = gen_reg_rtx (mode);
26605 rtx v = gen_reg_rtx (mode);
26607 /* x1 = x0 * (1.5 - y * (x0 * x0)) */
26608 emit_insn (gen_mul (u, x0, x0));
26609 rs6000_emit_nmsub (v, y, u, halfthree);
26610 emit_insn (gen_mul (x1, x0, v));
26614 emit_move_insn (dst, x0);
26618 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
26619 (Power7) targets. DST is the target, and SRC is the argument operand. */
26622 rs6000_emit_popcount (rtx dst, rtx src)
26624 enum machine_mode mode = GET_MODE (dst);
26627 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
26628 if (TARGET_POPCNTD)
26630 if (mode == SImode)
26631 emit_insn (gen_popcntdsi2 (dst, src));
26633 emit_insn (gen_popcntddi2 (dst, src));
26637 tmp1 = gen_reg_rtx (mode);
26639 if (mode == SImode)
26641 emit_insn (gen_popcntbsi2 (tmp1, src));
26642 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
26644 tmp2 = force_reg (SImode, tmp2);
26645 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
26649 emit_insn (gen_popcntbdi2 (tmp1, src));
26650 tmp2 = expand_mult (DImode, tmp1,
26651 GEN_INT ((HOST_WIDE_INT)
26652 0x01010101 << 32 | 0x01010101),
26654 tmp2 = force_reg (DImode, tmp2);
26655 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
26660 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
26661 target, and SRC is the argument operand. */
26664 rs6000_emit_parity (rtx dst, rtx src)
26666 enum machine_mode mode = GET_MODE (dst);
26669 tmp = gen_reg_rtx (mode);
26671 /* Use the PPC ISA 2.05 prtyw/prtyd instruction if we can. */
26674 if (mode == SImode)
26676 emit_insn (gen_popcntbsi2 (tmp, src));
26677 emit_insn (gen_paritysi2_cmpb (dst, tmp));
26681 emit_insn (gen_popcntbdi2 (tmp, src));
26682 emit_insn (gen_paritydi2_cmpb (dst, tmp));
26687 if (mode == SImode)
26689 /* Is mult+shift >= shift+xor+shift+xor? */
26690 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
26692 rtx tmp1, tmp2, tmp3, tmp4;
26694 tmp1 = gen_reg_rtx (SImode);
26695 emit_insn (gen_popcntbsi2 (tmp1, src));
26697 tmp2 = gen_reg_rtx (SImode);
26698 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
26699 tmp3 = gen_reg_rtx (SImode);
26700 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
26702 tmp4 = gen_reg_rtx (SImode);
26703 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
26704 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
26707 rs6000_emit_popcount (tmp, src);
26708 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
26712 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
26713 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
26715 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
26717 tmp1 = gen_reg_rtx (DImode);
26718 emit_insn (gen_popcntbdi2 (tmp1, src));
26720 tmp2 = gen_reg_rtx (DImode);
26721 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
26722 tmp3 = gen_reg_rtx (DImode);
26723 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
26725 tmp4 = gen_reg_rtx (DImode);
26726 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
26727 tmp5 = gen_reg_rtx (DImode);
26728 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
26730 tmp6 = gen_reg_rtx (DImode);
26731 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
26732 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
26735 rs6000_emit_popcount (tmp, src);
26736 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
26740 /* Return an RTX representing where to find the function value of a
26741 function returning MODE. */
26743 rs6000_complex_function_value (enum machine_mode mode)
26745 unsigned int regno;
26747 enum machine_mode inner = GET_MODE_INNER (mode);
26748 unsigned int inner_bytes = GET_MODE_SIZE (inner);
26750 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26751 regno = FP_ARG_RETURN;
26754 regno = GP_ARG_RETURN;
26756 /* 32-bit is OK since it'll go in r3/r4. */
26757 if (TARGET_32BIT && inner_bytes >= 4)
26758 return gen_rtx_REG (mode, regno);
26761 if (inner_bytes >= 8)
26762 return gen_rtx_REG (mode, regno);
26764 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
26766 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
26767 GEN_INT (inner_bytes));
26768 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
26771 /* Target hook for TARGET_FUNCTION_VALUE.
26773 On the SPE, both FPs and vectors are returned in r3.
26775 On RS/6000 an integer value is in r3 and a floating-point value is in
26776 fp1, unless -msoft-float. */
26779 rs6000_function_value (const_tree valtype,
26780 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
26781 bool outgoing ATTRIBUTE_UNUSED)
26783 enum machine_mode mode;
26784 unsigned int regno;
26786 /* Special handling for structs in darwin64. */
26788 && rs6000_darwin64_struct_check_p (TYPE_MODE (valtype), valtype))
26790 CUMULATIVE_ARGS valcum;
26794 valcum.fregno = FP_ARG_MIN_REG;
26795 valcum.vregno = ALTIVEC_ARG_MIN_REG;
26796 /* Do a trial code generation as if this were going to be passed as
26797 an argument; if any part goes in memory, we return NULL. */
26798 valret = rs6000_darwin64_record_arg (&valcum, valtype, true, /* retval= */ true);
26801 /* Otherwise fall through to standard ABI rules. */
26804 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
26806 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26807 return gen_rtx_PARALLEL (DImode,
26809 gen_rtx_EXPR_LIST (VOIDmode,
26810 gen_rtx_REG (SImode, GP_ARG_RETURN),
26812 gen_rtx_EXPR_LIST (VOIDmode,
26813 gen_rtx_REG (SImode,
26814 GP_ARG_RETURN + 1),
26817 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
26819 return gen_rtx_PARALLEL (DCmode,
26821 gen_rtx_EXPR_LIST (VOIDmode,
26822 gen_rtx_REG (SImode, GP_ARG_RETURN),
26824 gen_rtx_EXPR_LIST (VOIDmode,
26825 gen_rtx_REG (SImode,
26826 GP_ARG_RETURN + 1),
26828 gen_rtx_EXPR_LIST (VOIDmode,
26829 gen_rtx_REG (SImode,
26830 GP_ARG_RETURN + 2),
26832 gen_rtx_EXPR_LIST (VOIDmode,
26833 gen_rtx_REG (SImode,
26834 GP_ARG_RETURN + 3),
26838 mode = TYPE_MODE (valtype);
26839 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
26840 || POINTER_TYPE_P (valtype))
26841 mode = TARGET_32BIT ? SImode : DImode;
26843 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26844 /* _Decimal128 must use an even/odd register pair. */
26845 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26846 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
26847 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
26848 regno = FP_ARG_RETURN;
26849 else if (TREE_CODE (valtype) == COMPLEX_TYPE
26850 && targetm.calls.split_complex_arg)
26851 return rs6000_complex_function_value (mode);
26852 /* VSX is a superset of Altivec and adds V2DImode/V2DFmode. Since the same
26853 return register is used in both cases, and we won't see V2DImode/V2DFmode
26854 for pure altivec, combine the two cases. */
26855 else if (TREE_CODE (valtype) == VECTOR_TYPE
26856 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
26857 && ALTIVEC_OR_VSX_VECTOR_MODE (mode))
26858 regno = ALTIVEC_ARG_RETURN;
26859 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26860 && (mode == DFmode || mode == DCmode
26861 || mode == TFmode || mode == TCmode))
26862 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26864 regno = GP_ARG_RETURN;
26866 return gen_rtx_REG (mode, regno);
26869 /* Define how to find the value returned by a library function
26870 assuming the value has mode MODE. */
26872 rs6000_libcall_value (enum machine_mode mode)
26874 unsigned int regno;
26876 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
26878 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26879 return gen_rtx_PARALLEL (DImode,
26881 gen_rtx_EXPR_LIST (VOIDmode,
26882 gen_rtx_REG (SImode, GP_ARG_RETURN),
26884 gen_rtx_EXPR_LIST (VOIDmode,
26885 gen_rtx_REG (SImode,
26886 GP_ARG_RETURN + 1),
26890 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26891 /* _Decimal128 must use an even/odd register pair. */
26892 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26893 else if (SCALAR_FLOAT_MODE_P (mode)
26894 && TARGET_HARD_FLOAT && TARGET_FPRS
26895 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
26896 regno = FP_ARG_RETURN;
26897 /* VSX is a superset of Altivec and adds V2DImode/V2DFmode. Since the same
26898 return register is used in both cases, and we won't see V2DImode/V2DFmode
26899 for pure altivec, combine the two cases. */
26900 else if (ALTIVEC_OR_VSX_VECTOR_MODE (mode)
26901 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
26902 regno = ALTIVEC_ARG_RETURN;
26903 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
26904 return rs6000_complex_function_value (mode);
26905 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26906 && (mode == DFmode || mode == DCmode
26907 || mode == TFmode || mode == TCmode))
26908 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26910 regno = GP_ARG_RETURN;
26912 return gen_rtx_REG (mode, regno);
26916 /* Given FROM and TO register numbers, say whether this elimination is allowed.
26917 Frame pointer elimination is automatically handled.
26919 For the RS/6000, if frame pointer elimination is being done, we would like
26920 to convert ap into fp, not sp.
26922 We need r30 if -mminimal-toc was specified, and there are constant pool
26926 rs6000_can_eliminate (const int from, const int to)
26928 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
26929 ? ! frame_pointer_needed
26930 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
26931 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
26935 /* Define the offset between two registers, FROM to be eliminated and its
26936 replacement TO, at the start of a routine. */
26938 rs6000_initial_elimination_offset (int from, int to)
26940 rs6000_stack_t *info = rs6000_stack_info ();
26941 HOST_WIDE_INT offset;
26943 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26944 offset = info->push_p ? 0 : -info->total_size;
26945 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26947 offset = info->push_p ? 0 : -info->total_size;
26948 if (FRAME_GROWS_DOWNWARD)
26949 offset += info->fixed_size + info->vars_size + info->parm_size;
26951 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26952 offset = FRAME_GROWS_DOWNWARD
26953 ? info->fixed_size + info->vars_size + info->parm_size
26955 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26956 offset = info->total_size;
26957 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26958 offset = info->push_p ? info->total_size : 0;
26959 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
26962 gcc_unreachable ();
26968 rs6000_dwarf_register_span (rtx reg)
26972 unsigned regno = REGNO (reg);
26973 enum machine_mode mode = GET_MODE (reg);
26977 && (SPE_VECTOR_MODE (GET_MODE (reg))
26978 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
26979 && mode != SFmode && mode != SDmode && mode != SCmode)))
26984 regno = REGNO (reg);
26986 /* The duality of the SPE register size wreaks all kinds of havoc.
26987 This is a way of distinguishing r0 in 32-bits from r0 in
26989 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
26990 gcc_assert (words <= 4);
26991 for (i = 0; i < words; i++, regno++)
26993 if (BYTES_BIG_ENDIAN)
26995 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
26996 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
27000 parts[2 * i] = gen_rtx_REG (SImode, regno);
27001 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
27005 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
27008 /* Fill in sizes for SPE register high parts in table used by unwinder. */
27011 rs6000_init_dwarf_reg_sizes_extra (tree address)
27016 enum machine_mode mode = TYPE_MODE (char_type_node);
27017 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
27018 rtx mem = gen_rtx_MEM (BLKmode, addr);
27019 rtx value = gen_int_mode (4, mode);
27021 for (i = 1201; i < 1232; i++)
27023 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
27024 HOST_WIDE_INT offset
27025 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
27027 emit_move_insn (adjust_address (mem, mode, offset), value);
27032 /* Map internal gcc register numbers to DWARF2 register numbers. */
27035 rs6000_dbx_register_number (unsigned int regno)
27037 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
27039 if (regno == MQ_REGNO)
27041 if (regno == LR_REGNO)
27043 if (regno == CTR_REGNO)
27045 if (CR_REGNO_P (regno))
27046 return regno - CR0_REGNO + 86;
27047 if (regno == CA_REGNO)
27048 return 101; /* XER */
27049 if (ALTIVEC_REGNO_P (regno))
27050 return regno - FIRST_ALTIVEC_REGNO + 1124;
27051 if (regno == VRSAVE_REGNO)
27053 if (regno == VSCR_REGNO)
27055 if (regno == SPE_ACC_REGNO)
27057 if (regno == SPEFSCR_REGNO)
27059 /* SPE high reg number. We get these values of regno from
27060 rs6000_dwarf_register_span. */
27061 gcc_assert (regno >= 1200 && regno < 1232);
27065 /* target hook eh_return_filter_mode */
27066 static enum machine_mode
27067 rs6000_eh_return_filter_mode (void)
27069 return TARGET_32BIT ? SImode : word_mode;
27072 /* Target hook for scalar_mode_supported_p. */
27074 rs6000_scalar_mode_supported_p (enum machine_mode mode)
27076 if (DECIMAL_FLOAT_MODE_P (mode))
27077 return default_decimal_float_supported_p ();
27079 return default_scalar_mode_supported_p (mode);
27082 /* Target hook for vector_mode_supported_p. */
27084 rs6000_vector_mode_supported_p (enum machine_mode mode)
27087 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
27090 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
27093 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
27100 /* Target hook for invalid_arg_for_unprototyped_fn. */
27101 static const char *
27102 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
27104 return (!rs6000_darwin64_abi
27106 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
27107 && (funcdecl == NULL_TREE
27108 || (TREE_CODE (funcdecl) == FUNCTION_DECL
27109 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
27110 ? N_("AltiVec argument passed to unprototyped function")
27114 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
27115 setup by using __stack_chk_fail_local hidden function instead of
27116 calling __stack_chk_fail directly. Otherwise it is better to call
27117 __stack_chk_fail directly. */
27119 static tree ATTRIBUTE_UNUSED
27120 rs6000_stack_protect_fail (void)
27122 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
27123 ? default_hidden_stack_protect_fail ()
27124 : default_external_stack_protect_fail ();
27128 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
27129 int num_operands ATTRIBUTE_UNUSED)
27131 if (rs6000_warn_cell_microcode)
27134 int insn_code_number = recog_memoized (insn);
27135 location_t location = locator_location (INSN_LOCATOR (insn));
27137 /* Punt on insns we cannot recognize. */
27138 if (insn_code_number < 0)
27141 temp = get_insn_template (insn_code_number, insn);
27143 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
27144 warning_at (location, OPT_mwarn_cell_microcode,
27145 "emitting microcode insn %s\t[%s] #%d",
27146 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27147 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
27148 warning_at (location, OPT_mwarn_cell_microcode,
27149 "emitting conditional microcode insn %s\t[%s] #%d",
27150 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27155 /* Mask options that we want to support inside of attribute((target)) and
27156 #pragma GCC target operations. Note, we do not include things like
27157 64/32-bit, endianess, hard/soft floating point, etc. that would have
27158 different calling sequences. */
27160 struct rs6000_opt_mask {
27161 const char *name; /* option name */
27162 int mask; /* mask to set */
27163 bool invert; /* invert sense of mask */
27164 bool valid_target; /* option is a target option */
27167 static struct rs6000_opt_mask const rs6000_opt_masks[] =
27169 { "altivec", MASK_ALTIVEC, false, true },
27170 { "cmpb", MASK_CMPB, false, true },
27171 { "dlmzb", MASK_DLMZB, false, true },
27172 { "fprnd", MASK_FPRND, false, true },
27173 { "hard-dfp", MASK_DFP, false, true },
27174 { "isel", MASK_ISEL, false, true },
27175 { "mfcrf", MASK_MFCRF, false, true },
27176 { "mfpgpr", MASK_MFPGPR, false, true },
27177 { "mulhw", MASK_MULHW, false, true },
27178 { "multiple", MASK_MULTIPLE, false, true },
27179 { "update", MASK_NO_UPDATE, true , true },
27180 { "popcntb", MASK_POPCNTB, false, true },
27181 { "popcntd", MASK_POPCNTD, false, true },
27182 { "powerpc-gfxopt", MASK_PPC_GFXOPT, false, true },
27183 { "powerpc-gpopt", MASK_PPC_GPOPT, false, true },
27184 { "recip-precision", MASK_RECIP_PRECISION, false, true },
27185 { "string", MASK_STRING, false, true },
27186 { "vsx", MASK_VSX, false, true },
27189 { "aix64", MASK_64BIT, false, false },
27190 { "aix32", MASK_64BIT, true, false },
27192 { "64", MASK_64BIT, false, false },
27193 { "32", MASK_64BIT, true, false },
27197 { "eabi", MASK_EABI, false, false },
27199 #ifdef MASK_LITTLE_ENDIAN
27200 { "little", MASK_LITTLE_ENDIAN, false, false },
27201 { "big", MASK_LITTLE_ENDIAN, true, false },
27203 #ifdef MASK_RELOCATABLE
27204 { "relocatable", MASK_RELOCATABLE, false, false },
27206 #ifdef MASK_STRICT_ALIGN
27207 { "strict-align", MASK_STRICT_ALIGN, false, false },
27209 { "power", MASK_POWER, false, false },
27210 { "power2", MASK_POWER2, false, false },
27211 { "powerpc", MASK_POWERPC, false, false },
27212 { "soft-float", MASK_SOFT_FLOAT, false, false },
27213 { "string", MASK_STRING, false, false },
27216 /* Option variables that we want to support inside attribute((target)) and
27217 #pragma GCC target operations. */
27219 struct rs6000_opt_var {
27220 const char *name; /* option name */
27221 size_t global_offset; /* offset of the option in global_options. */
27222 size_t target_offset; /* offset of the option in target optiosn. */
27225 static struct rs6000_opt_var const rs6000_opt_vars[] =
27228 offsetof (struct gcc_options, x_TARGET_FRIZ),
27229 offsetof (struct cl_target_option, x_TARGET_FRIZ), },
27230 { "avoid-indexed-addresses",
27231 offsetof (struct gcc_options, x_TARGET_AVOID_XFORM),
27232 offsetof (struct cl_target_option, x_TARGET_AVOID_XFORM) },
27234 offsetof (struct gcc_options, x_rs6000_paired_float),
27235 offsetof (struct cl_target_option, x_rs6000_paired_float), },
27237 offsetof (struct gcc_options, x_rs6000_default_long_calls),
27238 offsetof (struct cl_target_option, x_rs6000_default_long_calls), },
27241 /* Inner function to handle attribute((target("..."))) and #pragma GCC target
27242 parsing. Return true if there were no errors. */
27245 rs6000_inner_target_options (tree args, bool attr_p)
27249 if (args == NULL_TREE)
27252 else if (TREE_CODE (args) == STRING_CST)
27254 char *p = ASTRDUP (TREE_STRING_POINTER (args));
27257 while ((q = strtok (p, ",")) != NULL)
27259 bool error_p = false;
27260 bool not_valid_p = false;
27261 const char *cpu_opt = NULL;
27264 if (strncmp (q, "cpu=", 4) == 0)
27266 int cpu_index = rs6000_cpu_name_lookup (q+4);
27267 if (cpu_index >= 0)
27268 rs6000_cpu_index = cpu_index;
27275 else if (strncmp (q, "tune=", 5) == 0)
27277 int tune_index = rs6000_cpu_name_lookup (q+5);
27278 if (tune_index >= 0)
27279 rs6000_tune_index = tune_index;
27289 bool invert = false;
27293 if (strncmp (r, "no-", 3) == 0)
27299 for (i = 0; i < ARRAY_SIZE (rs6000_opt_masks); i++)
27300 if (strcmp (r, rs6000_opt_masks[i].name) == 0)
27302 int mask = rs6000_opt_masks[i].mask;
27304 if (!rs6000_opt_masks[i].valid_target)
27305 not_valid_p = true;
27309 target_flags_explicit |= mask;
27311 if (rs6000_opt_masks[i].invert)
27315 target_flags &= ~mask;
27317 target_flags |= mask;
27322 if (error_p && !not_valid_p)
27324 for (i = 0; i < ARRAY_SIZE (rs6000_opt_vars); i++)
27325 if (strcmp (r, rs6000_opt_vars[i].name) == 0)
27327 size_t j = rs6000_opt_vars[i].global_offset;
27328 ((int *) &global_options)[j] = !invert;
27337 const char *eprefix, *esuffix;
27342 eprefix = "__attribute__((__target__(";
27347 eprefix = "#pragma GCC target ";
27352 error ("invalid cpu \"%s\" for %s\"%s\"%s", cpu_opt, eprefix,
27354 else if (not_valid_p)
27355 error ("%s\"%s\"%s is not allowed", eprefix, q, esuffix);
27357 error ("%s\"%s\"%s is invalid", eprefix, q, esuffix);
27362 else if (TREE_CODE (args) == TREE_LIST)
27366 tree value = TREE_VALUE (args);
27369 bool ret2 = rs6000_inner_target_options (value, attr_p);
27373 args = TREE_CHAIN (args);
27375 while (args != NULL_TREE);
27379 gcc_unreachable ();
27384 /* Print out the target options as a list for -mdebug=target. */
27387 rs6000_debug_target_options (tree args, const char *prefix)
27389 if (args == NULL_TREE)
27390 fprintf (stderr, "%s<NULL>", prefix);
27392 else if (TREE_CODE (args) == STRING_CST)
27394 char *p = ASTRDUP (TREE_STRING_POINTER (args));
27397 while ((q = strtok (p, ",")) != NULL)
27400 fprintf (stderr, "%s\"%s\"", prefix, q);
27405 else if (TREE_CODE (args) == TREE_LIST)
27409 tree value = TREE_VALUE (args);
27412 rs6000_debug_target_options (value, prefix);
27415 args = TREE_CHAIN (args);
27417 while (args != NULL_TREE);
27421 gcc_unreachable ();
27427 /* Hook to validate attribute((target("..."))). */
27430 rs6000_valid_attribute_p (tree fndecl,
27431 tree ARG_UNUSED (name),
27435 struct cl_target_option cur_target;
27437 tree old_optimize = build_optimization_node ();
27438 tree new_target, new_optimize;
27439 tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
27441 gcc_assert ((fndecl != NULL_TREE) && (args != NULL_TREE));
27443 if (TARGET_DEBUG_TARGET)
27445 tree tname = DECL_NAME (fndecl);
27446 fprintf (stderr, "\n==================== rs6000_valid_attribute_p:\n");
27448 fprintf (stderr, "function: %.*s\n",
27449 (int) IDENTIFIER_LENGTH (tname),
27450 IDENTIFIER_POINTER (tname));
27452 fprintf (stderr, "function: unknown\n");
27454 fprintf (stderr, "args:");
27455 rs6000_debug_target_options (args, " ");
27456 fprintf (stderr, "\n");
27459 fprintf (stderr, "flags: 0x%x\n", flags);
27461 fprintf (stderr, "--------------------\n");
27464 old_optimize = build_optimization_node ();
27465 func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
27467 /* If the function changed the optimization levels as well as setting target
27468 options, start with the optimizations specified. */
27469 if (func_optimize && func_optimize != old_optimize)
27470 cl_optimization_restore (&global_options,
27471 TREE_OPTIMIZATION (func_optimize));
27473 /* The target attributes may also change some optimization flags, so update
27474 the optimization options if necessary. */
27475 cl_target_option_save (&cur_target, &global_options);
27476 rs6000_cpu_index = rs6000_tune_index = -1;
27477 ret = rs6000_inner_target_options (args, true);
27479 /* Set up any additional state. */
27482 ret = rs6000_option_override_internal (false);
27483 new_target = build_target_option_node ();
27488 new_optimize = build_optimization_node ();
27495 DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target;
27497 if (old_optimize != new_optimize)
27498 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
27501 cl_target_option_restore (&global_options, &cur_target);
27503 if (old_optimize != new_optimize)
27504 cl_optimization_restore (&global_options,
27505 TREE_OPTIMIZATION (old_optimize));
27511 /* Hook to validate the current #pragma GCC target and set the state, and
27512 update the macros based on what was changed. If ARGS is NULL, then
27513 POP_TARGET is used to reset the options. */
27516 rs6000_pragma_target_parse (tree args, tree pop_target)
27521 if (TARGET_DEBUG_TARGET)
27523 fprintf (stderr, "\n==================== rs6000_pragma_target_parse\n");
27524 fprintf (stderr, "args:");
27525 rs6000_debug_target_options (args, " ");
27526 fprintf (stderr, "\n");
27530 fprintf (stderr, "pop_target:\n");
27531 debug_tree (pop_target);
27534 fprintf (stderr, "pop_target: <NULL>\n");
27536 fprintf (stderr, "--------------------\n");
27542 cur_tree = ((pop_target)
27544 : target_option_default_node);
27545 cl_target_option_restore (&global_options,
27546 TREE_TARGET_OPTION (cur_tree));
27550 rs6000_cpu_index = rs6000_tune_index = -1;
27551 ret = rs6000_inner_target_options (args, false);
27552 cur_tree = build_target_option_node ();
27559 target_option_current_node = cur_tree;
27565 /* Remember the last target of rs6000_set_current_function. */
27566 static GTY(()) tree rs6000_previous_fndecl;
27568 /* Establish appropriate back-end context for processing the function
27569 FNDECL. The argument might be NULL to indicate processing at top
27570 level, outside of any function scope. */
27572 rs6000_set_current_function (tree fndecl)
27574 tree old_tree = (rs6000_previous_fndecl
27575 ? DECL_FUNCTION_SPECIFIC_TARGET (rs6000_previous_fndecl)
27578 tree new_tree = (fndecl
27579 ? DECL_FUNCTION_SPECIFIC_TARGET (fndecl)
27582 if (TARGET_DEBUG_TARGET)
27584 bool print_final = false;
27585 fprintf (stderr, "\n==================== rs6000_set_current_function");
27588 fprintf (stderr, ", fndecl %s (%p)",
27589 (DECL_NAME (fndecl)
27590 ? IDENTIFIER_POINTER (DECL_NAME (fndecl))
27591 : "<unknown>"), (void *)fndecl);
27593 if (rs6000_previous_fndecl)
27594 fprintf (stderr, ", prev_fndecl (%p)", (void *)rs6000_previous_fndecl);
27596 fprintf (stderr, "\n");
27599 fprintf (stderr, "\nnew fndecl target specific options:\n");
27600 debug_tree (new_tree);
27601 print_final = true;
27606 fprintf (stderr, "\nold fndecl target specific options:\n");
27607 debug_tree (old_tree);
27608 print_final = true;
27612 fprintf (stderr, "--------------------\n");
27615 /* Only change the context if the function changes. This hook is called
27616 several times in the course of compiling a function, and we don't want to
27617 slow things down too much or call target_reinit when it isn't safe. */
27618 if (fndecl && fndecl != rs6000_previous_fndecl)
27620 rs6000_previous_fndecl = fndecl;
27621 if (old_tree == new_tree)
27626 cl_target_option_restore (&global_options,
27627 TREE_TARGET_OPTION (new_tree));
27633 struct cl_target_option *def
27634 = TREE_TARGET_OPTION (target_option_current_node);
27636 cl_target_option_restore (&global_options, def);
27643 /* Save the current options */
27646 rs6000_function_specific_save (struct cl_target_option *ptr)
27648 ptr->rs6000_target_flags_explicit = target_flags_explicit;
27651 /* Restore the current options */
27654 rs6000_function_specific_restore (struct cl_target_option *ptr)
27656 target_flags_explicit = ptr->rs6000_target_flags_explicit;
27657 (void) rs6000_option_override_internal (false);
27660 /* Print the current options */
27663 rs6000_function_specific_print (FILE *file, int indent,
27664 struct cl_target_option *ptr)
27667 int flags = ptr->x_target_flags;
27669 /* Print the various mask options. */
27670 for (i = 0; i < ARRAY_SIZE (rs6000_opt_masks); i++)
27671 if ((flags & rs6000_opt_masks[i].mask) != 0)
27673 flags &= ~ rs6000_opt_masks[i].mask;
27674 fprintf (file, "%*s-m%s%s\n", indent, "",
27675 rs6000_opt_masks[i].invert ? "no-" : "",
27676 rs6000_opt_masks[i].name);
27679 /* Print the various options that are variables. */
27680 for (i = 0; i < ARRAY_SIZE (rs6000_opt_vars); i++)
27682 size_t j = rs6000_opt_vars[i].target_offset;
27683 if (((signed char *) ptr)[j])
27684 fprintf (file, "%*s-m%s\n", indent, "",
27685 rs6000_opt_vars[i].name);
27690 /* Hook to determine if one function can safely inline another. */
27693 rs6000_can_inline_p (tree caller, tree callee)
27696 tree caller_tree = DECL_FUNCTION_SPECIFIC_TARGET (caller);
27697 tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (callee);
27699 /* If callee has no option attributes, then it is ok to inline. */
27703 /* If caller has no option attributes, but callee does then it is not ok to
27705 else if (!caller_tree)
27710 struct cl_target_option *caller_opts = TREE_TARGET_OPTION (caller_tree);
27711 struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree);
27713 /* Callee's options should a subset of the caller's, i.e. a vsx function
27714 can inline an altivec function but a non-vsx function can't inline a
27716 if ((caller_opts->x_target_flags & callee_opts->x_target_flags)
27717 == callee_opts->x_target_flags)
27721 if (TARGET_DEBUG_TARGET)
27722 fprintf (stderr, "rs6000_can_inline_p:, caller %s, callee %s, %s inline\n",
27723 (DECL_NAME (caller)
27724 ? IDENTIFIER_POINTER (DECL_NAME (caller))
27726 (DECL_NAME (callee)
27727 ? IDENTIFIER_POINTER (DECL_NAME (callee))
27729 (ret ? "can" : "cannot"));
27734 /* Allocate a stack temp and fixup the address so it meets the particular
27735 memory requirements (either offetable or REG+REG addressing). */
27738 rs6000_allocate_stack_temp (enum machine_mode mode,
27739 bool offsettable_p,
27742 rtx stack = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
27743 rtx addr = XEXP (stack, 0);
27744 int strict_p = (reload_in_progress || reload_completed);
27746 if (!legitimate_indirect_address_p (addr, strict_p))
27749 && !rs6000_legitimate_offset_address_p (mode, addr, strict_p))
27750 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
27752 else if (reg_reg_p && !legitimate_indexed_address_p (addr, strict_p))
27753 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
27759 /* Given a memory reference, if it is not a reg or reg+reg addressing, convert
27760 to such a form to deal with memory reference instructions like STFIWX that
27761 only take reg+reg addressing. */
27764 rs6000_address_for_fpconvert (rtx x)
27766 int strict_p = (reload_in_progress || reload_completed);
27769 gcc_assert (MEM_P (x));
27770 addr = XEXP (x, 0);
27771 if (! legitimate_indirect_address_p (addr, strict_p)
27772 && ! legitimate_indexed_address_p (addr, strict_p))
27774 if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)
27776 rtx reg = XEXP (addr, 0);
27777 HOST_WIDE_INT size = GET_MODE_SIZE (GET_MODE (x));
27778 rtx size_rtx = GEN_INT ((GET_CODE (addr) == PRE_DEC) ? -size : size);
27779 gcc_assert (REG_P (reg));
27780 emit_insn (gen_add3_insn (reg, reg, size_rtx));
27783 else if (GET_CODE (addr) == PRE_MODIFY)
27785 rtx reg = XEXP (addr, 0);
27786 rtx expr = XEXP (addr, 1);
27787 gcc_assert (REG_P (reg));
27788 gcc_assert (GET_CODE (expr) == PLUS);
27789 emit_insn (gen_add3_insn (reg, XEXP (expr, 0), XEXP (expr, 1)));
27793 x = replace_equiv_address (x, copy_addr_to_reg (addr));
27799 /* Given a memory reference, if it is not in the form for altivec memory
27800 reference instructions (i.e. reg or reg+reg addressing with AND of -16),
27801 convert to the altivec format. */
27804 rs6000_address_for_altivec (rtx x)
27806 gcc_assert (MEM_P (x));
27807 if (!altivec_indexed_or_indirect_operand (x, GET_MODE (x)))
27809 rtx addr = XEXP (x, 0);
27810 int strict_p = (reload_in_progress || reload_completed);
27812 if (!legitimate_indexed_address_p (addr, strict_p)
27813 && !legitimate_indirect_address_p (addr, strict_p))
27814 addr = copy_to_mode_reg (Pmode, addr);
27816 addr = gen_rtx_AND (Pmode, addr, GEN_INT (-16));
27817 x = change_address (x, GET_MODE (x), addr);
27823 /* Implement TARGET_LEGITIMATE_CONSTANT_P.
27825 On the RS/6000, all integer constants are acceptable, most won't be valid
27826 for particular insns, though. Only easy FP constants are acceptable. */
27829 rs6000_legitimate_constant_p (enum machine_mode mode, rtx x)
27831 if (rs6000_tls_referenced_p (x))
27834 return ((GET_CODE (x) != CONST_DOUBLE && GET_CODE (x) != CONST_VECTOR)
27835 || GET_MODE (x) == VOIDmode
27836 || (TARGET_POWERPC64 && mode == DImode)
27837 || easy_fp_constant (x, mode)
27838 || easy_vector_constant (x, mode));
27842 /* A function pointer under AIX is a pointer to a data area whose first word
27843 contains the actual address of the function, whose second word contains a
27844 pointer to its TOC, and whose third word contains a value to place in the
27845 static chain register (r11). Note that if we load the static chain, our
27846 "trampoline" need not have any executable code. */
27849 rs6000_call_indirect_aix (rtx value, rtx func_desc, rtx flag)
27855 rtx stack_toc_offset;
27857 rtx func_toc_offset;
27859 rtx func_sc_offset;
27862 rtx (*call_func) (rtx, rtx, rtx, rtx);
27863 rtx (*call_value_func) (rtx, rtx, rtx, rtx, rtx);
27865 stack_ptr = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
27866 toc_reg = gen_rtx_REG (Pmode, TOC_REGNUM);
27868 /* Load up address of the actual function. */
27869 func_desc = force_reg (Pmode, func_desc);
27870 func_addr = gen_reg_rtx (Pmode);
27871 emit_move_insn (func_addr, gen_rtx_MEM (Pmode, func_desc));
27876 stack_toc_offset = GEN_INT (TOC_SAVE_OFFSET_32BIT);
27877 func_toc_offset = GEN_INT (AIX_FUNC_DESC_TOC_32BIT);
27878 func_sc_offset = GEN_INT (AIX_FUNC_DESC_SC_32BIT);
27879 if (TARGET_POINTERS_TO_NESTED_FUNCTIONS)
27881 call_func = gen_call_indirect_aix32bit;
27882 call_value_func = gen_call_value_indirect_aix32bit;
27886 call_func = gen_call_indirect_aix32bit_nor11;
27887 call_value_func = gen_call_value_indirect_aix32bit_nor11;
27892 stack_toc_offset = GEN_INT (TOC_SAVE_OFFSET_64BIT);
27893 func_toc_offset = GEN_INT (AIX_FUNC_DESC_TOC_64BIT);
27894 func_sc_offset = GEN_INT (AIX_FUNC_DESC_SC_64BIT);
27895 if (TARGET_POINTERS_TO_NESTED_FUNCTIONS)
27897 call_func = gen_call_indirect_aix64bit;
27898 call_value_func = gen_call_value_indirect_aix64bit;
27902 call_func = gen_call_indirect_aix64bit_nor11;
27903 call_value_func = gen_call_value_indirect_aix64bit_nor11;
27907 /* Reserved spot to store the TOC. */
27908 stack_toc_mem = gen_frame_mem (Pmode,
27909 gen_rtx_PLUS (Pmode,
27911 stack_toc_offset));
27914 gcc_assert (cfun->machine);
27916 /* Can we optimize saving the TOC in the prologue or do we need to do it at
27918 if (TARGET_SAVE_TOC_INDIRECT && !cfun->calls_alloca)
27919 cfun->machine->save_toc_in_prologue = true;
27923 MEM_VOLATILE_P (stack_toc_mem) = 1;
27924 emit_move_insn (stack_toc_mem, toc_reg);
27927 /* Calculate the address to load the TOC of the called function. We don't
27928 actually load this until the split after reload. */
27929 func_toc_mem = gen_rtx_MEM (Pmode,
27930 gen_rtx_PLUS (Pmode,
27934 /* If we have a static chain, load it up. */
27935 if (TARGET_POINTERS_TO_NESTED_FUNCTIONS)
27937 func_sc_mem = gen_rtx_MEM (Pmode,
27938 gen_rtx_PLUS (Pmode,
27942 sc_reg = gen_rtx_REG (Pmode, STATIC_CHAIN_REGNUM);
27943 emit_move_insn (sc_reg, func_sc_mem);
27946 /* Create the call. */
27948 insn = call_value_func (value, func_addr, flag, func_toc_mem,
27951 insn = call_func (func_addr, flag, func_toc_mem, stack_toc_mem);
27953 emit_call_insn (insn);
27956 /* Return whether we need to always update the saved TOC pointer when we update
27957 the stack pointer. */
27960 rs6000_save_toc_in_prologue_p (void)
27962 return (cfun && cfun->machine && cfun->machine->save_toc_in_prologue);
27965 #ifdef HAVE_GAS_HIDDEN
27966 # define USE_HIDDEN_LINKONCE 1
27968 # define USE_HIDDEN_LINKONCE 0
27971 /* Fills in the label name that should be used for a 476 link stack thunk. */
27974 get_ppc476_thunk_name (char name[32])
27976 gcc_assert (TARGET_LINK_STACK);
27978 if (USE_HIDDEN_LINKONCE)
27979 sprintf (name, "__ppc476.get_thunk");
27981 ASM_GENERATE_INTERNAL_LABEL (name, "LPPC476_", 0);
27984 /* This function emits the simple thunk routine that is used to preserve
27985 the link stack on the 476 cpu. */
27988 rs6000_code_end (void)
27993 if (!TARGET_LINK_STACK)
27996 get_ppc476_thunk_name (name);
27998 decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL, get_identifier (name),
27999 build_function_type_list (void_type_node, NULL_TREE));
28000 DECL_RESULT (decl) = build_decl (BUILTINS_LOCATION, RESULT_DECL,
28001 NULL_TREE, void_type_node);
28002 TREE_PUBLIC (decl) = 1;
28003 TREE_STATIC (decl) = 1;
28005 if (USE_HIDDEN_LINKONCE)
28007 DECL_COMDAT_GROUP (decl) = DECL_ASSEMBLER_NAME (decl);
28008 targetm.asm_out.unique_section (decl, 0);
28009 switch_to_section (get_named_section (decl, NULL, 0));
28010 DECL_WEAK (decl) = 1;
28011 ASM_WEAKEN_DECL (asm_out_file, decl, name, 0);
28012 targetm.asm_out.globalize_label (asm_out_file, name);
28013 targetm.asm_out.assemble_visibility (decl, VISIBILITY_HIDDEN);
28014 ASM_DECLARE_FUNCTION_NAME (asm_out_file, name, decl);
28018 switch_to_section (text_section);
28019 ASM_OUTPUT_LABEL (asm_out_file, name);
28022 DECL_INITIAL (decl) = make_node (BLOCK);
28023 current_function_decl = decl;
28024 init_function_start (decl);
28025 first_function_block_is_cold = false;
28026 /* Make sure unwind info is emitted for the thunk if needed. */
28027 final_start_function (emit_barrier (), asm_out_file, 1);
28029 fputs ("\tblr\n", asm_out_file);
28031 final_end_function ();
28032 init_insn_lengths ();
28033 free_after_compilation (cfun);
28035 current_function_decl = NULL;
28038 struct gcc_target targetm = TARGET_INITIALIZER;
28040 #include "gt-rs6000.h"