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 rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int,
903 enum machine_mode, bool, bool, bool);
904 static bool rs6000_reg_live_or_pic_offset_p (int);
905 static tree rs6000_builtin_vectorized_libmass (tree, tree, tree);
906 static tree rs6000_builtin_vectorized_function (tree, tree, tree);
907 static void rs6000_restore_saved_cr (rtx, int);
908 static bool rs6000_output_addr_const_extra (FILE *, rtx);
909 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
910 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
911 static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
913 static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
914 static bool rs6000_return_in_memory (const_tree, const_tree);
915 static rtx rs6000_function_value (const_tree, const_tree, bool);
916 static void rs6000_file_start (void);
918 static int rs6000_elf_reloc_rw_mask (void);
919 static void rs6000_elf_asm_out_constructor (rtx, int) ATTRIBUTE_UNUSED;
920 static void rs6000_elf_asm_out_destructor (rtx, int) ATTRIBUTE_UNUSED;
921 static void rs6000_elf_file_end (void) ATTRIBUTE_UNUSED;
922 static void rs6000_elf_asm_init_sections (void);
923 static section *rs6000_elf_select_rtx_section (enum machine_mode, rtx,
924 unsigned HOST_WIDE_INT);
925 static void rs6000_elf_encode_section_info (tree, rtx, int)
928 static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx);
929 static void rs6000_alloc_sdmode_stack_slot (void);
930 static void rs6000_instantiate_decls (void);
932 static void rs6000_xcoff_asm_output_anchor (rtx);
933 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
934 static void rs6000_xcoff_asm_init_sections (void);
935 static int rs6000_xcoff_reloc_rw_mask (void);
936 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree);
937 static section *rs6000_xcoff_select_section (tree, int,
938 unsigned HOST_WIDE_INT);
939 static void rs6000_xcoff_unique_section (tree, int);
940 static section *rs6000_xcoff_select_rtx_section
941 (enum machine_mode, rtx, unsigned HOST_WIDE_INT);
942 static const char * rs6000_xcoff_strip_name_encoding (const char *);
943 static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
944 static void rs6000_xcoff_file_start (void);
945 static void rs6000_xcoff_file_end (void);
947 static int rs6000_variable_issue (FILE *, int, rtx, int);
948 static int rs6000_register_move_cost (enum machine_mode,
949 reg_class_t, reg_class_t);
950 static int rs6000_memory_move_cost (enum machine_mode, reg_class_t, bool);
951 static bool rs6000_rtx_costs (rtx, int, int, int *, bool);
952 static bool rs6000_debug_rtx_costs (rtx, int, int, int *, bool);
953 static int rs6000_debug_address_cost (rtx, bool);
954 static int rs6000_adjust_cost (rtx, rtx, rtx, int);
955 static int rs6000_debug_adjust_cost (rtx, rtx, rtx, int);
956 static void rs6000_sched_init (FILE *, int, int);
957 static bool is_microcoded_insn (rtx);
958 static bool is_nonpipeline_insn (rtx);
959 static bool is_cracked_insn (rtx);
960 static bool is_branch_slot_insn (rtx);
961 static bool is_load_insn (rtx);
962 static rtx get_store_dest (rtx pat);
963 static bool is_store_insn (rtx);
964 static bool set_to_load_agen (rtx,rtx);
965 static bool adjacent_mem_locations (rtx,rtx);
966 static int rs6000_adjust_priority (rtx, int);
967 static int rs6000_issue_rate (void);
968 static bool rs6000_is_costly_dependence (dep_t, int, int);
969 static rtx get_next_active_insn (rtx, rtx);
970 static bool insn_terminates_group_p (rtx , enum group_termination);
971 static bool insn_must_be_first_in_group (rtx);
972 static bool insn_must_be_last_in_group (rtx);
973 static bool is_costly_group (rtx *, rtx);
974 static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
975 static int redefine_groups (FILE *, int, rtx, rtx);
976 static int pad_groups (FILE *, int, rtx, rtx);
977 static void rs6000_sched_finish (FILE *, int);
978 static int rs6000_sched_reorder (FILE *, int, rtx *, int *, int);
979 static int rs6000_sched_reorder2 (FILE *, int, rtx *, int *, int);
980 static int rs6000_use_sched_lookahead (void);
981 static int rs6000_use_sched_lookahead_guard (rtx);
982 static void * rs6000_alloc_sched_context (void);
983 static void rs6000_init_sched_context (void *, bool);
984 static void rs6000_set_sched_context (void *);
985 static void rs6000_free_sched_context (void *);
986 static tree rs6000_builtin_reciprocal (unsigned int, bool, bool);
987 static tree rs6000_builtin_mask_for_load (void);
988 static tree rs6000_builtin_mul_widen_even (tree);
989 static tree rs6000_builtin_mul_widen_odd (tree);
990 static tree rs6000_builtin_conversion (unsigned int, tree, tree);
991 static tree rs6000_builtin_vec_perm (tree, tree *);
992 static bool rs6000_builtin_support_vector_misalignment (enum
996 static int rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt,
998 static enum machine_mode rs6000_preferred_simd_mode (enum machine_mode);
1000 static void def_builtin (int, const char *, tree, int);
1001 static bool rs6000_vector_alignment_reachable (const_tree, bool);
1002 static void rs6000_init_builtins (void);
1003 static tree rs6000_builtin_decl (unsigned, bool);
1005 static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
1006 static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
1007 static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
1008 static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
1009 static void altivec_init_builtins (void);
1010 static unsigned builtin_hash_function (const void *);
1011 static int builtin_hash_eq (const void *, const void *);
1012 static tree builtin_function_type (enum machine_mode, enum machine_mode,
1013 enum machine_mode, enum machine_mode,
1014 enum rs6000_builtins, const char *name);
1015 static void rs6000_common_init_builtins (void);
1016 static void rs6000_init_libfuncs (void);
1018 static void paired_init_builtins (void);
1019 static rtx paired_expand_builtin (tree, rtx, bool *);
1020 static rtx paired_expand_lv_builtin (enum insn_code, tree, rtx);
1021 static rtx paired_expand_stv_builtin (enum insn_code, tree);
1022 static rtx paired_expand_predicate_builtin (enum insn_code, tree, rtx);
1024 static void enable_mask_for_builtins (struct builtin_description *, int,
1025 enum rs6000_builtins,
1026 enum rs6000_builtins);
1027 static void spe_init_builtins (void);
1028 static rtx spe_expand_builtin (tree, rtx, bool *);
1029 static rtx spe_expand_stv_builtin (enum insn_code, tree);
1030 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
1031 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
1032 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
1033 static rs6000_stack_t *rs6000_stack_info (void);
1034 static void debug_stack_info (rs6000_stack_t *);
1036 static rtx altivec_expand_builtin (tree, rtx, bool *);
1037 static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
1038 static rtx altivec_expand_st_builtin (tree, rtx, bool *);
1039 static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
1040 static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
1041 static rtx altivec_expand_predicate_builtin (enum insn_code, tree, rtx);
1042 static rtx altivec_expand_stv_builtin (enum insn_code, tree);
1043 static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
1044 static rtx altivec_expand_vec_set_builtin (tree);
1045 static rtx altivec_expand_vec_ext_builtin (tree, rtx);
1046 static int get_element_number (tree, tree);
1047 static void rs6000_option_override (void);
1048 static int rs6000_loop_align_max_skip (rtx);
1049 static int first_altivec_reg_to_save (void);
1050 static unsigned int compute_vrsave_mask (void);
1051 static void compute_save_world_info (rs6000_stack_t *info_ptr);
1052 static void is_altivec_return_reg (rtx, void *);
1053 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
1054 int easy_vector_constant (rtx, enum machine_mode);
1055 static rtx rs6000_dwarf_register_span (rtx);
1056 static void rs6000_init_dwarf_reg_sizes_extra (tree);
1057 static rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode);
1058 static rtx rs6000_debug_legitimize_address (rtx, rtx, enum machine_mode);
1059 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
1060 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
1061 static rtx rs6000_delegitimize_address (rtx);
1062 static rtx rs6000_tls_get_addr (void);
1063 static rtx rs6000_got_sym (void);
1064 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
1065 static const char *rs6000_get_some_local_dynamic_name (void);
1066 static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
1067 static rtx rs6000_complex_function_value (enum machine_mode);
1068 static rtx rs6000_spe_function_arg (const CUMULATIVE_ARGS *,
1069 enum machine_mode, const_tree);
1070 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
1071 HOST_WIDE_INT, int);
1072 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
1075 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
1078 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
1079 const_tree, HOST_WIDE_INT,
1081 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, bool, bool);
1082 static rtx rs6000_mixed_function_arg (enum machine_mode, const_tree, int);
1083 static void rs6000_function_arg_advance (cumulative_args_t, enum machine_mode,
1085 static rtx rs6000_function_arg (cumulative_args_t, enum machine_mode,
1087 static unsigned int rs6000_function_arg_boundary (enum machine_mode,
1089 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
1090 static void setup_incoming_varargs (cumulative_args_t,
1091 enum machine_mode, tree,
1093 static bool rs6000_pass_by_reference (cumulative_args_t, enum machine_mode,
1095 static int rs6000_arg_partial_bytes (cumulative_args_t, enum machine_mode,
1097 static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree);
1099 static void macho_branch_islands (void);
1100 static int no_previous_def (tree function_name);
1101 static tree get_prev_label (tree function_name);
1102 static void rs6000_darwin_file_start (void);
1105 static tree rs6000_build_builtin_va_list (void);
1106 static void rs6000_va_start (tree, rtx);
1107 static tree rs6000_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
1108 static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree);
1109 static bool rs6000_scalar_mode_supported_p (enum machine_mode);
1110 static bool rs6000_vector_mode_supported_p (enum machine_mode);
1111 static rtx rs6000_emit_vector_compare_inner (enum rtx_code, rtx, rtx);
1112 static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
1114 static tree rs6000_stack_protect_fail (void);
1116 static rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, int, int,
1119 static rtx rs6000_debug_legitimize_reload_address (rtx, enum machine_mode, int,
1122 rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode, int, int,
1124 = rs6000_legitimize_reload_address;
1126 static bool rs6000_mode_dependent_address_p (const_rtx);
1127 static bool rs6000_mode_dependent_address (const_rtx);
1128 static bool rs6000_debug_mode_dependent_address (const_rtx);
1129 static bool (*rs6000_mode_dependent_address_ptr) (const_rtx)
1130 = rs6000_mode_dependent_address;
1132 static enum reg_class rs6000_secondary_reload_class (enum reg_class,
1133 enum machine_mode, rtx);
1134 static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class,
1137 enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class,
1138 enum machine_mode, rtx)
1139 = rs6000_secondary_reload_class;
1141 static enum reg_class rs6000_preferred_reload_class (rtx, enum reg_class);
1142 static enum reg_class rs6000_debug_preferred_reload_class (rtx,
1144 enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, enum reg_class)
1145 = rs6000_preferred_reload_class;
1147 static bool rs6000_secondary_memory_needed (enum reg_class, enum reg_class,
1150 static bool rs6000_debug_secondary_memory_needed (enum reg_class,
1154 bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class,
1156 = rs6000_secondary_memory_needed;
1158 static bool rs6000_cannot_change_mode_class (enum machine_mode,
1161 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode,
1165 bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode,
1168 = rs6000_cannot_change_mode_class;
1170 static reg_class_t rs6000_secondary_reload (bool, rtx, reg_class_t,
1172 struct secondary_reload_info *);
1174 const int INSN_NOT_AVAILABLE = -1;
1175 static enum machine_mode rs6000_eh_return_filter_mode (void);
1176 static bool rs6000_can_eliminate (const int, const int);
1177 static void rs6000_conditional_register_usage (void);
1178 static void rs6000_trampoline_init (rtx, tree, rtx);
1179 static bool rs6000_cannot_force_const_mem (enum machine_mode, rtx);
1180 static bool rs6000_legitimate_constant_p (enum machine_mode, rtx);
1181 static bool rs6000_save_toc_in_prologue_p (void);
1183 /* Hash table stuff for keeping track of TOC entries. */
1185 struct GTY(()) toc_hash_struct
1187 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1188 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1190 enum machine_mode key_mode;
1194 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
1196 /* Hash table to keep track of the argument types for builtin functions. */
1198 struct GTY(()) builtin_hash_struct
1201 enum machine_mode mode[4]; /* return value + 3 arguments. */
1202 unsigned char uns_p[4]; /* and whether the types are unsigned. */
1205 static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table;
1207 static bool rs6000_valid_attribute_p (tree, tree, tree, int);
1208 static void rs6000_function_specific_save (struct cl_target_option *);
1209 static void rs6000_function_specific_restore (struct cl_target_option *);
1210 static void rs6000_function_specific_print (FILE *, int,
1211 struct cl_target_option *);
1212 static bool rs6000_can_inline_p (tree, tree);
1213 static void rs6000_set_current_function (tree);
1216 /* Default register names. */
1217 char rs6000_reg_names[][8] =
1219 "0", "1", "2", "3", "4", "5", "6", "7",
1220 "8", "9", "10", "11", "12", "13", "14", "15",
1221 "16", "17", "18", "19", "20", "21", "22", "23",
1222 "24", "25", "26", "27", "28", "29", "30", "31",
1223 "0", "1", "2", "3", "4", "5", "6", "7",
1224 "8", "9", "10", "11", "12", "13", "14", "15",
1225 "16", "17", "18", "19", "20", "21", "22", "23",
1226 "24", "25", "26", "27", "28", "29", "30", "31",
1227 "mq", "lr", "ctr","ap",
1228 "0", "1", "2", "3", "4", "5", "6", "7",
1230 /* AltiVec registers. */
1231 "0", "1", "2", "3", "4", "5", "6", "7",
1232 "8", "9", "10", "11", "12", "13", "14", "15",
1233 "16", "17", "18", "19", "20", "21", "22", "23",
1234 "24", "25", "26", "27", "28", "29", "30", "31",
1236 /* SPE registers. */
1237 "spe_acc", "spefscr",
1238 /* Soft frame pointer. */
1242 #ifdef TARGET_REGNAMES
1243 static const char alt_reg_names[][8] =
1245 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1246 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1247 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1248 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1249 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1250 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1251 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1252 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1253 "mq", "lr", "ctr", "ap",
1254 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1256 /* AltiVec registers. */
1257 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1258 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1259 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1260 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1262 /* SPE registers. */
1263 "spe_acc", "spefscr",
1264 /* Soft frame pointer. */
1269 /* Table of valid machine attributes. */
1271 static const struct attribute_spec rs6000_attribute_table[] =
1273 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
1274 affects_type_identity } */
1275 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute,
1277 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute,
1279 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute,
1281 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute,
1283 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute,
1285 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1286 SUBTARGET_ATTRIBUTE_TABLE,
1288 { NULL, 0, 0, false, false, false, NULL, false }
1291 #ifndef MASK_STRICT_ALIGN
1292 #define MASK_STRICT_ALIGN 0
1294 #ifndef TARGET_PROFILE_KERNEL
1295 #define TARGET_PROFILE_KERNEL 0
1298 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1299 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1301 /* Initialize the GCC target structure. */
1302 #undef TARGET_ATTRIBUTE_TABLE
1303 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1304 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1305 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1306 #undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P
1307 #define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P rs6000_attribute_takes_identifier_p
1309 #undef TARGET_ASM_ALIGNED_DI_OP
1310 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1312 /* Default unaligned ops are only provided for ELF. Find the ops needed
1313 for non-ELF systems. */
1314 #ifndef OBJECT_FORMAT_ELF
1316 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1318 #undef TARGET_ASM_UNALIGNED_HI_OP
1319 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1320 #undef TARGET_ASM_UNALIGNED_SI_OP
1321 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1322 #undef TARGET_ASM_UNALIGNED_DI_OP
1323 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1326 #undef TARGET_ASM_UNALIGNED_HI_OP
1327 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1328 #undef TARGET_ASM_UNALIGNED_SI_OP
1329 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1330 #undef TARGET_ASM_UNALIGNED_DI_OP
1331 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1332 #undef TARGET_ASM_ALIGNED_DI_OP
1333 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1337 /* This hook deals with fixups for relocatable code and DI-mode objects
1339 #undef TARGET_ASM_INTEGER
1340 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1342 #if defined (HAVE_GAS_HIDDEN) && !defined (TARGET_MACHO)
1343 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1344 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1347 #undef TARGET_HAVE_TLS
1348 #define TARGET_HAVE_TLS HAVE_AS_TLS
1350 #undef TARGET_CANNOT_FORCE_CONST_MEM
1351 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_cannot_force_const_mem
1353 #undef TARGET_DELEGITIMIZE_ADDRESS
1354 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1356 #undef TARGET_ASM_FUNCTION_PROLOGUE
1357 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1358 #undef TARGET_ASM_FUNCTION_EPILOGUE
1359 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1361 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
1362 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA rs6000_output_addr_const_extra
1364 #undef TARGET_LEGITIMIZE_ADDRESS
1365 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1367 #undef TARGET_SCHED_VARIABLE_ISSUE
1368 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1370 #undef TARGET_SCHED_ISSUE_RATE
1371 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1372 #undef TARGET_SCHED_ADJUST_COST
1373 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1374 #undef TARGET_SCHED_ADJUST_PRIORITY
1375 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1376 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1377 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1378 #undef TARGET_SCHED_INIT
1379 #define TARGET_SCHED_INIT rs6000_sched_init
1380 #undef TARGET_SCHED_FINISH
1381 #define TARGET_SCHED_FINISH rs6000_sched_finish
1382 #undef TARGET_SCHED_REORDER
1383 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1384 #undef TARGET_SCHED_REORDER2
1385 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1387 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1388 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1390 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1391 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1393 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1394 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1395 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1396 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1397 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1398 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1399 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1400 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1402 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1403 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1404 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1405 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1406 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1407 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1408 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1409 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1410 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1411 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1412 #undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
1413 #define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT \
1414 rs6000_builtin_support_vector_misalignment
1415 #undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE
1416 #define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1417 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
1418 #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
1419 rs6000_builtin_vectorization_cost
1420 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
1421 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE \
1422 rs6000_preferred_simd_mode
1424 #undef TARGET_INIT_BUILTINS
1425 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1426 #undef TARGET_BUILTIN_DECL
1427 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1429 #undef TARGET_EXPAND_BUILTIN
1430 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1432 #undef TARGET_MANGLE_TYPE
1433 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1435 #undef TARGET_INIT_LIBFUNCS
1436 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1439 #undef TARGET_BINDS_LOCAL_P
1440 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1443 #undef TARGET_MS_BITFIELD_LAYOUT_P
1444 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1446 #undef TARGET_ASM_OUTPUT_MI_THUNK
1447 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1449 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1450 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1452 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1453 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1455 #undef TARGET_INVALID_WITHIN_DOLOOP
1456 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1458 #undef TARGET_REGISTER_MOVE_COST
1459 #define TARGET_REGISTER_MOVE_COST rs6000_register_move_cost
1460 #undef TARGET_MEMORY_MOVE_COST
1461 #define TARGET_MEMORY_MOVE_COST rs6000_memory_move_cost
1462 #undef TARGET_RTX_COSTS
1463 #define TARGET_RTX_COSTS rs6000_rtx_costs
1464 #undef TARGET_ADDRESS_COST
1465 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1467 #undef TARGET_DWARF_REGISTER_SPAN
1468 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1470 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1471 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1473 /* On rs6000, function arguments are promoted, as are function return
1475 #undef TARGET_PROMOTE_FUNCTION_MODE
1476 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1478 #undef TARGET_RETURN_IN_MEMORY
1479 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1481 #undef TARGET_SETUP_INCOMING_VARARGS
1482 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1484 /* Always strict argument naming on rs6000. */
1485 #undef TARGET_STRICT_ARGUMENT_NAMING
1486 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1487 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1488 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1489 #undef TARGET_SPLIT_COMPLEX_ARG
1490 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1491 #undef TARGET_MUST_PASS_IN_STACK
1492 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1493 #undef TARGET_PASS_BY_REFERENCE
1494 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1495 #undef TARGET_ARG_PARTIAL_BYTES
1496 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1497 #undef TARGET_FUNCTION_ARG_ADVANCE
1498 #define TARGET_FUNCTION_ARG_ADVANCE rs6000_function_arg_advance
1499 #undef TARGET_FUNCTION_ARG
1500 #define TARGET_FUNCTION_ARG rs6000_function_arg
1501 #undef TARGET_FUNCTION_ARG_BOUNDARY
1502 #define TARGET_FUNCTION_ARG_BOUNDARY rs6000_function_arg_boundary
1504 #undef TARGET_BUILD_BUILTIN_VA_LIST
1505 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1507 #undef TARGET_EXPAND_BUILTIN_VA_START
1508 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1510 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1511 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1513 #undef TARGET_EH_RETURN_FILTER_MODE
1514 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1516 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1517 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1519 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1520 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1522 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1523 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1525 #undef TARGET_ASM_LOOP_ALIGN_MAX_SKIP
1526 #define TARGET_ASM_LOOP_ALIGN_MAX_SKIP rs6000_loop_align_max_skip
1528 #undef TARGET_OPTION_OVERRIDE
1529 #define TARGET_OPTION_OVERRIDE rs6000_option_override
1531 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1532 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1533 rs6000_builtin_vectorized_function
1535 #ifndef TARGET_MACHO
1536 #undef TARGET_STACK_PROTECT_FAIL
1537 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1540 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1541 The PowerPC architecture requires only weak consistency among
1542 processors--that is, memory accesses between processors need not be
1543 sequentially consistent and memory accesses among processors can occur
1544 in any order. The ability to order memory accesses weakly provides
1545 opportunities for more efficient use of the system bus. Unless a
1546 dependency exists, the 604e allows read operations to precede store
1548 #undef TARGET_RELAXED_ORDERING
1549 #define TARGET_RELAXED_ORDERING true
1552 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1553 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1556 /* Use a 32-bit anchor range. This leads to sequences like:
1558 addis tmp,anchor,high
1561 where tmp itself acts as an anchor, and can be shared between
1562 accesses to the same 64k page. */
1563 #undef TARGET_MIN_ANCHOR_OFFSET
1564 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1565 #undef TARGET_MAX_ANCHOR_OFFSET
1566 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1567 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1568 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1570 #undef TARGET_BUILTIN_RECIPROCAL
1571 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1573 #undef TARGET_EXPAND_TO_RTL_HOOK
1574 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1576 #undef TARGET_INSTANTIATE_DECLS
1577 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1579 #undef TARGET_SECONDARY_RELOAD
1580 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1582 #undef TARGET_LEGITIMATE_ADDRESS_P
1583 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1585 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
1586 #define TARGET_MODE_DEPENDENT_ADDRESS_P rs6000_mode_dependent_address_p
1588 #undef TARGET_CAN_ELIMINATE
1589 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1591 #undef TARGET_CONDITIONAL_REGISTER_USAGE
1592 #define TARGET_CONDITIONAL_REGISTER_USAGE rs6000_conditional_register_usage
1594 #undef TARGET_TRAMPOLINE_INIT
1595 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1597 #undef TARGET_FUNCTION_VALUE
1598 #define TARGET_FUNCTION_VALUE rs6000_function_value
1600 #undef TARGET_OPTION_VALID_ATTRIBUTE_P
1601 #define TARGET_OPTION_VALID_ATTRIBUTE_P rs6000_valid_attribute_p
1603 #undef TARGET_OPTION_SAVE
1604 #define TARGET_OPTION_SAVE rs6000_function_specific_save
1606 #undef TARGET_OPTION_RESTORE
1607 #define TARGET_OPTION_RESTORE rs6000_function_specific_restore
1609 #undef TARGET_OPTION_PRINT
1610 #define TARGET_OPTION_PRINT rs6000_function_specific_print
1612 #undef TARGET_CAN_INLINE_P
1613 #define TARGET_CAN_INLINE_P rs6000_can_inline_p
1615 #undef TARGET_SET_CURRENT_FUNCTION
1616 #define TARGET_SET_CURRENT_FUNCTION rs6000_set_current_function
1618 #undef TARGET_LEGITIMATE_CONSTANT_P
1619 #define TARGET_LEGITIMATE_CONSTANT_P rs6000_legitimate_constant_p
1621 struct gcc_target targetm = TARGET_INITIALIZER;
1624 /* Simplifications for entries below. */
1627 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
1628 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
1631 /* Some OSs don't support saving the high part of 64-bit registers on context
1632 switch. Other OSs don't support saving Altivec registers. On those OSs, we
1633 don't touch the MASK_POWERPC64 or MASK_ALTIVEC settings; if the user wants
1634 either, the user must explicitly specify them and we won't interfere with
1635 the user's specification. */
1638 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
1639 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
1640 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
1641 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
1642 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
1643 | MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE
1644 | MASK_RECIP_PRECISION)
1647 /* Masks for instructions set at various powerpc ISAs. */
1649 ISA_2_1_MASKS = MASK_MFCRF,
1650 ISA_2_2_MASKS = (ISA_2_1_MASKS | MASK_POPCNTB),
1651 ISA_2_4_MASKS = (ISA_2_2_MASKS | MASK_FPRND),
1653 /* For ISA 2.05, do not add MFPGPR, since it isn't in ISA 2.06, and don't add
1654 ALTIVEC, since in general it isn't a win on power6. In ISA 2.04, fsel,
1655 fre, fsqrt, etc. were no longer documented as optional. Group masks by
1656 server and embedded. */
1657 ISA_2_5_MASKS_EMBEDDED = (ISA_2_2_MASKS | MASK_CMPB | MASK_RECIP_PRECISION
1658 | MASK_PPC_GFXOPT | MASK_PPC_GPOPT),
1659 ISA_2_5_MASKS_SERVER = (ISA_2_5_MASKS_EMBEDDED | MASK_DFP),
1661 /* For ISA 2.06, don't add ISEL, since in general it isn't a win, but
1662 altivec is a win so enable it. */
1663 ISA_2_6_MASKS_EMBEDDED = (ISA_2_5_MASKS_EMBEDDED | MASK_POPCNTD),
1664 ISA_2_6_MASKS_SERVER = (ISA_2_5_MASKS_SERVER | MASK_POPCNTD | MASK_ALTIVEC
1670 const char *const name; /* Canonical processor name. */
1671 const enum processor_type processor; /* Processor type enum value. */
1672 const int target_enable; /* Target flags to enable. */
1675 static struct rs6000_ptt const processor_target_table[] =
1677 #define RS6000_CPU(NAME, CPU, FLAGS) { NAME, CPU, FLAGS },
1678 #include "rs6000-cpus.def"
1682 /* Look up a processor name for -mcpu=xxx and -mtune=xxx. Return -1 if the
1686 rs6000_cpu_name_lookup (const char *name)
1692 for (i = 0; i < ARRAY_SIZE (processor_target_table); i++)
1693 if (! strcmp (name, processor_target_table[i].name))
1701 /* Return number of consecutive hard regs needed starting at reg REGNO
1702 to hold something of mode MODE.
1703 This is ordinarily the length in words of a value of mode MODE
1704 but can be less for certain modes in special long registers.
1706 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1707 scalar instructions. The upper 32 bits are only available to the
1710 POWER and PowerPC GPRs hold 32 bits worth;
1711 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1714 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1716 unsigned HOST_WIDE_INT reg_size;
1718 if (FP_REGNO_P (regno))
1719 reg_size = (VECTOR_MEM_VSX_P (mode)
1720 ? UNITS_PER_VSX_WORD
1721 : UNITS_PER_FP_WORD);
1723 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1724 reg_size = UNITS_PER_SPE_WORD;
1726 else if (ALTIVEC_REGNO_P (regno))
1727 reg_size = UNITS_PER_ALTIVEC_WORD;
1729 /* The value returned for SCmode in the E500 double case is 2 for
1730 ABI compatibility; storing an SCmode value in a single register
1731 would require function_arg and rs6000_spe_function_arg to handle
1732 SCmode so as to pass the value correctly in a pair of
1734 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1735 && !DECIMAL_FLOAT_MODE_P (mode))
1736 reg_size = UNITS_PER_FP_WORD;
1739 reg_size = UNITS_PER_WORD;
1741 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1744 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1747 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1749 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1751 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1752 implementations. Don't allow an item to be split between a FP register
1753 and an Altivec register. */
1754 if (VECTOR_MEM_VSX_P (mode))
1756 if (FP_REGNO_P (regno))
1757 return FP_REGNO_P (last_regno);
1759 if (ALTIVEC_REGNO_P (regno))
1760 return ALTIVEC_REGNO_P (last_regno);
1763 /* The GPRs can hold any mode, but values bigger than one register
1764 cannot go past R31. */
1765 if (INT_REGNO_P (regno))
1766 return INT_REGNO_P (last_regno);
1768 /* The float registers (except for VSX vector modes) can only hold floating
1769 modes and DImode. This excludes the 32-bit decimal float mode for
1771 if (FP_REGNO_P (regno))
1773 if (SCALAR_FLOAT_MODE_P (mode)
1774 && (mode != TDmode || (regno % 2) == 0)
1775 && FP_REGNO_P (last_regno))
1778 if (GET_MODE_CLASS (mode) == MODE_INT
1779 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1782 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1783 && PAIRED_VECTOR_MODE (mode))
1789 /* The CR register can only hold CC modes. */
1790 if (CR_REGNO_P (regno))
1791 return GET_MODE_CLASS (mode) == MODE_CC;
1793 if (CA_REGNO_P (regno))
1794 return mode == BImode;
1796 /* AltiVec only in AldyVec registers. */
1797 if (ALTIVEC_REGNO_P (regno))
1798 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1800 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1801 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1804 /* We cannot put TImode anywhere except general register and it must be able
1805 to fit within the register set. In the future, allow TImode in the
1806 Altivec or VSX registers. */
1808 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1811 /* Print interesting facts about registers. */
1813 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1817 for (r = first_regno; r <= last_regno; ++r)
1819 const char *comma = "";
1822 if (first_regno == last_regno)
1823 fprintf (stderr, "%s:\t", reg_name);
1825 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1828 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1829 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1833 fprintf (stderr, ",\n\t");
1838 if (rs6000_hard_regno_nregs[m][r] > 1)
1839 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
1840 rs6000_hard_regno_nregs[m][r]);
1842 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
1847 if (call_used_regs[r])
1851 fprintf (stderr, ",\n\t");
1856 len += fprintf (stderr, "%s%s", comma, "call-used");
1864 fprintf (stderr, ",\n\t");
1869 len += fprintf (stderr, "%s%s", comma, "fixed");
1875 fprintf (stderr, ",\n\t");
1879 fprintf (stderr, "%sregno = %d\n", comma, r);
1883 #define DEBUG_FMT_D "%-32s= %d\n"
1884 #define DEBUG_FMT_S "%-32s= %s\n"
1886 /* Print various interesting information with -mdebug=reg. */
1888 rs6000_debug_reg_global (void)
1890 static const char *const tf[2] = { "false", "true" };
1891 const char *nl = (const char *)0;
1893 char costly_num[20];
1895 const char *costly_str;
1896 const char *nop_str;
1897 const char *trace_str;
1898 const char *abi_str;
1899 const char *cmodel_str;
1901 /* Map enum rs6000_vector to string. */
1902 static const char *rs6000_debug_vector_unit[] = {
1911 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
1912 LAST_VIRTUAL_REGISTER);
1913 rs6000_debug_reg_print (0, 31, "gr");
1914 rs6000_debug_reg_print (32, 63, "fp");
1915 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
1918 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
1919 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
1920 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
1921 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
1922 rs6000_debug_reg_print (CA_REGNO, CA_REGNO, "ca");
1923 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
1924 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
1925 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
1926 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
1930 "d reg_class = %s\n"
1931 "f reg_class = %s\n"
1932 "v reg_class = %s\n"
1933 "wa reg_class = %s\n"
1934 "wd reg_class = %s\n"
1935 "wf reg_class = %s\n"
1936 "ws reg_class = %s\n\n",
1937 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
1938 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
1939 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
1940 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
1941 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
1942 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
1943 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
1945 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1946 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
1949 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
1951 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
1952 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
1958 if (rs6000_recip_control)
1960 fprintf (stderr, "\nReciprocal mask = 0x%x\n", rs6000_recip_control);
1962 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1963 if (rs6000_recip_bits[m])
1966 "Reciprocal estimate mode: %-5s divide: %s rsqrt: %s\n",
1968 (RS6000_RECIP_AUTO_RE_P (m)
1970 : (RS6000_RECIP_HAVE_RE_P (m) ? "have" : "none")),
1971 (RS6000_RECIP_AUTO_RSQRTE_P (m)
1973 : (RS6000_RECIP_HAVE_RSQRTE_P (m) ? "have" : "none")));
1976 fputs ("\n", stderr);
1979 if (rs6000_cpu_index >= 0)
1980 fprintf (stderr, DEBUG_FMT_S, "cpu",
1981 processor_target_table[rs6000_cpu_index].name);
1983 if (rs6000_tune_index >= 0)
1984 fprintf (stderr, DEBUG_FMT_S, "tune",
1985 processor_target_table[rs6000_tune_index].name);
1987 switch (rs6000_sched_costly_dep)
1989 case max_dep_latency:
1990 costly_str = "max_dep_latency";
1994 costly_str = "no_dep_costly";
1997 case all_deps_costly:
1998 costly_str = "all_deps_costly";
2001 case true_store_to_load_dep_costly:
2002 costly_str = "true_store_to_load_dep_costly";
2005 case store_to_load_dep_costly:
2006 costly_str = "store_to_load_dep_costly";
2010 costly_str = costly_num;
2011 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
2015 fprintf (stderr, DEBUG_FMT_S, "sched_costly_dep", costly_str);
2017 switch (rs6000_sched_insert_nops)
2019 case sched_finish_regroup_exact:
2020 nop_str = "sched_finish_regroup_exact";
2023 case sched_finish_pad_groups:
2024 nop_str = "sched_finish_pad_groups";
2027 case sched_finish_none:
2028 nop_str = "sched_finish_none";
2033 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
2037 fprintf (stderr, DEBUG_FMT_S, "sched_insert_nops", nop_str);
2039 switch (rs6000_sdata)
2046 fprintf (stderr, DEBUG_FMT_S, "sdata", "data");
2050 fprintf (stderr, DEBUG_FMT_S, "sdata", "sysv");
2054 fprintf (stderr, DEBUG_FMT_S, "sdata", "eabi");
2059 switch (rs6000_traceback)
2061 case traceback_default: trace_str = "default"; break;
2062 case traceback_none: trace_str = "none"; break;
2063 case traceback_part: trace_str = "part"; break;
2064 case traceback_full: trace_str = "full"; break;
2065 default: trace_str = "unknown"; break;
2068 fprintf (stderr, DEBUG_FMT_S, "traceback", trace_str);
2070 switch (rs6000_current_cmodel)
2072 case CMODEL_SMALL: cmodel_str = "small"; break;
2073 case CMODEL_MEDIUM: cmodel_str = "medium"; break;
2074 case CMODEL_LARGE: cmodel_str = "large"; break;
2075 default: cmodel_str = "unknown"; break;
2078 fprintf (stderr, DEBUG_FMT_S, "cmodel", cmodel_str);
2080 switch (rs6000_current_abi)
2082 case ABI_NONE: abi_str = "none"; break;
2083 case ABI_AIX: abi_str = "aix"; break;
2084 case ABI_V4: abi_str = "V4"; break;
2085 case ABI_DARWIN: abi_str = "darwin"; break;
2086 default: abi_str = "unknown"; break;
2089 fprintf (stderr, DEBUG_FMT_S, "abi", abi_str);
2091 if (rs6000_altivec_abi)
2092 fprintf (stderr, DEBUG_FMT_S, "altivec_abi", "true");
2095 fprintf (stderr, DEBUG_FMT_S, "spe_abi", "true");
2097 if (rs6000_darwin64_abi)
2098 fprintf (stderr, DEBUG_FMT_S, "darwin64_abi", "true");
2100 if (rs6000_float_gprs)
2101 fprintf (stderr, DEBUG_FMT_S, "float_gprs", "true");
2103 fprintf (stderr, DEBUG_FMT_S, "always_hint", tf[!!rs6000_always_hint]);
2104 fprintf (stderr, DEBUG_FMT_S, "align_branch",
2105 tf[!!rs6000_align_branch_targets]);
2106 fprintf (stderr, DEBUG_FMT_D, "tls_size", rs6000_tls_size);
2107 fprintf (stderr, DEBUG_FMT_D, "long_double_size",
2108 rs6000_long_double_type_size);
2109 fprintf (stderr, DEBUG_FMT_D, "sched_restricted_insns_priority",
2110 (int)rs6000_sched_restricted_insns_priority);
2113 /* Initialize the various global tables that are based on register size. */
2115 rs6000_init_hard_regno_mode_ok (bool global_init_p)
2121 /* Precalculate REGNO_REG_CLASS. */
2122 rs6000_regno_regclass[0] = GENERAL_REGS;
2123 for (r = 1; r < 32; ++r)
2124 rs6000_regno_regclass[r] = BASE_REGS;
2126 for (r = 32; r < 64; ++r)
2127 rs6000_regno_regclass[r] = FLOAT_REGS;
2129 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
2130 rs6000_regno_regclass[r] = NO_REGS;
2132 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
2133 rs6000_regno_regclass[r] = ALTIVEC_REGS;
2135 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
2136 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
2137 rs6000_regno_regclass[r] = CR_REGS;
2139 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
2140 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
2141 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
2142 rs6000_regno_regclass[CA_REGNO] = CA_REGS;
2143 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
2144 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
2145 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
2146 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
2147 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
2148 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
2150 /* Precalculate vector information, this must be set up before the
2151 rs6000_hard_regno_nregs_internal below. */
2152 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2154 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
2155 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
2156 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
2159 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
2160 rs6000_constraints[c] = NO_REGS;
2162 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
2163 believes it can use native alignment or still uses 128-bit alignment. */
2164 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
2175 /* V2DF mode, VSX only. */
2178 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
2179 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
2180 rs6000_vector_align[V2DFmode] = align64;
2183 /* V4SF mode, either VSX or Altivec. */
2186 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
2187 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
2188 rs6000_vector_align[V4SFmode] = align32;
2190 else if (TARGET_ALTIVEC)
2192 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
2193 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
2194 rs6000_vector_align[V4SFmode] = align32;
2197 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
2201 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
2202 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
2203 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
2204 rs6000_vector_align[V4SImode] = align32;
2205 rs6000_vector_align[V8HImode] = align32;
2206 rs6000_vector_align[V16QImode] = align32;
2210 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
2211 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
2212 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
2216 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
2217 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
2218 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
2222 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
2223 Altivec doesn't have 64-bit support. */
2226 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
2227 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
2228 rs6000_vector_align[V2DImode] = align64;
2231 /* DFmode, see if we want to use the VSX unit. */
2232 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
2234 rs6000_vector_unit[DFmode] = VECTOR_VSX;
2235 rs6000_vector_mem[DFmode]
2236 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
2237 rs6000_vector_align[DFmode] = align64;
2240 /* TODO add SPE and paired floating point vector support. */
2242 /* Register class constaints for the constraints that depend on compile
2244 if (TARGET_HARD_FLOAT && TARGET_FPRS)
2245 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
2247 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
2248 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
2252 /* At present, we just use VSX_REGS, but we have different constraints
2253 based on the use, in case we want to fine tune the default register
2254 class used. wa = any VSX register, wf = register class to use for
2255 V4SF, wd = register class to use for V2DF, and ws = register classs to
2256 use for DF scalars. */
2257 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
2258 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
2259 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
2260 rs6000_constraints[RS6000_CONSTRAINT_ws] = (TARGET_VSX_SCALAR_MEMORY
2266 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
2268 /* Set up the reload helper functions. */
2269 if (TARGET_VSX || TARGET_ALTIVEC)
2273 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
2274 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
2275 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
2276 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
2277 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
2278 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
2279 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
2280 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
2281 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
2282 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
2283 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
2284 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
2288 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
2289 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
2290 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
2291 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
2292 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
2293 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
2294 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
2295 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
2296 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
2297 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
2298 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
2299 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
2303 /* Precalculate HARD_REGNO_NREGS. */
2304 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2305 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2306 rs6000_hard_regno_nregs[m][r]
2307 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
2309 /* Precalculate HARD_REGNO_MODE_OK. */
2310 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2311 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2312 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
2313 rs6000_hard_regno_mode_ok_p[m][r] = true;
2315 /* Precalculate CLASS_MAX_NREGS sizes. */
2316 for (c = 0; c < LIM_REG_CLASSES; ++c)
2320 if (TARGET_VSX && VSX_REG_CLASS_P (c))
2321 reg_size = UNITS_PER_VSX_WORD;
2323 else if (c == ALTIVEC_REGS)
2324 reg_size = UNITS_PER_ALTIVEC_WORD;
2326 else if (c == FLOAT_REGS)
2327 reg_size = UNITS_PER_FP_WORD;
2330 reg_size = UNITS_PER_WORD;
2332 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2333 rs6000_class_max_nregs[m][c]
2334 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
2337 if (TARGET_E500_DOUBLE)
2338 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
2340 /* Calculate which modes to automatically generate code to use a the
2341 reciprocal divide and square root instructions. In the future, possibly
2342 automatically generate the instructions even if the user did not specify
2343 -mrecip. The older machines double precision reciprocal sqrt estimate is
2344 not accurate enough. */
2345 memset (rs6000_recip_bits, 0, sizeof (rs6000_recip_bits));
2347 rs6000_recip_bits[SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2349 rs6000_recip_bits[DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2350 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2351 rs6000_recip_bits[V4SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2352 if (VECTOR_UNIT_VSX_P (V2DFmode))
2353 rs6000_recip_bits[V2DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2355 if (TARGET_FRSQRTES)
2356 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2358 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2359 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2360 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2361 if (VECTOR_UNIT_VSX_P (V2DFmode))
2362 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2364 if (rs6000_recip_control)
2366 if (!flag_finite_math_only)
2367 warning (0, "-mrecip requires -ffinite-math or -ffast-math");
2368 if (flag_trapping_math)
2369 warning (0, "-mrecip requires -fno-trapping-math or -ffast-math");
2370 if (!flag_reciprocal_math)
2371 warning (0, "-mrecip requires -freciprocal-math or -ffast-math");
2372 if (flag_finite_math_only && !flag_trapping_math && flag_reciprocal_math)
2374 if (RS6000_RECIP_HAVE_RE_P (SFmode)
2375 && (rs6000_recip_control & RECIP_SF_DIV) != 0)
2376 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2378 if (RS6000_RECIP_HAVE_RE_P (DFmode)
2379 && (rs6000_recip_control & RECIP_DF_DIV) != 0)
2380 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2382 if (RS6000_RECIP_HAVE_RE_P (V4SFmode)
2383 && (rs6000_recip_control & RECIP_V4SF_DIV) != 0)
2384 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2386 if (RS6000_RECIP_HAVE_RE_P (V2DFmode)
2387 && (rs6000_recip_control & RECIP_V2DF_DIV) != 0)
2388 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2390 if (RS6000_RECIP_HAVE_RSQRTE_P (SFmode)
2391 && (rs6000_recip_control & RECIP_SF_RSQRT) != 0)
2392 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2394 if (RS6000_RECIP_HAVE_RSQRTE_P (DFmode)
2395 && (rs6000_recip_control & RECIP_DF_RSQRT) != 0)
2396 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2398 if (RS6000_RECIP_HAVE_RSQRTE_P (V4SFmode)
2399 && (rs6000_recip_control & RECIP_V4SF_RSQRT) != 0)
2400 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2402 if (RS6000_RECIP_HAVE_RSQRTE_P (V2DFmode)
2403 && (rs6000_recip_control & RECIP_V2DF_RSQRT) != 0)
2404 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2408 if (global_init_p || TARGET_DEBUG_TARGET)
2410 if (TARGET_DEBUG_REG)
2411 rs6000_debug_reg_global ();
2413 if (TARGET_DEBUG_COST || TARGET_DEBUG_REG)
2415 "SImode variable mult cost = %d\n"
2416 "SImode constant mult cost = %d\n"
2417 "SImode short constant mult cost = %d\n"
2418 "DImode multipliciation cost = %d\n"
2419 "SImode division cost = %d\n"
2420 "DImode division cost = %d\n"
2421 "Simple fp operation cost = %d\n"
2422 "DFmode multiplication cost = %d\n"
2423 "SFmode division cost = %d\n"
2424 "DFmode division cost = %d\n"
2425 "cache line size = %d\n"
2426 "l1 cache size = %d\n"
2427 "l2 cache size = %d\n"
2428 "simultaneous prefetches = %d\n"
2431 rs6000_cost->mulsi_const,
2432 rs6000_cost->mulsi_const9,
2440 rs6000_cost->cache_line_size,
2441 rs6000_cost->l1_cache_size,
2442 rs6000_cost->l2_cache_size,
2443 rs6000_cost->simultaneous_prefetches);
2448 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2451 darwin_rs6000_override_options (void)
2453 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2455 rs6000_altivec_abi = 1;
2456 TARGET_ALTIVEC_VRSAVE = 1;
2458 if (DEFAULT_ABI == ABI_DARWIN
2460 darwin_one_byte_bool = 1;
2462 if (TARGET_64BIT && ! TARGET_POWERPC64)
2464 target_flags |= MASK_POWERPC64;
2465 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2469 rs6000_default_long_calls = 1;
2470 target_flags |= MASK_SOFT_FLOAT;
2473 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2475 if (!flag_mkernel && !flag_apple_kext
2477 && ! (target_flags_explicit & MASK_ALTIVEC))
2478 target_flags |= MASK_ALTIVEC;
2480 /* Unless the user (not the configurer) has explicitly overridden
2481 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2482 G4 unless targetting the kernel. */
2485 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2486 && ! (target_flags_explicit & MASK_ALTIVEC)
2487 && ! global_options_set.x_rs6000_cpu_index)
2489 target_flags |= MASK_ALTIVEC;
2494 /* If not otherwise specified by a target, make 'long double' equivalent to
2497 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2498 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2501 /* Override command line options. Mostly we process the processor type and
2502 sometimes adjust other TARGET_ options. */
2505 rs6000_option_override_internal (bool global_init_p)
2508 const char *default_cpu = OPTION_TARGET_CPU_DEFAULT;
2512 struct cl_target_option *main_target_opt
2513 = ((global_init_p || target_option_default_node == NULL)
2514 ? NULL : TREE_TARGET_OPTION (target_option_default_node));
2516 /* On 64-bit Darwin, power alignment is ABI-incompatible with some C
2517 library functions, so warn about it. The flag may be useful for
2518 performance studies from time to time though, so don't disable it
2520 if (global_options_set.x_rs6000_alignment_flags
2521 && rs6000_alignment_flags == MASK_ALIGN_POWER
2522 && DEFAULT_ABI == ABI_DARWIN
2524 warning (0, "-malign-power is not supported for 64-bit Darwin;"
2525 " it is incompatible with the installed C and C++ libraries");
2527 if (global_options_set.x_rs6000_spe_abi
2530 error ("not configured for SPE ABI");
2532 /* Numerous experiment shows that IRA based loop pressure
2533 calculation works better for RTL loop invariant motion on targets
2534 with enough (>= 32) registers. It is an expensive optimization.
2535 So it is on only for peak performance. */
2536 if (optimize >= 3 && global_init_p)
2537 flag_ira_loop_pressure = 1;
2539 /* Set the pointer size. */
2542 rs6000_pmode = (int)DImode;
2543 rs6000_pointer_size = 64;
2547 rs6000_pmode = (int)SImode;
2548 rs6000_pointer_size = 32;
2551 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2552 #ifdef OS_MISSING_POWERPC64
2553 if (OS_MISSING_POWERPC64)
2554 set_masks &= ~MASK_POWERPC64;
2556 #ifdef OS_MISSING_ALTIVEC
2557 if (OS_MISSING_ALTIVEC)
2558 set_masks &= ~MASK_ALTIVEC;
2561 /* Don't override by the processor default if given explicitly. */
2562 set_masks &= ~target_flags_explicit;
2564 /* Identify the processor type. */
2567 if (TARGET_POWERPC64)
2568 default_cpu = "powerpc64";
2569 else if (TARGET_POWERPC)
2570 default_cpu = "powerpc";
2573 /* Process the -mcpu=<xxx> and -mtune=<xxx> argument. If the user changed
2574 the cpu in a target attribute or pragma, but did not specify a tuning
2575 option, use the cpu for the tuning option rather than the option specified
2576 with -mtune on the command line. */
2577 if (rs6000_cpu_index > 0)
2578 cpu_index = rs6000_cpu_index;
2579 else if (main_target_opt != NULL && main_target_opt->x_rs6000_cpu_index > 0)
2580 rs6000_cpu_index = cpu_index = main_target_opt->x_rs6000_cpu_index;
2582 rs6000_cpu_index = cpu_index = rs6000_cpu_name_lookup (default_cpu);
2584 if (rs6000_tune_index > 0)
2585 tune_index = rs6000_tune_index;
2587 rs6000_tune_index = tune_index = cpu_index;
2591 target_flags &= ~set_masks;
2592 target_flags |= (processor_target_table[cpu_index].target_enable
2596 rs6000_cpu = ((tune_index >= 0)
2597 ? processor_target_table[tune_index].processor
2599 ? PROCESSOR_DEFAULT64
2600 : PROCESSOR_DEFAULT));
2602 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2603 || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64)
2606 error ("AltiVec not supported in this target");
2608 error ("SPE not supported in this target");
2611 /* Disable Cell microcode if we are optimizing for the Cell
2612 and not optimizing for size. */
2613 if (rs6000_gen_cell_microcode == -1)
2614 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2617 /* If we are optimizing big endian systems for space and it's OK to
2618 use instructions that would be microcoded on the Cell, use the
2619 load/store multiple and string instructions. */
2620 if (BYTES_BIG_ENDIAN && optimize_size && rs6000_gen_cell_microcode)
2621 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2623 /* Don't allow -mmultiple or -mstring on little endian systems
2624 unless the cpu is a 750, because the hardware doesn't support the
2625 instructions used in little endian mode, and causes an alignment
2626 trap. The 750 does not cause an alignment trap (except when the
2627 target is unaligned). */
2629 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2631 if (TARGET_MULTIPLE)
2633 target_flags &= ~MASK_MULTIPLE;
2634 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2635 warning (0, "-mmultiple is not supported on little endian systems");
2640 target_flags &= ~MASK_STRING;
2641 if ((target_flags_explicit & MASK_STRING) != 0)
2642 warning (0, "-mstring is not supported on little endian systems");
2646 /* Add some warnings for VSX. */
2649 const char *msg = NULL;
2650 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2651 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2653 if (target_flags_explicit & MASK_VSX)
2654 msg = N_("-mvsx requires hardware floating point");
2656 target_flags &= ~ MASK_VSX;
2658 else if (TARGET_PAIRED_FLOAT)
2659 msg = N_("-mvsx and -mpaired are incompatible");
2660 /* The hardware will allow VSX and little endian, but until we make sure
2661 things like vector select, etc. work don't allow VSX on little endian
2662 systems at this point. */
2663 else if (!BYTES_BIG_ENDIAN)
2664 msg = N_("-mvsx used with little endian code");
2665 else if (TARGET_AVOID_XFORM > 0)
2666 msg = N_("-mvsx needs indexed addressing");
2667 else if (!TARGET_ALTIVEC && (target_flags_explicit & MASK_ALTIVEC))
2669 if (target_flags_explicit & MASK_VSX)
2670 msg = N_("-mvsx and -mno-altivec are incompatible");
2672 msg = N_("-mno-altivec disables vsx");
2678 target_flags &= ~ MASK_VSX;
2679 target_flags_explicit |= MASK_VSX;
2683 /* For the newer switches (vsx, dfp, etc.) set some of the older options,
2684 unless the user explicitly used the -mno-<option> to disable the code. */
2686 target_flags |= (ISA_2_6_MASKS_SERVER & ~target_flags_explicit);
2687 else if (TARGET_POPCNTD)
2688 target_flags |= (ISA_2_6_MASKS_EMBEDDED & ~target_flags_explicit);
2689 else if (TARGET_DFP)
2690 target_flags |= (ISA_2_5_MASKS_SERVER & ~target_flags_explicit);
2691 else if (TARGET_CMPB)
2692 target_flags |= (ISA_2_5_MASKS_EMBEDDED & ~target_flags_explicit);
2693 else if (TARGET_FPRND)
2694 target_flags |= (ISA_2_4_MASKS & ~target_flags_explicit);
2695 else if (TARGET_POPCNTB)
2696 target_flags |= (ISA_2_2_MASKS & ~target_flags_explicit);
2697 else if (TARGET_ALTIVEC)
2698 target_flags |= (MASK_PPC_GFXOPT & ~target_flags_explicit);
2700 /* E500mc does "better" if we inline more aggressively. Respect the
2701 user's opinion, though. */
2702 if (rs6000_block_move_inline_limit == 0
2703 && (rs6000_cpu == PROCESSOR_PPCE500MC
2704 || rs6000_cpu == PROCESSOR_PPCE500MC64))
2705 rs6000_block_move_inline_limit = 128;
2707 /* store_one_arg depends on expand_block_move to handle at least the
2708 size of reg_parm_stack_space. */
2709 if (rs6000_block_move_inline_limit < (TARGET_POWERPC64 ? 64 : 32))
2710 rs6000_block_move_inline_limit = (TARGET_POWERPC64 ? 64 : 32);
2714 /* If the appropriate debug option is enabled, replace the target hooks
2715 with debug versions that call the real version and then prints
2716 debugging information. */
2717 if (TARGET_DEBUG_COST)
2719 targetm.rtx_costs = rs6000_debug_rtx_costs;
2720 targetm.address_cost = rs6000_debug_address_cost;
2721 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2724 if (TARGET_DEBUG_ADDR)
2726 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2727 targetm.legitimize_address = rs6000_debug_legitimize_address;
2728 rs6000_secondary_reload_class_ptr
2729 = rs6000_debug_secondary_reload_class;
2730 rs6000_secondary_memory_needed_ptr
2731 = rs6000_debug_secondary_memory_needed;
2732 rs6000_cannot_change_mode_class_ptr
2733 = rs6000_debug_cannot_change_mode_class;
2734 rs6000_preferred_reload_class_ptr
2735 = rs6000_debug_preferred_reload_class;
2736 rs6000_legitimize_reload_address_ptr
2737 = rs6000_debug_legitimize_reload_address;
2738 rs6000_mode_dependent_address_ptr
2739 = rs6000_debug_mode_dependent_address;
2742 if (rs6000_veclibabi_name)
2744 if (strcmp (rs6000_veclibabi_name, "mass") == 0)
2745 rs6000_veclib_handler = rs6000_builtin_vectorized_libmass;
2748 error ("unknown vectorization library ABI type (%s) for "
2749 "-mveclibabi= switch", rs6000_veclibabi_name);
2755 if (!global_options_set.x_rs6000_long_double_type_size)
2757 if (main_target_opt != NULL
2758 && (main_target_opt->x_rs6000_long_double_type_size
2759 != RS6000_DEFAULT_LONG_DOUBLE_SIZE))
2760 error ("target attribute or pragma changes long double size");
2762 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2765 #ifndef POWERPC_LINUX
2766 if (!global_options_set.x_rs6000_ieeequad)
2767 rs6000_ieeequad = 1;
2770 /* Disable VSX and Altivec silently if the user switched cpus to power7 in a
2771 target attribute or pragma which automatically enables both options,
2772 unless the altivec ABI was set. This is set by default for 64-bit, but
2774 if (main_target_opt != NULL && !main_target_opt->x_rs6000_altivec_abi)
2775 target_flags &= ~((MASK_VSX | MASK_ALTIVEC) & ~target_flags_explicit);
2777 /* Enable Altivec ABI for AIX -maltivec. */
2778 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2780 if (main_target_opt != NULL && !main_target_opt->x_rs6000_altivec_abi)
2781 error ("target attribute or pragma changes AltiVec ABI");
2783 rs6000_altivec_abi = 1;
2786 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2787 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2788 be explicitly overridden in either case. */
2791 if (!global_options_set.x_rs6000_altivec_abi
2792 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2794 if (main_target_opt != NULL &&
2795 !main_target_opt->x_rs6000_altivec_abi)
2796 error ("target attribute or pragma changes AltiVec ABI");
2798 rs6000_altivec_abi = 1;
2801 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2802 if (!global_options_set.x_TARGET_ALTIVEC_VRSAVE)
2803 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2806 /* Set the Darwin64 ABI as default for 64-bit Darwin.
2807 So far, the only darwin64 targets are also MACH-O. */
2809 && DEFAULT_ABI == ABI_DARWIN
2812 if (main_target_opt != NULL && !main_target_opt->x_rs6000_darwin64_abi)
2813 error ("target attribute or pragma changes darwin64 ABI");
2816 rs6000_darwin64_abi = 1;
2817 /* Default to natural alignment, for better performance. */
2818 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2822 /* Place FP constants in the constant pool instead of TOC
2823 if section anchors enabled. */
2824 if (flag_section_anchors)
2825 TARGET_NO_FP_IN_TOC = 1;
2827 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2828 SUBTARGET_OVERRIDE_OPTIONS;
2830 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2831 SUBSUBTARGET_OVERRIDE_OPTIONS;
2833 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2834 SUB3TARGET_OVERRIDE_OPTIONS;
2837 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC
2838 || rs6000_cpu == PROCESSOR_PPCE500MC64)
2840 /* The e500 and e500mc do not have string instructions, and we set
2841 MASK_STRING above when optimizing for size. */
2842 if ((target_flags & MASK_STRING) != 0)
2843 target_flags = target_flags & ~MASK_STRING;
2845 else if (global_options_set.x_rs6000_cpu_index)
2847 /* For the powerpc-eabispe configuration, we set all these by
2848 default, so let's unset them if we manually set another
2849 CPU that is not the E500. */
2850 if (main_target_opt != NULL
2851 && ((main_target_opt->x_rs6000_spe_abi != rs6000_spe_abi)
2852 || (main_target_opt->x_rs6000_spe != rs6000_spe)
2853 || (main_target_opt->x_rs6000_float_gprs != rs6000_float_gprs)))
2854 error ("target attribute or pragma changes SPE ABI");
2857 if (!global_options_set.x_rs6000_spe_abi)
2859 if (!global_options_set.x_rs6000_spe)
2861 if (!global_options_set.x_rs6000_float_gprs)
2862 rs6000_float_gprs = 0;
2864 if (!(target_flags_explicit & MASK_ISEL))
2865 target_flags &= ~MASK_ISEL;
2868 /* Detect invalid option combinations with E500. */
2871 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
2872 && rs6000_cpu != PROCESSOR_POWER5
2873 && rs6000_cpu != PROCESSOR_POWER6
2874 && rs6000_cpu != PROCESSOR_POWER7
2875 && rs6000_cpu != PROCESSOR_PPCA2
2876 && rs6000_cpu != PROCESSOR_CELL);
2877 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
2878 || rs6000_cpu == PROCESSOR_POWER5
2879 || rs6000_cpu == PROCESSOR_POWER7);
2880 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
2881 || rs6000_cpu == PROCESSOR_POWER5
2882 || rs6000_cpu == PROCESSOR_POWER6
2883 || rs6000_cpu == PROCESSOR_POWER7
2884 || rs6000_cpu == PROCESSOR_PPCE500MC
2885 || rs6000_cpu == PROCESSOR_PPCE500MC64);
2887 /* Allow debug switches to override the above settings. These are set to -1
2888 in rs6000.opt to indicate the user hasn't directly set the switch. */
2889 if (TARGET_ALWAYS_HINT >= 0)
2890 rs6000_always_hint = TARGET_ALWAYS_HINT;
2892 if (TARGET_SCHED_GROUPS >= 0)
2893 rs6000_sched_groups = TARGET_SCHED_GROUPS;
2895 if (TARGET_ALIGN_BRANCH_TARGETS >= 0)
2896 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
2898 rs6000_sched_restricted_insns_priority
2899 = (rs6000_sched_groups ? 1 : 0);
2901 /* Handle -msched-costly-dep option. */
2902 rs6000_sched_costly_dep
2903 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
2905 if (rs6000_sched_costly_dep_str)
2907 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
2908 rs6000_sched_costly_dep = no_dep_costly;
2909 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
2910 rs6000_sched_costly_dep = all_deps_costly;
2911 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
2912 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
2913 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
2914 rs6000_sched_costly_dep = store_to_load_dep_costly;
2916 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
2917 atoi (rs6000_sched_costly_dep_str));
2920 /* Handle -minsert-sched-nops option. */
2921 rs6000_sched_insert_nops
2922 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
2924 if (rs6000_sched_insert_nops_str)
2926 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
2927 rs6000_sched_insert_nops = sched_finish_none;
2928 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
2929 rs6000_sched_insert_nops = sched_finish_pad_groups;
2930 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
2931 rs6000_sched_insert_nops = sched_finish_regroup_exact;
2933 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
2934 atoi (rs6000_sched_insert_nops_str));
2939 #ifdef TARGET_REGNAMES
2940 /* If the user desires alternate register names, copy in the
2941 alternate names now. */
2942 if (TARGET_REGNAMES)
2943 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
2946 /* Set aix_struct_return last, after the ABI is determined.
2947 If -maix-struct-return or -msvr4-struct-return was explicitly
2948 used, don't override with the ABI default. */
2949 if (!global_options_set.x_aix_struct_return)
2950 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
2953 /* IBM XL compiler defaults to unsigned bitfields. */
2954 if (TARGET_XL_COMPAT)
2955 flag_signed_bitfields = 0;
2958 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
2959 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
2962 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
2964 /* We can only guarantee the availability of DI pseudo-ops when
2965 assembling for 64-bit targets. */
2968 targetm.asm_out.aligned_op.di = NULL;
2969 targetm.asm_out.unaligned_op.di = NULL;
2973 /* Set branch target alignment, if not optimizing for size. */
2976 /* Cell wants to be aligned 8byte for dual issue. Titan wants to be
2977 aligned 8byte to avoid misprediction by the branch predictor. */
2978 if (rs6000_cpu == PROCESSOR_TITAN
2979 || rs6000_cpu == PROCESSOR_CELL)
2981 if (align_functions <= 0)
2982 align_functions = 8;
2983 if (align_jumps <= 0)
2985 if (align_loops <= 0)
2988 if (rs6000_align_branch_targets)
2990 if (align_functions <= 0)
2991 align_functions = 16;
2992 if (align_jumps <= 0)
2994 if (align_loops <= 0)
2996 can_override_loop_align = 1;
3000 if (align_jumps_max_skip <= 0)
3001 align_jumps_max_skip = 15;
3002 if (align_loops_max_skip <= 0)
3003 align_loops_max_skip = 15;
3006 /* Arrange to save and restore machine status around nested functions. */
3007 init_machine_status = rs6000_init_machine_status;
3009 /* We should always be splitting complex arguments, but we can't break
3010 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
3011 if (DEFAULT_ABI != ABI_AIX)
3012 targetm.calls.split_complex_arg = NULL;
3015 /* Initialize rs6000_cost with the appropriate target costs. */
3017 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
3021 case PROCESSOR_RIOS1:
3022 rs6000_cost = &rios1_cost;
3025 case PROCESSOR_RIOS2:
3026 rs6000_cost = &rios2_cost;
3029 case PROCESSOR_RS64A:
3030 rs6000_cost = &rs64a_cost;
3033 case PROCESSOR_MPCCORE:
3034 rs6000_cost = &mpccore_cost;
3037 case PROCESSOR_PPC403:
3038 rs6000_cost = &ppc403_cost;
3041 case PROCESSOR_PPC405:
3042 rs6000_cost = &ppc405_cost;
3045 case PROCESSOR_PPC440:
3046 rs6000_cost = &ppc440_cost;
3049 case PROCESSOR_PPC476:
3050 rs6000_cost = &ppc476_cost;
3053 case PROCESSOR_PPC601:
3054 rs6000_cost = &ppc601_cost;
3057 case PROCESSOR_PPC603:
3058 rs6000_cost = &ppc603_cost;
3061 case PROCESSOR_PPC604:
3062 rs6000_cost = &ppc604_cost;
3065 case PROCESSOR_PPC604e:
3066 rs6000_cost = &ppc604e_cost;
3069 case PROCESSOR_PPC620:
3070 rs6000_cost = &ppc620_cost;
3073 case PROCESSOR_PPC630:
3074 rs6000_cost = &ppc630_cost;
3077 case PROCESSOR_CELL:
3078 rs6000_cost = &ppccell_cost;
3081 case PROCESSOR_PPC750:
3082 case PROCESSOR_PPC7400:
3083 rs6000_cost = &ppc750_cost;
3086 case PROCESSOR_PPC7450:
3087 rs6000_cost = &ppc7450_cost;
3090 case PROCESSOR_PPC8540:
3091 rs6000_cost = &ppc8540_cost;
3094 case PROCESSOR_PPCE300C2:
3095 case PROCESSOR_PPCE300C3:
3096 rs6000_cost = &ppce300c2c3_cost;
3099 case PROCESSOR_PPCE500MC:
3100 rs6000_cost = &ppce500mc_cost;
3103 case PROCESSOR_PPCE500MC64:
3104 rs6000_cost = &ppce500mc64_cost;
3107 case PROCESSOR_TITAN:
3108 rs6000_cost = &titan_cost;
3111 case PROCESSOR_POWER4:
3112 case PROCESSOR_POWER5:
3113 rs6000_cost = &power4_cost;
3116 case PROCESSOR_POWER6:
3117 rs6000_cost = &power6_cost;
3120 case PROCESSOR_POWER7:
3121 rs6000_cost = &power7_cost;
3124 case PROCESSOR_PPCA2:
3125 rs6000_cost = &ppca2_cost;
3134 maybe_set_param_value (PARAM_SIMULTANEOUS_PREFETCHES,
3135 rs6000_cost->simultaneous_prefetches,
3136 global_options.x_param_values,
3137 global_options_set.x_param_values);
3138 maybe_set_param_value (PARAM_L1_CACHE_SIZE, rs6000_cost->l1_cache_size,
3139 global_options.x_param_values,
3140 global_options_set.x_param_values);
3141 maybe_set_param_value (PARAM_L1_CACHE_LINE_SIZE,
3142 rs6000_cost->cache_line_size,
3143 global_options.x_param_values,
3144 global_options_set.x_param_values);
3145 maybe_set_param_value (PARAM_L2_CACHE_SIZE, rs6000_cost->l2_cache_size,
3146 global_options.x_param_values,
3147 global_options_set.x_param_values);
3149 /* If using typedef char *va_list, signal that
3150 __builtin_va_start (&ap, 0) can be optimized to
3151 ap = __builtin_next_arg (0). */
3152 if (DEFAULT_ABI != ABI_V4)
3153 targetm.expand_builtin_va_start = NULL;
3156 /* Set up single/double float flags.
3157 If TARGET_HARD_FLOAT is set, but neither single or double is set,
3158 then set both flags. */
3159 if (TARGET_HARD_FLOAT && TARGET_FPRS
3160 && rs6000_single_float == 0 && rs6000_double_float == 0)
3161 rs6000_single_float = rs6000_double_float = 1;
3163 /* Reset single and double FP flags if target is E500. */
3166 rs6000_single_float = rs6000_double_float = 0;
3167 if (TARGET_E500_SINGLE)
3168 rs6000_single_float = 1;
3169 if (TARGET_E500_DOUBLE)
3170 rs6000_single_float = rs6000_double_float = 1;
3173 if (main_target_opt)
3175 if (main_target_opt->x_rs6000_single_float != rs6000_single_float)
3176 error ("target attribute or pragma changes single precision floating "
3178 if (main_target_opt->x_rs6000_double_float != rs6000_double_float)
3179 error ("target attribute or pragma changes double precision floating "
3183 /* If not explicitly specified via option, decide whether to generate indexed
3184 load/store instructions. */
3185 if (TARGET_AVOID_XFORM == -1)
3186 /* Avoid indexed addressing when targeting Power6 in order to avoid the
3187 DERAT mispredict penalty. However the LVE and STVE altivec instructions
3188 need indexed accesses and the type used is the scalar type of the element
3189 being loaded or stored. */
3190 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB
3191 && !TARGET_ALTIVEC);
3193 /* Set the -mrecip options. */
3194 if (rs6000_recip_name)
3196 char *p = ASTRDUP (rs6000_recip_name);
3198 unsigned int mask, i;
3201 while ((q = strtok (p, ",")) != NULL)
3212 if (!strcmp (q, "default"))
3213 mask = ((TARGET_RECIP_PRECISION)
3214 ? RECIP_HIGH_PRECISION : RECIP_LOW_PRECISION);
3217 for (i = 0; i < ARRAY_SIZE (recip_options); i++)
3218 if (!strcmp (q, recip_options[i].string))
3220 mask = recip_options[i].mask;
3224 if (i == ARRAY_SIZE (recip_options))
3226 error ("unknown option for -mrecip=%s", q);
3234 rs6000_recip_control &= ~mask;
3236 rs6000_recip_control |= mask;
3240 rs6000_init_hard_regno_mode_ok (global_init_p);
3242 /* Save the initial options in case the user does function specific options */
3244 target_option_default_node = target_option_current_node
3245 = build_target_option_node ();
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_vec_perm. */
3480 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
3482 tree inner_type = TREE_TYPE (type);
3483 bool uns_p = TYPE_UNSIGNED (inner_type);
3486 *mask_element_type = unsigned_char_type_node;
3488 switch (TYPE_MODE (type))
3492 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
3493 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
3498 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
3499 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
3504 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
3505 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
3509 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
3513 if (!TARGET_ALLOW_DF_PERMUTE)
3516 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
3520 if (!TARGET_ALLOW_DF_PERMUTE)
3524 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
3525 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
3537 /* Implement targetm.vectorize.builtin_vectorization_cost. */
3539 rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
3540 tree vectype, int misalign)
3544 switch (type_of_cost)
3554 case cond_branch_not_taken:
3558 case cond_branch_taken:
3561 case unaligned_load:
3562 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3564 elements = TYPE_VECTOR_SUBPARTS (vectype);
3566 /* Double word aligned. */
3574 /* Double word aligned. */
3578 /* Unknown misalignment. */
3591 /* Misaligned loads are not supported. */
3596 case unaligned_store:
3597 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3599 elements = TYPE_VECTOR_SUBPARTS (vectype);
3601 /* Double word aligned. */
3609 /* Double word aligned. */
3613 /* Unknown misalignment. */
3626 /* Misaligned stores are not supported. */
3636 /* Implement targetm.vectorize.preferred_simd_mode. */
3638 static enum machine_mode
3639 rs6000_preferred_simd_mode (enum machine_mode mode)
3648 if (TARGET_ALTIVEC || TARGET_VSX)
3672 if (TARGET_PAIRED_FLOAT
3678 /* Handler for the Mathematical Acceleration Subsystem (mass) interface to a
3679 library with vectorized intrinsics. */
3682 rs6000_builtin_vectorized_libmass (tree fndecl, tree type_out, tree type_in)
3685 const char *suffix = NULL;
3686 tree fntype, new_fndecl, bdecl = NULL_TREE;
3689 enum machine_mode el_mode, in_mode;
3692 /* Libmass is suitable for unsafe math only as it does not correctly support
3693 parts of IEEE with the required precision such as denormals. Only support
3694 it if we have VSX to use the simd d2 or f4 functions.
3695 XXX: Add variable length support. */
3696 if (!flag_unsafe_math_optimizations || !TARGET_VSX)
3699 el_mode = TYPE_MODE (TREE_TYPE (type_out));
3700 n = TYPE_VECTOR_SUBPARTS (type_out);
3701 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3702 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3703 if (el_mode != in_mode
3707 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3709 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3712 case BUILT_IN_ATAN2:
3713 case BUILT_IN_HYPOT:
3719 case BUILT_IN_ACOSH:
3721 case BUILT_IN_ASINH:
3723 case BUILT_IN_ATANH:
3731 case BUILT_IN_EXPM1:
3732 case BUILT_IN_LGAMMA:
3733 case BUILT_IN_LOG10:
3734 case BUILT_IN_LOG1P:
3742 bdecl = implicit_built_in_decls[fn];
3743 suffix = "d2"; /* pow -> powd2 */
3744 if (el_mode != DFmode
3749 case BUILT_IN_ATAN2F:
3750 case BUILT_IN_HYPOTF:
3755 case BUILT_IN_ACOSF:
3756 case BUILT_IN_ACOSHF:
3757 case BUILT_IN_ASINF:
3758 case BUILT_IN_ASINHF:
3759 case BUILT_IN_ATANF:
3760 case BUILT_IN_ATANHF:
3761 case BUILT_IN_CBRTF:
3763 case BUILT_IN_COSHF:
3765 case BUILT_IN_ERFCF:
3766 case BUILT_IN_EXP2F:
3768 case BUILT_IN_EXPM1F:
3769 case BUILT_IN_LGAMMAF:
3770 case BUILT_IN_LOG10F:
3771 case BUILT_IN_LOG1PF:
3772 case BUILT_IN_LOG2F:
3775 case BUILT_IN_SINHF:
3776 case BUILT_IN_SQRTF:
3778 case BUILT_IN_TANHF:
3779 bdecl = implicit_built_in_decls[fn];
3780 suffix = "4"; /* powf -> powf4 */
3781 if (el_mode != SFmode
3793 gcc_assert (suffix != NULL);
3794 bname = IDENTIFIER_POINTER (DECL_NAME (bdecl));
3795 strcpy (name, bname + sizeof ("__builtin_") - 1);
3796 strcat (name, suffix);
3799 fntype = build_function_type_list (type_out, type_in, NULL);
3800 else if (n_args == 2)
3801 fntype = build_function_type_list (type_out, type_in, type_in, NULL);
3805 /* Build a function declaration for the vectorized function. */
3806 new_fndecl = build_decl (BUILTINS_LOCATION,
3807 FUNCTION_DECL, get_identifier (name), fntype);
3808 TREE_PUBLIC (new_fndecl) = 1;
3809 DECL_EXTERNAL (new_fndecl) = 1;
3810 DECL_IS_NOVOPS (new_fndecl) = 1;
3811 TREE_READONLY (new_fndecl) = 1;
3816 /* Returns a function decl for a vectorized version of the builtin function
3817 with builtin function code FN and the result vector type TYPE, or NULL_TREE
3818 if it is not available. */
3821 rs6000_builtin_vectorized_function (tree fndecl, tree type_out,
3824 enum machine_mode in_mode, out_mode;
3827 if (TREE_CODE (type_out) != VECTOR_TYPE
3828 || TREE_CODE (type_in) != VECTOR_TYPE
3829 || !TARGET_VECTORIZE_BUILTINS)
3832 out_mode = TYPE_MODE (TREE_TYPE (type_out));
3833 out_n = TYPE_VECTOR_SUBPARTS (type_out);
3834 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3835 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3837 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3839 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3842 case BUILT_IN_COPYSIGN:
3843 if (VECTOR_UNIT_VSX_P (V2DFmode)
3844 && out_mode == DFmode && out_n == 2
3845 && in_mode == DFmode && in_n == 2)
3846 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
3848 case BUILT_IN_COPYSIGNF:
3849 if (out_mode != SFmode || out_n != 4
3850 || in_mode != SFmode || in_n != 4)
3852 if (VECTOR_UNIT_VSX_P (V4SFmode))
3853 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
3854 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3855 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
3858 if (VECTOR_UNIT_VSX_P (V2DFmode)
3859 && out_mode == DFmode && out_n == 2
3860 && in_mode == DFmode && in_n == 2)
3861 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
3863 case BUILT_IN_SQRTF:
3864 if (VECTOR_UNIT_VSX_P (V4SFmode)
3865 && out_mode == SFmode && out_n == 4
3866 && in_mode == SFmode && in_n == 4)
3867 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
3870 if (VECTOR_UNIT_VSX_P (V2DFmode)
3871 && out_mode == DFmode && out_n == 2
3872 && in_mode == DFmode && in_n == 2)
3873 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
3875 case BUILT_IN_CEILF:
3876 if (out_mode != SFmode || out_n != 4
3877 || in_mode != SFmode || in_n != 4)
3879 if (VECTOR_UNIT_VSX_P (V4SFmode))
3880 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
3881 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3882 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
3884 case BUILT_IN_FLOOR:
3885 if (VECTOR_UNIT_VSX_P (V2DFmode)
3886 && out_mode == DFmode && out_n == 2
3887 && in_mode == DFmode && in_n == 2)
3888 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
3890 case BUILT_IN_FLOORF:
3891 if (out_mode != SFmode || out_n != 4
3892 || in_mode != SFmode || in_n != 4)
3894 if (VECTOR_UNIT_VSX_P (V4SFmode))
3895 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
3896 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3897 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
3900 if (VECTOR_UNIT_VSX_P (V2DFmode)
3901 && out_mode == DFmode && out_n == 2
3902 && in_mode == DFmode && in_n == 2)
3903 return rs6000_builtin_decls[VSX_BUILTIN_XVMADDDP];
3906 if (VECTOR_UNIT_VSX_P (V4SFmode)
3907 && out_mode == SFmode && out_n == 4
3908 && in_mode == SFmode && in_n == 4)
3909 return rs6000_builtin_decls[VSX_BUILTIN_XVMADDSP];
3910 else if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)
3911 && out_mode == SFmode && out_n == 4
3912 && in_mode == SFmode && in_n == 4)
3913 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VMADDFP];
3915 case BUILT_IN_TRUNC:
3916 if (VECTOR_UNIT_VSX_P (V2DFmode)
3917 && out_mode == DFmode && out_n == 2
3918 && in_mode == DFmode && in_n == 2)
3919 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
3921 case BUILT_IN_TRUNCF:
3922 if (out_mode != SFmode || out_n != 4
3923 || in_mode != SFmode || in_n != 4)
3925 if (VECTOR_UNIT_VSX_P (V4SFmode))
3926 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
3927 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3928 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
3930 case BUILT_IN_NEARBYINT:
3931 if (VECTOR_UNIT_VSX_P (V2DFmode)
3932 && flag_unsafe_math_optimizations
3933 && out_mode == DFmode && out_n == 2
3934 && in_mode == DFmode && in_n == 2)
3935 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
3937 case BUILT_IN_NEARBYINTF:
3938 if (VECTOR_UNIT_VSX_P (V4SFmode)
3939 && flag_unsafe_math_optimizations
3940 && out_mode == SFmode && out_n == 4
3941 && in_mode == SFmode && in_n == 4)
3942 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
3945 if (VECTOR_UNIT_VSX_P (V2DFmode)
3946 && !flag_trapping_math
3947 && out_mode == DFmode && out_n == 2
3948 && in_mode == DFmode && in_n == 2)
3949 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
3951 case BUILT_IN_RINTF:
3952 if (VECTOR_UNIT_VSX_P (V4SFmode)
3953 && !flag_trapping_math
3954 && out_mode == SFmode && out_n == 4
3955 && in_mode == SFmode && in_n == 4)
3956 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
3963 else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
3965 enum rs6000_builtins fn
3966 = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl);
3969 case RS6000_BUILTIN_RSQRTF:
3970 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
3971 && out_mode == SFmode && out_n == 4
3972 && in_mode == SFmode && in_n == 4)
3973 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRSQRTFP];
3975 case RS6000_BUILTIN_RSQRT:
3976 if (VECTOR_UNIT_VSX_P (V2DFmode)
3977 && out_mode == DFmode && out_n == 2
3978 && in_mode == DFmode && in_n == 2)
3979 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
3981 case RS6000_BUILTIN_RECIPF:
3982 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
3983 && out_mode == SFmode && out_n == 4
3984 && in_mode == SFmode && in_n == 4)
3985 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRECIPFP];
3987 case RS6000_BUILTIN_RECIP:
3988 if (VECTOR_UNIT_VSX_P (V2DFmode)
3989 && out_mode == DFmode && out_n == 2
3990 && in_mode == DFmode && in_n == 2)
3991 return rs6000_builtin_decls[VSX_BUILTIN_RECIP_V2DF];
3998 /* Generate calls to libmass if appropriate. */
3999 if (rs6000_veclib_handler)
4000 return rs6000_veclib_handler (fndecl, type_out, type_in);
4005 /* Default CPU string for rs6000*_file_start functions. */
4006 static const char *rs6000_default_cpu;
4008 /* Do anything needed at the start of the asm file. */
4011 rs6000_file_start (void)
4014 const char *start = buffer;
4015 FILE *file = asm_out_file;
4017 rs6000_default_cpu = TARGET_CPU_DEFAULT;
4019 default_file_start ();
4021 #ifdef TARGET_BI_ARCH
4022 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
4023 rs6000_default_cpu = 0;
4026 if (flag_verbose_asm)
4028 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
4030 if (rs6000_default_cpu != 0 && rs6000_default_cpu[0] != '\0')
4032 fprintf (file, "%s --with-cpu=%s", start, rs6000_default_cpu);
4036 if (global_options_set.x_rs6000_cpu_index)
4038 fprintf (file, "%s -mcpu=%s", start,
4039 processor_target_table[rs6000_cpu_index].name);
4043 if (global_options_set.x_rs6000_tune_index)
4045 fprintf (file, "%s -mtune=%s", start,
4046 processor_target_table[rs6000_tune_index].name);
4050 if (PPC405_ERRATUM77)
4052 fprintf (file, "%s PPC405CR_ERRATUM77", start);
4056 #ifdef USING_ELFOS_H
4057 switch (rs6000_sdata)
4059 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
4060 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
4061 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
4062 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
4065 if (rs6000_sdata && g_switch_value)
4067 fprintf (file, "%s -G %d", start,
4077 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
4079 switch_to_section (toc_section);
4080 switch_to_section (text_section);
4085 /* Return nonzero if this function is known to have a null epilogue. */
4088 direct_return (void)
4090 if (reload_completed)
4092 rs6000_stack_t *info = rs6000_stack_info ();
4094 if (info->first_gp_reg_save == 32
4095 && info->first_fp_reg_save == 64
4096 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
4097 && ! info->lr_save_p
4098 && ! info->cr_save_p
4099 && info->vrsave_mask == 0
4107 /* Return the number of instructions it takes to form a constant in an
4108 integer register. */
4111 num_insns_constant_wide (HOST_WIDE_INT value)
4113 /* signed constant loadable with {cal|addi} */
4114 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
4117 /* constant loadable with {cau|addis} */
4118 else if ((value & 0xffff) == 0
4119 && (value >> 31 == -1 || value >> 31 == 0))
4122 #if HOST_BITS_PER_WIDE_INT == 64
4123 else if (TARGET_POWERPC64)
4125 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
4126 HOST_WIDE_INT high = value >> 31;
4128 if (high == 0 || high == -1)
4134 return num_insns_constant_wide (high) + 1;
4136 return num_insns_constant_wide (low) + 1;
4138 return (num_insns_constant_wide (high)
4139 + num_insns_constant_wide (low) + 1);
4148 num_insns_constant (rtx op, enum machine_mode mode)
4150 HOST_WIDE_INT low, high;
4152 switch (GET_CODE (op))
4155 #if HOST_BITS_PER_WIDE_INT == 64
4156 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
4157 && mask64_operand (op, mode))
4161 return num_insns_constant_wide (INTVAL (op));
4164 if (mode == SFmode || mode == SDmode)
4169 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4170 if (DECIMAL_FLOAT_MODE_P (mode))
4171 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
4173 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
4174 return num_insns_constant_wide ((HOST_WIDE_INT) l);
4177 if (mode == VOIDmode || mode == DImode)
4179 high = CONST_DOUBLE_HIGH (op);
4180 low = CONST_DOUBLE_LOW (op);
4187 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4188 if (DECIMAL_FLOAT_MODE_P (mode))
4189 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
4191 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
4192 high = l[WORDS_BIG_ENDIAN == 0];
4193 low = l[WORDS_BIG_ENDIAN != 0];
4197 return (num_insns_constant_wide (low)
4198 + num_insns_constant_wide (high));
4201 if ((high == 0 && low >= 0)
4202 || (high == -1 && low < 0))
4203 return num_insns_constant_wide (low);
4205 else if (mask64_operand (op, mode))
4209 return num_insns_constant_wide (high) + 1;
4212 return (num_insns_constant_wide (high)
4213 + num_insns_constant_wide (low) + 1);
4221 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
4222 If the mode of OP is MODE_VECTOR_INT, this simply returns the
4223 corresponding element of the vector, but for V4SFmode and V2SFmode,
4224 the corresponding "float" is interpreted as an SImode integer. */
4227 const_vector_elt_as_int (rtx op, unsigned int elt)
4231 /* We can't handle V2DImode and V2DFmode vector constants here yet. */
4232 gcc_assert (GET_MODE (op) != V2DImode
4233 && GET_MODE (op) != V2DFmode);
4235 tmp = CONST_VECTOR_ELT (op, elt);
4236 if (GET_MODE (op) == V4SFmode
4237 || GET_MODE (op) == V2SFmode)
4238 tmp = gen_lowpart (SImode, tmp);
4239 return INTVAL (tmp);
4242 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
4243 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
4244 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
4245 all items are set to the same value and contain COPIES replicas of the
4246 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
4247 operand and the others are set to the value of the operand's msb. */
4250 vspltis_constant (rtx op, unsigned step, unsigned copies)
4252 enum machine_mode mode = GET_MODE (op);
4253 enum machine_mode inner = GET_MODE_INNER (mode);
4261 HOST_WIDE_INT splat_val;
4262 HOST_WIDE_INT msb_val;
4264 if (mode == V2DImode || mode == V2DFmode)
4267 nunits = GET_MODE_NUNITS (mode);
4268 bitsize = GET_MODE_BITSIZE (inner);
4269 mask = GET_MODE_MASK (inner);
4271 val = const_vector_elt_as_int (op, nunits - 1);
4273 msb_val = val > 0 ? 0 : -1;
4275 /* Construct the value to be splatted, if possible. If not, return 0. */
4276 for (i = 2; i <= copies; i *= 2)
4278 HOST_WIDE_INT small_val;
4280 small_val = splat_val >> bitsize;
4282 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
4284 splat_val = small_val;
4287 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
4288 if (EASY_VECTOR_15 (splat_val))
4291 /* Also check if we can splat, and then add the result to itself. Do so if
4292 the value is positive, of if the splat instruction is using OP's mode;
4293 for splat_val < 0, the splat and the add should use the same mode. */
4294 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
4295 && (splat_val >= 0 || (step == 1 && copies == 1)))
4298 /* Also check if are loading up the most significant bit which can be done by
4299 loading up -1 and shifting the value left by -1. */
4300 else if (EASY_VECTOR_MSB (splat_val, inner))
4306 /* Check if VAL is present in every STEP-th element, and the
4307 other elements are filled with its most significant bit. */
4308 for (i = 0; i < nunits - 1; ++i)
4310 HOST_WIDE_INT desired_val;
4311 if (((i + 1) & (step - 1)) == 0)
4314 desired_val = msb_val;
4316 if (desired_val != const_vector_elt_as_int (op, i))
4324 /* Return true if OP is of the given MODE and can be synthesized
4325 with a vspltisb, vspltish or vspltisw. */
4328 easy_altivec_constant (rtx op, enum machine_mode mode)
4330 unsigned step, copies;
4332 if (mode == VOIDmode)
4333 mode = GET_MODE (op);
4334 else if (mode != GET_MODE (op))
4337 /* V2DI/V2DF was added with VSX. Only allow 0 and all 1's as easy
4339 if (mode == V2DFmode)
4340 return zero_constant (op, mode);
4342 if (mode == V2DImode)
4344 /* In case the compiler is built 32-bit, CONST_DOUBLE constants are not
4346 if (GET_CODE (CONST_VECTOR_ELT (op, 0)) != CONST_INT
4347 || GET_CODE (CONST_VECTOR_ELT (op, 1)) != CONST_INT)
4350 if (zero_constant (op, mode))
4353 if (INTVAL (CONST_VECTOR_ELT (op, 0)) == -1
4354 && INTVAL (CONST_VECTOR_ELT (op, 1)) == -1)
4360 /* Start with a vspltisw. */
4361 step = GET_MODE_NUNITS (mode) / 4;
4364 if (vspltis_constant (op, step, copies))
4367 /* Then try with a vspltish. */
4373 if (vspltis_constant (op, step, copies))
4376 /* And finally a vspltisb. */
4382 if (vspltis_constant (op, step, copies))
4388 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
4389 result is OP. Abort if it is not possible. */
4392 gen_easy_altivec_constant (rtx op)
4394 enum machine_mode mode = GET_MODE (op);
4395 int nunits = GET_MODE_NUNITS (mode);
4396 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
4397 unsigned step = nunits / 4;
4398 unsigned copies = 1;
4400 /* Start with a vspltisw. */
4401 if (vspltis_constant (op, step, copies))
4402 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
4404 /* Then try with a vspltish. */
4410 if (vspltis_constant (op, step, copies))
4411 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
4413 /* And finally a vspltisb. */
4419 if (vspltis_constant (op, step, copies))
4420 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
4426 output_vec_const_move (rtx *operands)
4429 enum machine_mode mode;
4434 mode = GET_MODE (dest);
4438 if (zero_constant (vec, mode))
4439 return "xxlxor %x0,%x0,%x0";
4441 if (mode == V2DImode
4442 && INTVAL (CONST_VECTOR_ELT (vec, 0)) == -1
4443 && INTVAL (CONST_VECTOR_ELT (vec, 1)) == -1)
4444 return "vspltisw %0,-1";
4450 if (zero_constant (vec, mode))
4451 return "vxor %0,%0,%0";
4453 splat_vec = gen_easy_altivec_constant (vec);
4454 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
4455 operands[1] = XEXP (splat_vec, 0);
4456 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
4459 switch (GET_MODE (splat_vec))
4462 return "vspltisw %0,%1";
4465 return "vspltish %0,%1";
4468 return "vspltisb %0,%1";
4475 gcc_assert (TARGET_SPE);
4477 /* Vector constant 0 is handled as a splitter of V2SI, and in the
4478 pattern of V1DI, V4HI, and V2SF.
4480 FIXME: We should probably return # and add post reload
4481 splitters for these, but this way is so easy ;-). */
4482 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
4483 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
4484 operands[1] = CONST_VECTOR_ELT (vec, 0);
4485 operands[2] = CONST_VECTOR_ELT (vec, 1);
4487 return "li %0,%1\n\tevmergelo %0,%0,%0";
4489 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
4492 /* Initialize TARGET of vector PAIRED to VALS. */
4495 paired_expand_vector_init (rtx target, rtx vals)
4497 enum machine_mode mode = GET_MODE (target);
4498 int n_elts = GET_MODE_NUNITS (mode);
4500 rtx x, new_rtx, tmp, constant_op, op1, op2;
4503 for (i = 0; i < n_elts; ++i)
4505 x = XVECEXP (vals, 0, i);
4506 if (!CONSTANT_P (x))
4511 /* Load from constant pool. */
4512 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
4518 /* The vector is initialized only with non-constants. */
4519 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
4520 XVECEXP (vals, 0, 1));
4522 emit_move_insn (target, new_rtx);
4526 /* One field is non-constant and the other one is a constant. Load the
4527 constant from the constant pool and use ps_merge instruction to
4528 construct the whole vector. */
4529 op1 = XVECEXP (vals, 0, 0);
4530 op2 = XVECEXP (vals, 0, 1);
4532 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
4534 tmp = gen_reg_rtx (GET_MODE (constant_op));
4535 emit_move_insn (tmp, constant_op);
4537 if (CONSTANT_P (op1))
4538 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
4540 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
4542 emit_move_insn (target, new_rtx);
4546 paired_expand_vector_move (rtx operands[])
4548 rtx op0 = operands[0], op1 = operands[1];
4550 emit_move_insn (op0, op1);
4553 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
4554 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
4555 operands for the relation operation COND. This is a recursive
4559 paired_emit_vector_compare (enum rtx_code rcode,
4560 rtx dest, rtx op0, rtx op1,
4561 rtx cc_op0, rtx cc_op1)
4563 rtx tmp = gen_reg_rtx (V2SFmode);
4566 gcc_assert (TARGET_PAIRED_FLOAT);
4567 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
4573 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4577 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4578 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
4582 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
4585 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4588 tmp1 = gen_reg_rtx (V2SFmode);
4589 max = gen_reg_rtx (V2SFmode);
4590 min = gen_reg_rtx (V2SFmode);
4591 gen_reg_rtx (V2SFmode);
4593 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4594 emit_insn (gen_selv2sf4
4595 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4596 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
4597 emit_insn (gen_selv2sf4
4598 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4599 emit_insn (gen_subv2sf3 (tmp1, min, max));
4600 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
4603 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
4606 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4609 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
4612 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4615 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
4624 /* Emit vector conditional expression.
4625 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
4626 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
4629 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
4630 rtx cond, rtx cc_op0, rtx cc_op1)
4632 enum rtx_code rcode = GET_CODE (cond);
4634 if (!TARGET_PAIRED_FLOAT)
4637 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
4642 /* Initialize vector TARGET to VALS. */
4645 rs6000_expand_vector_init (rtx target, rtx vals)
4647 enum machine_mode mode = GET_MODE (target);
4648 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4649 int n_elts = GET_MODE_NUNITS (mode);
4650 int n_var = 0, one_var = -1;
4651 bool all_same = true, all_const_zero = true;
4655 for (i = 0; i < n_elts; ++i)
4657 x = XVECEXP (vals, 0, i);
4658 if (!CONSTANT_P (x))
4659 ++n_var, one_var = i;
4660 else if (x != CONST0_RTX (inner_mode))
4661 all_const_zero = false;
4663 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
4669 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
4670 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
4671 if ((int_vector_p || TARGET_VSX) && all_const_zero)
4673 /* Zero register. */
4674 emit_insn (gen_rtx_SET (VOIDmode, target,
4675 gen_rtx_XOR (mode, target, target)));
4678 else if (int_vector_p && easy_vector_constant (const_vec, mode))
4680 /* Splat immediate. */
4681 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
4686 /* Load from constant pool. */
4687 emit_move_insn (target, const_vec);
4692 /* Double word values on VSX can use xxpermdi or lxvdsx. */
4693 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4697 rtx element = XVECEXP (vals, 0, 0);
4698 if (mode == V2DFmode)
4699 emit_insn (gen_vsx_splat_v2df (target, element));
4701 emit_insn (gen_vsx_splat_v2di (target, element));
4705 if (mode == V2DFmode)
4707 rtx op0 = copy_to_mode_reg (DFmode, XVECEXP (vals, 0, 0));
4708 rtx op1 = copy_to_mode_reg (DFmode, XVECEXP (vals, 0, 1));
4709 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
4713 rtx op0 = copy_to_mode_reg (DImode, XVECEXP (vals, 0, 0));
4714 rtx op1 = copy_to_mode_reg (DImode, XVECEXP (vals, 0, 1));
4715 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
4721 /* With single precision floating point on VSX, know that internally single
4722 precision is actually represented as a double, and either make 2 V2DF
4723 vectors, and convert these vectors to single precision, or do one
4724 conversion, and splat the result to the other elements. */
4725 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
4729 rtx freg = gen_reg_rtx (V4SFmode);
4730 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
4732 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
4733 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
4737 rtx dbl_even = gen_reg_rtx (V2DFmode);
4738 rtx dbl_odd = gen_reg_rtx (V2DFmode);
4739 rtx flt_even = gen_reg_rtx (V4SFmode);
4740 rtx flt_odd = gen_reg_rtx (V4SFmode);
4742 emit_insn (gen_vsx_concat_v2sf (dbl_even,
4743 copy_to_reg (XVECEXP (vals, 0, 0)),
4744 copy_to_reg (XVECEXP (vals, 0, 1))));
4745 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
4746 copy_to_reg (XVECEXP (vals, 0, 2)),
4747 copy_to_reg (XVECEXP (vals, 0, 3))));
4748 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
4749 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
4750 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
4755 /* Store value to stack temp. Load vector element. Splat. However, splat
4756 of 64-bit items is not supported on Altivec. */
4757 if (all_same && GET_MODE_SIZE (mode) <= 4)
4759 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4760 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
4761 XVECEXP (vals, 0, 0));
4762 x = gen_rtx_UNSPEC (VOIDmode,
4763 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4764 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4766 gen_rtx_SET (VOIDmode,
4769 x = gen_rtx_VEC_SELECT (inner_mode, target,
4770 gen_rtx_PARALLEL (VOIDmode,
4771 gen_rtvec (1, const0_rtx)));
4772 emit_insn (gen_rtx_SET (VOIDmode, target,
4773 gen_rtx_VEC_DUPLICATE (mode, x)));
4777 /* One field is non-constant. Load constant then overwrite
4781 rtx copy = copy_rtx (vals);
4783 /* Load constant part of vector, substitute neighboring value for
4785 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
4786 rs6000_expand_vector_init (target, copy);
4788 /* Insert variable. */
4789 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
4793 /* Construct the vector in memory one field at a time
4794 and load the whole vector. */
4795 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4796 for (i = 0; i < n_elts; i++)
4797 emit_move_insn (adjust_address_nv (mem, inner_mode,
4798 i * GET_MODE_SIZE (inner_mode)),
4799 XVECEXP (vals, 0, i));
4800 emit_move_insn (target, mem);
4803 /* Set field ELT of TARGET to VAL. */
4806 rs6000_expand_vector_set (rtx target, rtx val, int elt)
4808 enum machine_mode mode = GET_MODE (target);
4809 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4810 rtx reg = gen_reg_rtx (mode);
4812 int width = GET_MODE_SIZE (inner_mode);
4815 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4817 rtx (*set_func) (rtx, rtx, rtx, rtx)
4818 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
4819 emit_insn (set_func (target, target, val, GEN_INT (elt)));
4823 /* Load single variable value. */
4824 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4825 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
4826 x = gen_rtx_UNSPEC (VOIDmode,
4827 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4828 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4830 gen_rtx_SET (VOIDmode,
4834 /* Linear sequence. */
4835 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
4836 for (i = 0; i < 16; ++i)
4837 XVECEXP (mask, 0, i) = GEN_INT (i);
4839 /* Set permute mask to insert element into target. */
4840 for (i = 0; i < width; ++i)
4841 XVECEXP (mask, 0, elt*width + i)
4842 = GEN_INT (i + 0x10);
4843 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
4844 x = gen_rtx_UNSPEC (mode,
4845 gen_rtvec (3, target, reg,
4846 force_reg (V16QImode, x)),
4848 emit_insn (gen_rtx_SET (VOIDmode, target, x));
4851 /* Extract field ELT from VEC into TARGET. */
4854 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
4856 enum machine_mode mode = GET_MODE (vec);
4857 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4860 if (VECTOR_MEM_VSX_P (mode))
4867 emit_insn (gen_vsx_extract_v2df (target, vec, GEN_INT (elt)));
4870 emit_insn (gen_vsx_extract_v2di (target, vec, GEN_INT (elt)));
4873 emit_insn (gen_vsx_extract_v4sf (target, vec, GEN_INT (elt)));
4878 /* Allocate mode-sized buffer. */
4879 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4881 emit_move_insn (mem, vec);
4883 /* Add offset to field within buffer matching vector element. */
4884 mem = adjust_address_nv (mem, inner_mode, elt * GET_MODE_SIZE (inner_mode));
4886 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
4889 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
4890 implement ANDing by the mask IN. */
4892 build_mask64_2_operands (rtx in, rtx *out)
4894 #if HOST_BITS_PER_WIDE_INT >= 64
4895 unsigned HOST_WIDE_INT c, lsb, m1, m2;
4898 gcc_assert (GET_CODE (in) == CONST_INT);
4903 /* Assume c initially something like 0x00fff000000fffff. The idea
4904 is to rotate the word so that the middle ^^^^^^ group of zeros
4905 is at the MS end and can be cleared with an rldicl mask. We then
4906 rotate back and clear off the MS ^^ group of zeros with a
4908 c = ~c; /* c == 0xff000ffffff00000 */
4909 lsb = c & -c; /* lsb == 0x0000000000100000 */
4910 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
4911 c = ~c; /* c == 0x00fff000000fffff */
4912 c &= -lsb; /* c == 0x00fff00000000000 */
4913 lsb = c & -c; /* lsb == 0x0000100000000000 */
4914 c = ~c; /* c == 0xff000fffffffffff */
4915 c &= -lsb; /* c == 0xff00000000000000 */
4917 while ((lsb >>= 1) != 0)
4918 shift++; /* shift == 44 on exit from loop */
4919 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
4920 m1 = ~m1; /* m1 == 0x000000ffffffffff */
4921 m2 = ~c; /* m2 == 0x00ffffffffffffff */
4925 /* Assume c initially something like 0xff000f0000000000. The idea
4926 is to rotate the word so that the ^^^ middle group of zeros
4927 is at the LS end and can be cleared with an rldicr mask. We then
4928 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
4930 lsb = c & -c; /* lsb == 0x0000010000000000 */
4931 m2 = -lsb; /* m2 == 0xffffff0000000000 */
4932 c = ~c; /* c == 0x00fff0ffffffffff */
4933 c &= -lsb; /* c == 0x00fff00000000000 */
4934 lsb = c & -c; /* lsb == 0x0000100000000000 */
4935 c = ~c; /* c == 0xff000fffffffffff */
4936 c &= -lsb; /* c == 0xff00000000000000 */
4938 while ((lsb >>= 1) != 0)
4939 shift++; /* shift == 44 on exit from loop */
4940 m1 = ~c; /* m1 == 0x00ffffffffffffff */
4941 m1 >>= shift; /* m1 == 0x0000000000000fff */
4942 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
4945 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
4946 masks will be all 1's. We are guaranteed more than one transition. */
4947 out[0] = GEN_INT (64 - shift);
4948 out[1] = GEN_INT (m1);
4949 out[2] = GEN_INT (shift);
4950 out[3] = GEN_INT (m2);
4958 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
4961 invalid_e500_subreg (rtx op, enum machine_mode mode)
4963 if (TARGET_E500_DOUBLE)
4965 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
4966 subreg:TI and reg:TF. Decimal float modes are like integer
4967 modes (only low part of each register used) for this
4969 if (GET_CODE (op) == SUBREG
4970 && (mode == SImode || mode == DImode || mode == TImode
4971 || mode == DDmode || mode == TDmode)
4972 && REG_P (SUBREG_REG (op))
4973 && (GET_MODE (SUBREG_REG (op)) == DFmode
4974 || GET_MODE (SUBREG_REG (op)) == TFmode))
4977 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
4979 if (GET_CODE (op) == SUBREG
4980 && (mode == DFmode || mode == TFmode)
4981 && REG_P (SUBREG_REG (op))
4982 && (GET_MODE (SUBREG_REG (op)) == DImode
4983 || GET_MODE (SUBREG_REG (op)) == TImode
4984 || GET_MODE (SUBREG_REG (op)) == DDmode
4985 || GET_MODE (SUBREG_REG (op)) == TDmode))
4990 && GET_CODE (op) == SUBREG
4992 && REG_P (SUBREG_REG (op))
4993 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
4999 /* AIX increases natural record alignment to doubleword if the first
5000 field is an FP double while the FP fields remain word aligned. */
5003 rs6000_special_round_type_align (tree type, unsigned int computed,
5004 unsigned int specified)
5006 unsigned int align = MAX (computed, specified);
5007 tree field = TYPE_FIELDS (type);
5009 /* Skip all non field decls */
5010 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5011 field = DECL_CHAIN (field);
5013 if (field != NULL && field != type)
5015 type = TREE_TYPE (field);
5016 while (TREE_CODE (type) == ARRAY_TYPE)
5017 type = TREE_TYPE (type);
5019 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
5020 align = MAX (align, 64);
5026 /* Darwin increases record alignment to the natural alignment of
5030 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
5031 unsigned int specified)
5033 unsigned int align = MAX (computed, specified);
5035 if (TYPE_PACKED (type))
5038 /* Find the first field, looking down into aggregates. */
5040 tree field = TYPE_FIELDS (type);
5041 /* Skip all non field decls */
5042 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5043 field = DECL_CHAIN (field);
5046 /* A packed field does not contribute any extra alignment. */
5047 if (DECL_PACKED (field))
5049 type = TREE_TYPE (field);
5050 while (TREE_CODE (type) == ARRAY_TYPE)
5051 type = TREE_TYPE (type);
5052 } while (AGGREGATE_TYPE_P (type));
5054 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
5055 align = MAX (align, TYPE_ALIGN (type));
5060 /* Return 1 for an operand in small memory on V.4/eabi. */
5063 small_data_operand (rtx op ATTRIBUTE_UNUSED,
5064 enum machine_mode mode ATTRIBUTE_UNUSED)
5069 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
5072 if (DEFAULT_ABI != ABI_V4)
5075 /* Vector and float memory instructions have a limited offset on the
5076 SPE, so using a vector or float variable directly as an operand is
5079 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
5082 if (GET_CODE (op) == SYMBOL_REF)
5085 else if (GET_CODE (op) != CONST
5086 || GET_CODE (XEXP (op, 0)) != PLUS
5087 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
5088 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
5093 rtx sum = XEXP (op, 0);
5094 HOST_WIDE_INT summand;
5096 /* We have to be careful here, because it is the referenced address
5097 that must be 32k from _SDA_BASE_, not just the symbol. */
5098 summand = INTVAL (XEXP (sum, 1));
5099 if (summand < 0 || summand > g_switch_value)
5102 sym_ref = XEXP (sum, 0);
5105 return SYMBOL_REF_SMALL_P (sym_ref);
5111 /* Return true if either operand is a general purpose register. */
5114 gpr_or_gpr_p (rtx op0, rtx op1)
5116 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
5117 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
5121 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
5124 reg_offset_addressing_ok_p (enum machine_mode mode)
5134 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
5135 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
5143 /* Paired vector modes. Only reg+reg addressing is valid. */
5144 if (TARGET_PAIRED_FLOAT)
5156 virtual_stack_registers_memory_p (rtx op)
5160 if (GET_CODE (op) == REG)
5161 regnum = REGNO (op);
5163 else if (GET_CODE (op) == PLUS
5164 && GET_CODE (XEXP (op, 0)) == REG
5165 && GET_CODE (XEXP (op, 1)) == CONST_INT)
5166 regnum = REGNO (XEXP (op, 0));
5171 return (regnum >= FIRST_VIRTUAL_REGISTER
5172 && regnum <= LAST_VIRTUAL_POINTER_REGISTER);
5175 /* Return true if memory accesses to OP are known to never straddle
5179 offsettable_ok_by_alignment (rtx op, HOST_WIDE_INT offset,
5180 enum machine_mode mode)
5183 unsigned HOST_WIDE_INT dsize, dalign;
5185 if (GET_CODE (op) != SYMBOL_REF)
5188 decl = SYMBOL_REF_DECL (op);
5191 if (GET_MODE_SIZE (mode) == 0)
5194 /* -fsection-anchors loses the original SYMBOL_REF_DECL when
5195 replacing memory addresses with an anchor plus offset. We
5196 could find the decl by rummaging around in the block->objects
5197 VEC for the given offset but that seems like too much work. */
5199 if (SYMBOL_REF_HAS_BLOCK_INFO_P (op)
5200 && SYMBOL_REF_ANCHOR_P (op)
5201 && SYMBOL_REF_BLOCK (op) != NULL)
5203 struct object_block *block = SYMBOL_REF_BLOCK (op);
5204 HOST_WIDE_INT lsb, mask;
5206 /* Given the alignment of the block.. */
5207 dalign = block->alignment;
5208 mask = dalign / BITS_PER_UNIT - 1;
5210 /* ..and the combined offset of the anchor and any offset
5211 to this block object.. */
5212 offset += SYMBOL_REF_BLOCK_OFFSET (op);
5213 lsb = offset & -offset;
5215 /* ..find how many bits of the alignment we know for the
5220 return dalign >= GET_MODE_SIZE (mode);
5225 if (TREE_CODE (decl) == FUNCTION_DECL)
5228 if (!DECL_SIZE_UNIT (decl))
5231 if (!host_integerp (DECL_SIZE_UNIT (decl), 1))
5234 dsize = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
5238 dalign = DECL_ALIGN_UNIT (decl);
5239 return dalign >= dsize;
5242 type = TREE_TYPE (decl);
5244 if (TREE_CODE (decl) == STRING_CST)
5245 dsize = TREE_STRING_LENGTH (decl);
5246 else if (TYPE_SIZE_UNIT (type)
5247 && host_integerp (TYPE_SIZE_UNIT (type), 1))
5248 dsize = tree_low_cst (TYPE_SIZE_UNIT (type), 1);
5254 dalign = TYPE_ALIGN (type);
5255 if (CONSTANT_CLASS_P (decl))
5256 dalign = CONSTANT_ALIGNMENT (decl, dalign);
5258 dalign = DATA_ALIGNMENT (decl, dalign);
5259 dalign /= BITS_PER_UNIT;
5260 return dalign >= dsize;
5264 constant_pool_expr_p (rtx op)
5268 split_const (op, &base, &offset);
5269 return (GET_CODE (base) == SYMBOL_REF
5270 && CONSTANT_POOL_ADDRESS_P (base)
5271 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
5274 static rtx tocrel_base, tocrel_offset;
5277 toc_relative_expr_p (rtx op)
5279 if (GET_CODE (op) != CONST)
5282 split_const (op, &tocrel_base, &tocrel_offset);
5283 return (GET_CODE (tocrel_base) == UNSPEC
5284 && XINT (tocrel_base, 1) == UNSPEC_TOCREL);
5287 /* Return true if X is a constant pool address, and also for cmodel=medium
5288 if X is a toc-relative address known to be offsettable within MODE. */
5291 legitimate_constant_pool_address_p (const_rtx x, enum machine_mode mode,
5295 && (GET_CODE (x) == PLUS || GET_CODE (x) == LO_SUM)
5296 && GET_CODE (XEXP (x, 0)) == REG
5297 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5298 || ((TARGET_MINIMAL_TOC
5299 || TARGET_CMODEL != CMODEL_SMALL)
5300 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict)))
5301 && toc_relative_expr_p (XEXP (x, 1))
5302 && (TARGET_CMODEL != CMODEL_MEDIUM
5303 || constant_pool_expr_p (XVECEXP (tocrel_base, 0, 0))
5305 || offsettable_ok_by_alignment (XVECEXP (tocrel_base, 0, 0),
5306 INTVAL (tocrel_offset), mode)));
5310 legitimate_small_data_p (enum machine_mode mode, rtx x)
5312 return (DEFAULT_ABI == ABI_V4
5313 && !flag_pic && !TARGET_TOC
5314 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
5315 && small_data_operand (x, mode));
5318 /* SPE offset addressing is limited to 5-bits worth of double words. */
5319 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
5322 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
5324 unsigned HOST_WIDE_INT offset, extra;
5326 if (GET_CODE (x) != PLUS)
5328 if (GET_CODE (XEXP (x, 0)) != REG)
5330 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5332 if (!reg_offset_addressing_ok_p (mode))
5333 return virtual_stack_registers_memory_p (x);
5334 if (legitimate_constant_pool_address_p (x, mode, strict))
5336 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5339 offset = INTVAL (XEXP (x, 1));
5347 /* SPE vector modes. */
5348 return SPE_CONST_OFFSET_OK (offset);
5351 if (TARGET_E500_DOUBLE)
5352 return SPE_CONST_OFFSET_OK (offset);
5354 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
5356 if (VECTOR_MEM_VSX_P (DFmode))
5361 /* On e500v2, we may have:
5363 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
5365 Which gets addressed with evldd instructions. */
5366 if (TARGET_E500_DOUBLE)
5367 return SPE_CONST_OFFSET_OK (offset);
5369 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
5371 else if (offset & 3)
5376 if (TARGET_E500_DOUBLE)
5377 return (SPE_CONST_OFFSET_OK (offset)
5378 && SPE_CONST_OFFSET_OK (offset + 8));
5382 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
5384 else if (offset & 3)
5395 return (offset < 0x10000) && (offset + extra < 0x10000);
5399 legitimate_indexed_address_p (rtx x, int strict)
5403 if (GET_CODE (x) != PLUS)
5409 /* Recognize the rtl generated by reload which we know will later be
5410 replaced with proper base and index regs. */
5412 && reload_in_progress
5413 && (REG_P (op0) || GET_CODE (op0) == PLUS)
5417 return (REG_P (op0) && REG_P (op1)
5418 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
5419 && INT_REG_OK_FOR_INDEX_P (op1, strict))
5420 || (INT_REG_OK_FOR_BASE_P (op1, strict)
5421 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
5425 avoiding_indexed_address_p (enum machine_mode mode)
5427 /* Avoid indexed addressing for modes that have non-indexed
5428 load/store instruction forms. */
5429 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
5433 legitimate_indirect_address_p (rtx x, int strict)
5435 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
5439 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
5441 if (!TARGET_MACHO || !flag_pic
5442 || mode != SImode || GET_CODE (x) != MEM)
5446 if (GET_CODE (x) != LO_SUM)
5448 if (GET_CODE (XEXP (x, 0)) != REG)
5450 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
5454 return CONSTANT_P (x);
5458 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
5460 if (GET_CODE (x) != LO_SUM)
5462 if (GET_CODE (XEXP (x, 0)) != REG)
5464 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5466 /* Restrict addressing for DI because of our SUBREG hackery. */
5467 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5468 || mode == DDmode || mode == TDmode
5473 if (TARGET_ELF || TARGET_MACHO)
5475 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
5479 if (GET_MODE_NUNITS (mode) != 1)
5481 if (GET_MODE_BITSIZE (mode) > 64
5482 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
5483 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5484 && (mode == DFmode || mode == DDmode))))
5487 return CONSTANT_P (x);
5494 /* Try machine-dependent ways of modifying an illegitimate address
5495 to be legitimate. If we find one, return the new, valid address.
5496 This is used from only one place: `memory_address' in explow.c.
5498 OLDX is the address as it was before break_out_memory_refs was
5499 called. In some cases it is useful to look at this to decide what
5502 It is always safe for this function to do nothing. It exists to
5503 recognize opportunities to optimize the output.
5505 On RS/6000, first check for the sum of a register with a constant
5506 integer that is out of range. If so, generate code to add the
5507 constant with the low-order 16 bits masked to the register and force
5508 this result into another register (this can be done with `cau').
5509 Then generate an address of REG+(CONST&0xffff), allowing for the
5510 possibility of bit 16 being a one.
5512 Then check for the sum of a register and something not constant, try to
5513 load the other things into a register and return the sum. */
5516 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
5517 enum machine_mode mode)
5519 unsigned int extra = 0;
5521 if (!reg_offset_addressing_ok_p (mode))
5523 if (virtual_stack_registers_memory_p (x))
5526 /* In theory we should not be seeing addresses of the form reg+0,
5527 but just in case it is generated, optimize it away. */
5528 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
5529 return force_reg (Pmode, XEXP (x, 0));
5531 /* Make sure both operands are registers. */
5532 else if (GET_CODE (x) == PLUS)
5533 return gen_rtx_PLUS (Pmode,
5534 force_reg (Pmode, XEXP (x, 0)),
5535 force_reg (Pmode, XEXP (x, 1)));
5537 return force_reg (Pmode, x);
5539 if (GET_CODE (x) == SYMBOL_REF)
5541 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
5543 return rs6000_legitimize_tls_address (x, model);
5553 if (!TARGET_POWERPC64)
5561 extra = TARGET_POWERPC64 ? 8 : 12;
5567 if (GET_CODE (x) == PLUS
5568 && GET_CODE (XEXP (x, 0)) == REG
5569 && GET_CODE (XEXP (x, 1)) == CONST_INT
5570 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
5572 && !((TARGET_POWERPC64
5573 && (mode == DImode || mode == TImode)
5574 && (INTVAL (XEXP (x, 1)) & 3) != 0)
5575 || SPE_VECTOR_MODE (mode)
5576 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5577 || mode == DImode || mode == DDmode
5578 || mode == TDmode))))
5580 HOST_WIDE_INT high_int, low_int;
5582 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
5583 if (low_int >= 0x8000 - extra)
5585 high_int = INTVAL (XEXP (x, 1)) - low_int;
5586 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
5587 GEN_INT (high_int)), 0);
5588 return plus_constant (sum, low_int);
5590 else if (GET_CODE (x) == PLUS
5591 && GET_CODE (XEXP (x, 0)) == REG
5592 && GET_CODE (XEXP (x, 1)) != CONST_INT
5593 && GET_MODE_NUNITS (mode) == 1
5594 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5596 || ((mode != DImode && mode != DFmode && mode != DDmode)
5597 || (TARGET_E500_DOUBLE && mode != DDmode)))
5598 && (TARGET_POWERPC64 || mode != DImode)
5599 && !avoiding_indexed_address_p (mode)
5604 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
5605 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
5607 else if (SPE_VECTOR_MODE (mode)
5608 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5609 || mode == DDmode || mode == TDmode
5610 || mode == DImode)))
5614 /* We accept [reg + reg] and [reg + OFFSET]. */
5616 if (GET_CODE (x) == PLUS)
5618 rtx op1 = XEXP (x, 0);
5619 rtx op2 = XEXP (x, 1);
5622 op1 = force_reg (Pmode, op1);
5624 if (GET_CODE (op2) != REG
5625 && (GET_CODE (op2) != CONST_INT
5626 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
5627 || (GET_MODE_SIZE (mode) > 8
5628 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
5629 op2 = force_reg (Pmode, op2);
5631 /* We can't always do [reg + reg] for these, because [reg +
5632 reg + offset] is not a legitimate addressing mode. */
5633 y = gen_rtx_PLUS (Pmode, op1, op2);
5635 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
5636 return force_reg (Pmode, y);
5641 return force_reg (Pmode, x);
5647 && GET_CODE (x) != CONST_INT
5648 && GET_CODE (x) != CONST_DOUBLE
5650 && GET_MODE_NUNITS (mode) == 1
5651 && (GET_MODE_BITSIZE (mode) <= 32
5652 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5653 && (mode == DFmode || mode == DDmode))))
5655 rtx reg = gen_reg_rtx (Pmode);
5656 emit_insn (gen_elf_high (reg, x));
5657 return gen_rtx_LO_SUM (Pmode, reg, x);
5659 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
5662 && ! MACHO_DYNAMIC_NO_PIC_P
5664 && GET_CODE (x) != CONST_INT
5665 && GET_CODE (x) != CONST_DOUBLE
5667 && GET_MODE_NUNITS (mode) == 1
5668 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5669 || (mode != DFmode && mode != DDmode))
5673 rtx reg = gen_reg_rtx (Pmode);
5674 emit_insn (gen_macho_high (reg, x));
5675 return gen_rtx_LO_SUM (Pmode, reg, x);
5678 && GET_CODE (x) == SYMBOL_REF
5679 && constant_pool_expr_p (x)
5680 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
5682 rtx reg = TARGET_CMODEL != CMODEL_SMALL ? gen_reg_rtx (Pmode) : NULL_RTX;
5683 return create_TOC_reference (x, reg);
5689 /* Debug version of rs6000_legitimize_address. */
5691 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
5697 ret = rs6000_legitimize_address (x, oldx, mode);
5698 insns = get_insns ();
5704 "\nrs6000_legitimize_address: mode %s, old code %s, "
5705 "new code %s, modified\n",
5706 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
5707 GET_RTX_NAME (GET_CODE (ret)));
5709 fprintf (stderr, "Original address:\n");
5712 fprintf (stderr, "oldx:\n");
5715 fprintf (stderr, "New address:\n");
5720 fprintf (stderr, "Insns added:\n");
5721 debug_rtx_list (insns, 20);
5727 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
5728 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
5739 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
5740 We need to emit DTP-relative relocations. */
5743 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
5748 fputs ("\t.long\t", file);
5751 fputs (DOUBLE_INT_ASM_OP, file);
5756 output_addr_const (file, x);
5757 fputs ("@dtprel+0x8000", file);
5760 /* In the name of slightly smaller debug output, and to cater to
5761 general assembler lossage, recognize various UNSPEC sequences
5762 and turn them back into a direct symbol reference. */
5765 rs6000_delegitimize_address (rtx orig_x)
5769 orig_x = delegitimize_mem_from_attrs (orig_x);
5774 if (GET_CODE (x) == (TARGET_CMODEL != CMODEL_SMALL ? LO_SUM : PLUS)
5775 && GET_CODE (XEXP (x, 1)) == CONST)
5777 rtx offset = NULL_RTX;
5779 y = XEXP (XEXP (x, 1), 0);
5780 if (GET_CODE (y) == PLUS
5781 && GET_MODE (y) == Pmode
5782 && CONST_INT_P (XEXP (y, 1)))
5784 offset = XEXP (y, 1);
5787 if (GET_CODE (y) == UNSPEC
5788 && XINT (y, 1) == UNSPEC_TOCREL
5789 && ((GET_CODE (XEXP (x, 0)) == REG
5790 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5791 || TARGET_MINIMAL_TOC
5792 || TARGET_CMODEL != CMODEL_SMALL))
5793 || (TARGET_CMODEL != CMODEL_SMALL
5794 && GET_CODE (XEXP (x, 0)) == CONST
5795 && GET_CODE (XEXP (XEXP (x, 0), 0)) == PLUS
5796 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == REG
5797 && REGNO (XEXP (XEXP (XEXP (x, 0), 0), 0)) == TOC_REGISTER
5798 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == HIGH
5799 && rtx_equal_p (XEXP (x, 1),
5800 XEXP (XEXP (XEXP (XEXP (x, 0), 0), 1), 0)))))
5802 y = XVECEXP (y, 0, 0);
5803 if (offset != NULL_RTX)
5804 y = gen_rtx_PLUS (Pmode, y, offset);
5805 if (!MEM_P (orig_x))
5808 return replace_equiv_address_nv (orig_x, y);
5813 && GET_CODE (orig_x) == LO_SUM
5814 && GET_CODE (XEXP (orig_x, 1)) == CONST)
5816 y = XEXP (XEXP (orig_x, 1), 0);
5817 if (GET_CODE (y) == UNSPEC
5818 && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET)
5819 return XVECEXP (y, 0, 0);
5825 /* Construct the SYMBOL_REF for the tls_get_addr function. */
5827 static GTY(()) rtx rs6000_tls_symbol;
5829 rs6000_tls_get_addr (void)
5831 if (!rs6000_tls_symbol)
5832 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
5834 return rs6000_tls_symbol;
5837 /* Construct the SYMBOL_REF for TLS GOT references. */
5839 static GTY(()) rtx rs6000_got_symbol;
5841 rs6000_got_sym (void)
5843 if (!rs6000_got_symbol)
5845 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
5846 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
5847 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
5850 return rs6000_got_symbol;
5853 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
5854 this (thread-local) address. */
5857 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
5861 dest = gen_reg_rtx (Pmode);
5862 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
5868 tlsreg = gen_rtx_REG (Pmode, 13);
5869 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
5873 tlsreg = gen_rtx_REG (Pmode, 2);
5874 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
5878 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
5882 tmp = gen_reg_rtx (Pmode);
5885 tlsreg = gen_rtx_REG (Pmode, 13);
5886 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
5890 tlsreg = gen_rtx_REG (Pmode, 2);
5891 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
5895 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
5897 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
5902 rtx r3, got, tga, tmp1, tmp2, call_insn;
5904 /* We currently use relocations like @got@tlsgd for tls, which
5905 means the linker will handle allocation of tls entries, placing
5906 them in the .got section. So use a pointer to the .got section,
5907 not one to secondary TOC sections used by 64-bit -mminimal-toc,
5908 or to secondary GOT sections used by 32-bit -fPIC. */
5910 got = gen_rtx_REG (Pmode, 2);
5914 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
5917 rtx gsym = rs6000_got_sym ();
5918 got = gen_reg_rtx (Pmode);
5920 rs6000_emit_move (got, gsym, Pmode);
5925 tmp1 = gen_reg_rtx (Pmode);
5926 tmp2 = gen_reg_rtx (Pmode);
5927 mem = gen_const_mem (Pmode, tmp1);
5928 lab = gen_label_rtx ();
5929 emit_insn (gen_load_toc_v4_PIC_1b (gsym, lab));
5930 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
5931 emit_move_insn (tmp2, mem);
5932 last = emit_insn (gen_addsi3 (got, tmp1, tmp2));
5933 set_unique_reg_note (last, REG_EQUAL, gsym);
5938 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
5940 tga = rs6000_tls_get_addr ();
5941 emit_library_call_value (tga, dest, LCT_CONST, Pmode,
5942 1, const0_rtx, Pmode);
5944 r3 = gen_rtx_REG (Pmode, 3);
5945 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5946 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
5947 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5948 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
5949 else if (DEFAULT_ABI == ABI_V4)
5950 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
5953 call_insn = last_call_insn ();
5954 PATTERN (call_insn) = insn;
5955 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5956 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
5957 pic_offset_table_rtx);
5959 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
5961 tga = rs6000_tls_get_addr ();
5962 tmp1 = gen_reg_rtx (Pmode);
5963 emit_library_call_value (tga, tmp1, LCT_CONST, Pmode,
5964 1, const0_rtx, Pmode);
5966 r3 = gen_rtx_REG (Pmode, 3);
5967 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5968 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
5969 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5970 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
5971 else if (DEFAULT_ABI == ABI_V4)
5972 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
5975 call_insn = last_call_insn ();
5976 PATTERN (call_insn) = insn;
5977 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5978 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
5979 pic_offset_table_rtx);
5981 if (rs6000_tls_size == 16)
5984 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
5986 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
5988 else if (rs6000_tls_size == 32)
5990 tmp2 = gen_reg_rtx (Pmode);
5992 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
5994 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
5997 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
5999 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
6003 tmp2 = gen_reg_rtx (Pmode);
6005 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
6007 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
6009 insn = gen_rtx_SET (Pmode, dest,
6010 gen_rtx_PLUS (Pmode, tmp2, tmp1));
6016 /* IE, or 64-bit offset LE. */
6017 tmp2 = gen_reg_rtx (Pmode);
6019 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
6021 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
6024 insn = gen_tls_tls_64 (dest, tmp2, addr);
6026 insn = gen_tls_tls_32 (dest, tmp2, addr);
6034 /* Return 1 if X contains a thread-local symbol. */
6037 rs6000_tls_referenced_p (rtx x)
6039 if (! TARGET_HAVE_TLS)
6042 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
6045 /* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
6048 rs6000_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
6050 if (GET_CODE (x) == CONST
6051 && GET_CODE (XEXP (x, 0)) == PLUS
6052 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH)
6055 return rs6000_tls_referenced_p (x);
6058 /* Return 1 if *X is a thread-local symbol. This is the same as
6059 rs6000_tls_symbol_ref except for the type of the unused argument. */
6062 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
6064 return RS6000_SYMBOL_REF_TLS_P (*x);
6067 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
6068 replace the input X, or the original X if no replacement is called for.
6069 The output parameter *WIN is 1 if the calling macro should goto WIN,
6072 For RS/6000, we wish to handle large displacements off a base
6073 register by splitting the addend across an addiu/addis and the mem insn.
6074 This cuts number of extra insns needed from 3 to 1.
6076 On Darwin, we use this to generate code for floating point constants.
6077 A movsf_low is generated so we wind up with 2 instructions rather than 3.
6078 The Darwin code is inside #if TARGET_MACHO because only then are the
6079 machopic_* functions defined. */
6081 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
6082 int opnum, int type,
6083 int ind_levels ATTRIBUTE_UNUSED, int *win)
6085 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6087 /* Nasty hack for vsx_splat_V2DF/V2DI load from mem, which takes a
6088 DFmode/DImode MEM. */
6091 && ((mode == DFmode && recog_data.operand_mode[0] == V2DFmode)
6092 || (mode == DImode && recog_data.operand_mode[0] == V2DImode)))
6093 reg_offset_p = false;
6095 /* We must recognize output that we have already generated ourselves. */
6096 if (GET_CODE (x) == PLUS
6097 && GET_CODE (XEXP (x, 0)) == PLUS
6098 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6099 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6100 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6102 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6103 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6104 opnum, (enum reload_type)type);
6109 /* Likewise for (lo_sum (high ...) ...) output we have generated. */
6110 if (GET_CODE (x) == LO_SUM
6111 && GET_CODE (XEXP (x, 0)) == HIGH)
6113 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6114 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6115 opnum, (enum reload_type)type);
6121 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
6122 && GET_CODE (x) == LO_SUM
6123 && GET_CODE (XEXP (x, 0)) == PLUS
6124 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
6125 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6126 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
6127 && machopic_operand_p (XEXP (x, 1)))
6129 /* Result of previous invocation of this function on Darwin
6130 floating point constant. */
6131 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6132 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6133 opnum, (enum reload_type)type);
6139 if (TARGET_CMODEL != CMODEL_SMALL
6140 && GET_CODE (x) == LO_SUM
6141 && GET_CODE (XEXP (x, 0)) == PLUS
6142 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6143 && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER
6144 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST
6145 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 0)) == HIGH
6146 && GET_CODE (XEXP (x, 1)) == CONST
6147 && GET_CODE (XEXP (XEXP (x, 1), 0)) == UNSPEC
6148 && XINT (XEXP (XEXP (x, 1), 0), 1) == UNSPEC_TOCREL
6149 && rtx_equal_p (XEXP (XEXP (XEXP (XEXP (x, 0), 1), 0), 0), XEXP (x, 1)))
6151 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6152 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6153 opnum, (enum reload_type) type);
6158 /* Force ld/std non-word aligned offset into base register by wrapping
6160 if (GET_CODE (x) == PLUS
6161 && GET_CODE (XEXP (x, 0)) == REG
6162 && REGNO (XEXP (x, 0)) < 32
6163 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6164 && GET_CODE (XEXP (x, 1)) == CONST_INT
6166 && (INTVAL (XEXP (x, 1)) & 3) != 0
6167 && VECTOR_MEM_NONE_P (mode)
6168 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
6169 && TARGET_POWERPC64)
6171 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
6172 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6173 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6174 opnum, (enum reload_type) type);
6179 if (GET_CODE (x) == PLUS
6180 && GET_CODE (XEXP (x, 0)) == REG
6181 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
6182 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6183 && GET_CODE (XEXP (x, 1)) == CONST_INT
6185 && !SPE_VECTOR_MODE (mode)
6186 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6187 || mode == DDmode || mode == TDmode
6189 && VECTOR_MEM_NONE_P (mode))
6191 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
6192 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
6194 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
6196 /* Check for 32-bit overflow. */
6197 if (high + low != val)
6203 /* Reload the high part into a base reg; leave the low part
6204 in the mem directly. */
6206 x = gen_rtx_PLUS (GET_MODE (x),
6207 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
6211 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6212 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6213 opnum, (enum reload_type)type);
6218 if (GET_CODE (x) == SYMBOL_REF
6220 && VECTOR_MEM_NONE_P (mode)
6221 && !SPE_VECTOR_MODE (mode)
6223 && DEFAULT_ABI == ABI_DARWIN
6224 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
6226 && DEFAULT_ABI == ABI_V4
6229 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
6230 The same goes for DImode without 64-bit gprs and DFmode and DDmode
6234 && (mode != DImode || TARGET_POWERPC64)
6235 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
6236 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
6241 rtx offset = machopic_gen_offset (x);
6242 x = gen_rtx_LO_SUM (GET_MODE (x),
6243 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
6244 gen_rtx_HIGH (Pmode, offset)), offset);
6248 x = gen_rtx_LO_SUM (GET_MODE (x),
6249 gen_rtx_HIGH (Pmode, x), x);
6251 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6252 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6253 opnum, (enum reload_type)type);
6258 /* Reload an offset address wrapped by an AND that represents the
6259 masking of the lower bits. Strip the outer AND and let reload
6260 convert the offset address into an indirect address. For VSX,
6261 force reload to create the address with an AND in a separate
6262 register, because we can't guarantee an altivec register will
6264 if (VECTOR_MEM_ALTIVEC_P (mode)
6265 && GET_CODE (x) == AND
6266 && GET_CODE (XEXP (x, 0)) == PLUS
6267 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6268 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6269 && GET_CODE (XEXP (x, 1)) == CONST_INT
6270 && INTVAL (XEXP (x, 1)) == -16)
6279 && GET_CODE (x) == SYMBOL_REF
6280 && constant_pool_expr_p (x)
6281 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
6283 x = create_TOC_reference (x, NULL_RTX);
6284 if (TARGET_CMODEL != CMODEL_SMALL)
6285 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6286 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6287 opnum, (enum reload_type) type);
6295 /* Debug version of rs6000_legitimize_reload_address. */
6297 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
6298 int opnum, int type,
6299 int ind_levels, int *win)
6301 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
6304 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
6305 "type = %d, ind_levels = %d, win = %d, original addr:\n",
6306 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
6310 fprintf (stderr, "Same address returned\n");
6312 fprintf (stderr, "NULL returned\n");
6315 fprintf (stderr, "New address:\n");
6322 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
6323 that is a valid memory address for an instruction.
6324 The MODE argument is the machine mode for the MEM expression
6325 that wants to use this address.
6327 On the RS/6000, there are four valid address: a SYMBOL_REF that
6328 refers to a constant pool entry of an address (or the sum of it
6329 plus a constant), a short (16-bit signed) constant plus a register,
6330 the sum of two registers, or a register indirect, possibly with an
6331 auto-increment. For DFmode, DDmode and DImode with a constant plus
6332 register, we must ensure that both words are addressable or PowerPC64
6333 with offset word aligned.
6335 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
6336 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
6337 because adjacent memory cells are accessed by adding word-sized offsets
6338 during assembly output. */
6340 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
6342 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6344 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
6345 if (VECTOR_MEM_ALTIVEC_P (mode)
6346 && GET_CODE (x) == AND
6347 && GET_CODE (XEXP (x, 1)) == CONST_INT
6348 && INTVAL (XEXP (x, 1)) == -16)
6351 if (RS6000_SYMBOL_REF_TLS_P (x))
6353 if (legitimate_indirect_address_p (x, reg_ok_strict))
6355 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
6356 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6357 && !SPE_VECTOR_MODE (mode)
6360 /* Restrict addressing for DI because of our SUBREG hackery. */
6361 && !(TARGET_E500_DOUBLE
6362 && (mode == DFmode || mode == DDmode || mode == DImode))
6364 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
6366 if (virtual_stack_registers_memory_p (x))
6368 if (reg_offset_p && legitimate_small_data_p (mode, x))
6371 && legitimate_constant_pool_address_p (x, mode, reg_ok_strict))
6373 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
6376 && GET_CODE (x) == PLUS
6377 && GET_CODE (XEXP (x, 0)) == REG
6378 && (XEXP (x, 0) == virtual_stack_vars_rtx
6379 || XEXP (x, 0) == arg_pointer_rtx)
6380 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6382 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
6387 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6389 || (mode != DFmode && mode != DDmode)
6390 || (TARGET_E500_DOUBLE && mode != DDmode))
6391 && (TARGET_POWERPC64 || mode != DImode)
6392 && !avoiding_indexed_address_p (mode)
6393 && legitimate_indexed_address_p (x, reg_ok_strict))
6395 if (GET_CODE (x) == PRE_MODIFY
6399 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6401 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
6402 && (TARGET_POWERPC64 || mode != DImode)
6403 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6404 && !SPE_VECTOR_MODE (mode)
6405 /* Restrict addressing for DI because of our SUBREG hackery. */
6406 && !(TARGET_E500_DOUBLE
6407 && (mode == DFmode || mode == DDmode || mode == DImode))
6409 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
6410 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
6411 || (!avoiding_indexed_address_p (mode)
6412 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
6413 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
6415 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
6420 /* Debug version of rs6000_legitimate_address_p. */
6422 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
6425 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
6427 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
6428 "strict = %d, code = %s\n",
6429 ret ? "true" : "false",
6430 GET_MODE_NAME (mode),
6432 GET_RTX_NAME (GET_CODE (x)));
6438 /* Implement TARGET_MODE_DEPENDENT_ADDRESS_P. */
6441 rs6000_mode_dependent_address_p (const_rtx addr)
6443 return rs6000_mode_dependent_address_ptr (addr);
6446 /* Go to LABEL if ADDR (a legitimate address expression)
6447 has an effect that depends on the machine mode it is used for.
6449 On the RS/6000 this is true of all integral offsets (since AltiVec
6450 and VSX modes don't allow them) or is a pre-increment or decrement.
6452 ??? Except that due to conceptual problems in offsettable_address_p
6453 we can't really report the problems of integral offsets. So leave
6454 this assuming that the adjustable offset must be valid for the
6455 sub-words of a TFmode operand, which is what we had before. */
6458 rs6000_mode_dependent_address (const_rtx addr)
6460 switch (GET_CODE (addr))
6463 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
6464 is considered a legitimate address before reload, so there
6465 are no offset restrictions in that case. Note that this
6466 condition is safe in strict mode because any address involving
6467 virtual_stack_vars_rtx or arg_pointer_rtx would already have
6468 been rejected as illegitimate. */
6469 if (XEXP (addr, 0) != virtual_stack_vars_rtx
6470 && XEXP (addr, 0) != arg_pointer_rtx
6471 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
6473 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
6474 return val + 12 + 0x8000 >= 0x10000;
6479 /* Anything in the constant pool is sufficiently aligned that
6480 all bytes have the same high part address. */
6481 return !legitimate_constant_pool_address_p (addr, QImode, false);
6483 /* Auto-increment cases are now treated generically in recog.c. */
6485 return TARGET_UPDATE;
6487 /* AND is only allowed in Altivec loads. */
6498 /* Debug version of rs6000_mode_dependent_address. */
6500 rs6000_debug_mode_dependent_address (const_rtx addr)
6502 bool ret = rs6000_mode_dependent_address (addr);
6504 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
6505 ret ? "true" : "false");
6511 /* Implement FIND_BASE_TERM. */
6514 rs6000_find_base_term (rtx op)
6518 split_const (op, &base, &offset);
6519 if (GET_CODE (base) == UNSPEC)
6520 switch (XINT (base, 1))
6523 case UNSPEC_MACHOPIC_OFFSET:
6524 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
6525 for aliasing purposes. */
6526 return XVECEXP (base, 0, 0);
6532 /* More elaborate version of recog's offsettable_memref_p predicate
6533 that works around the ??? note of rs6000_mode_dependent_address.
6534 In particular it accepts
6536 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
6538 in 32-bit mode, that the recog predicate rejects. */
6541 rs6000_offsettable_memref_p (rtx op)
6546 /* First mimic offsettable_memref_p. */
6547 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
6550 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
6551 the latter predicate knows nothing about the mode of the memory
6552 reference and, therefore, assumes that it is the largest supported
6553 mode (TFmode). As a consequence, legitimate offsettable memory
6554 references are rejected. rs6000_legitimate_offset_address_p contains
6555 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
6556 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
6559 /* Change register usage conditional on target flags. */
6561 rs6000_conditional_register_usage (void)
6565 if (TARGET_DEBUG_TARGET)
6566 fprintf (stderr, "rs6000_conditional_register_usage called\n");
6568 /* Set MQ register fixed (already call_used) if not POWER
6569 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
6574 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
6576 fixed_regs[13] = call_used_regs[13]
6577 = call_really_used_regs[13] = 1;
6579 /* Conditionally disable FPRs. */
6580 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6581 for (i = 32; i < 64; i++)
6582 fixed_regs[i] = call_used_regs[i]
6583 = call_really_used_regs[i] = 1;
6585 /* The TOC register is not killed across calls in a way that is
6586 visible to the compiler. */
6587 if (DEFAULT_ABI == ABI_AIX)
6588 call_really_used_regs[2] = 0;
6590 if (DEFAULT_ABI == ABI_V4
6591 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6593 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6595 if (DEFAULT_ABI == ABI_V4
6596 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6598 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6599 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6600 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6602 if (DEFAULT_ABI == ABI_DARWIN
6603 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
6604 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6605 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6606 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6608 if (TARGET_TOC && TARGET_MINIMAL_TOC)
6609 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6610 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6614 global_regs[SPEFSCR_REGNO] = 1;
6615 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
6616 registers in prologues and epilogues. We no longer use r14
6617 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
6618 pool for link-compatibility with older versions of GCC. Once
6619 "old" code has died out, we can return r14 to the allocation
6622 = call_used_regs[14]
6623 = call_really_used_regs[14] = 1;
6626 if (!TARGET_ALTIVEC && !TARGET_VSX)
6628 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
6629 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6630 call_really_used_regs[VRSAVE_REGNO] = 1;
6633 if (TARGET_ALTIVEC || TARGET_VSX)
6634 global_regs[VSCR_REGNO] = 1;
6636 if (TARGET_ALTIVEC_ABI)
6638 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
6639 call_used_regs[i] = call_really_used_regs[i] = 1;
6641 /* AIX reserves VR20:31 in non-extended ABI mode. */
6643 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
6644 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6648 /* Try to output insns to set TARGET equal to the constant C if it can
6649 be done in less than N insns. Do all computations in MODE.
6650 Returns the place where the output has been placed if it can be
6651 done and the insns have been emitted. If it would take more than N
6652 insns, zero is returned and no insns and emitted. */
6655 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
6656 rtx source, int n ATTRIBUTE_UNUSED)
6658 rtx result, insn, set;
6659 HOST_WIDE_INT c0, c1;
6666 dest = gen_reg_rtx (mode);
6667 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
6671 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
6673 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
6674 GEN_INT (INTVAL (source)
6675 & (~ (HOST_WIDE_INT) 0xffff))));
6676 emit_insn (gen_rtx_SET (VOIDmode, dest,
6677 gen_rtx_IOR (SImode, copy_rtx (result),
6678 GEN_INT (INTVAL (source) & 0xffff))));
6683 switch (GET_CODE (source))
6686 c0 = INTVAL (source);
6691 #if HOST_BITS_PER_WIDE_INT >= 64
6692 c0 = CONST_DOUBLE_LOW (source);
6695 c0 = CONST_DOUBLE_LOW (source);
6696 c1 = CONST_DOUBLE_HIGH (source);
6704 result = rs6000_emit_set_long_const (dest, c0, c1);
6711 insn = get_last_insn ();
6712 set = single_set (insn);
6713 if (! CONSTANT_P (SET_SRC (set)))
6714 set_unique_reg_note (insn, REG_EQUAL, source);
6719 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
6720 fall back to a straight forward decomposition. We do this to avoid
6721 exponential run times encountered when looking for longer sequences
6722 with rs6000_emit_set_const. */
6724 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
6726 if (!TARGET_POWERPC64)
6728 rtx operand1, operand2;
6730 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
6732 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
6734 emit_move_insn (operand1, GEN_INT (c1));
6735 emit_move_insn (operand2, GEN_INT (c2));
6739 HOST_WIDE_INT ud1, ud2, ud3, ud4;
6742 ud2 = (c1 & 0xffff0000) >> 16;
6743 #if HOST_BITS_PER_WIDE_INT >= 64
6747 ud4 = (c2 & 0xffff0000) >> 16;
6749 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
6750 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
6753 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
6755 emit_move_insn (dest, GEN_INT (ud1));
6758 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
6759 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
6762 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6765 emit_move_insn (dest, GEN_INT (ud2 << 16));
6767 emit_move_insn (copy_rtx (dest),
6768 gen_rtx_IOR (DImode, copy_rtx (dest),
6771 else if (ud3 == 0 && ud4 == 0)
6773 gcc_assert (ud2 & 0x8000);
6774 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6777 emit_move_insn (copy_rtx (dest),
6778 gen_rtx_IOR (DImode, copy_rtx (dest),
6780 emit_move_insn (copy_rtx (dest),
6781 gen_rtx_ZERO_EXTEND (DImode,
6782 gen_lowpart (SImode,
6785 else if ((ud4 == 0xffff && (ud3 & 0x8000))
6786 || (ud4 == 0 && ! (ud3 & 0x8000)))
6789 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
6792 emit_move_insn (dest, GEN_INT (ud3 << 16));
6795 emit_move_insn (copy_rtx (dest),
6796 gen_rtx_IOR (DImode, copy_rtx (dest),
6798 emit_move_insn (copy_rtx (dest),
6799 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6802 emit_move_insn (copy_rtx (dest),
6803 gen_rtx_IOR (DImode, copy_rtx (dest),
6809 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
6812 emit_move_insn (dest, GEN_INT (ud4 << 16));
6815 emit_move_insn (copy_rtx (dest),
6816 gen_rtx_IOR (DImode, copy_rtx (dest),
6819 emit_move_insn (copy_rtx (dest),
6820 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6823 emit_move_insn (copy_rtx (dest),
6824 gen_rtx_IOR (DImode, copy_rtx (dest),
6825 GEN_INT (ud2 << 16)));
6827 emit_move_insn (copy_rtx (dest),
6828 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
6834 /* Helper for the following. Get rid of [r+r] memory refs
6835 in cases where it won't work (TImode, TFmode, TDmode). */
6838 rs6000_eliminate_indexed_memrefs (rtx operands[2])
6840 if (reload_in_progress)
6843 if (GET_CODE (operands[0]) == MEM
6844 && GET_CODE (XEXP (operands[0], 0)) != REG
6845 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0),
6846 GET_MODE (operands[0]), false))
6848 = replace_equiv_address (operands[0],
6849 copy_addr_to_reg (XEXP (operands[0], 0)));
6851 if (GET_CODE (operands[1]) == MEM
6852 && GET_CODE (XEXP (operands[1], 0)) != REG
6853 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0),
6854 GET_MODE (operands[1]), false))
6856 = replace_equiv_address (operands[1],
6857 copy_addr_to_reg (XEXP (operands[1], 0)));
6860 /* Emit a move from SOURCE to DEST in mode MODE. */
6862 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
6866 operands[1] = source;
6868 if (TARGET_DEBUG_ADDR)
6871 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
6872 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
6873 GET_MODE_NAME (mode),
6876 can_create_pseudo_p ());
6878 fprintf (stderr, "source:\n");
6882 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
6883 if (GET_CODE (operands[1]) == CONST_DOUBLE
6884 && ! FLOAT_MODE_P (mode)
6885 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
6887 /* FIXME. This should never happen. */
6888 /* Since it seems that it does, do the safe thing and convert
6890 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
6892 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
6893 || FLOAT_MODE_P (mode)
6894 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
6895 || CONST_DOUBLE_LOW (operands[1]) < 0)
6896 && (CONST_DOUBLE_HIGH (operands[1]) != -1
6897 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
6899 /* Check if GCC is setting up a block move that will end up using FP
6900 registers as temporaries. We must make sure this is acceptable. */
6901 if (GET_CODE (operands[0]) == MEM
6902 && GET_CODE (operands[1]) == MEM
6904 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
6905 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
6906 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
6907 ? 32 : MEM_ALIGN (operands[0])))
6908 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
6910 : MEM_ALIGN (operands[1]))))
6911 && ! MEM_VOLATILE_P (operands [0])
6912 && ! MEM_VOLATILE_P (operands [1]))
6914 emit_move_insn (adjust_address (operands[0], SImode, 0),
6915 adjust_address (operands[1], SImode, 0));
6916 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
6917 adjust_address (copy_rtx (operands[1]), SImode, 4));
6921 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
6922 && !gpc_reg_operand (operands[1], mode))
6923 operands[1] = force_reg (mode, operands[1]);
6925 if (mode == SFmode && ! TARGET_POWERPC
6926 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6927 && GET_CODE (operands[0]) == MEM)
6931 if (reload_in_progress || reload_completed)
6932 regnum = true_regnum (operands[1]);
6933 else if (GET_CODE (operands[1]) == REG)
6934 regnum = REGNO (operands[1]);
6938 /* If operands[1] is a register, on POWER it may have
6939 double-precision data in it, so truncate it to single
6941 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
6944 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
6945 : gen_reg_rtx (mode));
6946 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
6947 operands[1] = newreg;
6951 /* Recognize the case where operand[1] is a reference to thread-local
6952 data and load its address to a register. */
6953 if (rs6000_tls_referenced_p (operands[1]))
6955 enum tls_model model;
6956 rtx tmp = operands[1];
6959 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6961 addend = XEXP (XEXP (tmp, 0), 1);
6962 tmp = XEXP (XEXP (tmp, 0), 0);
6965 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6966 model = SYMBOL_REF_TLS_MODEL (tmp);
6967 gcc_assert (model != 0);
6969 tmp = rs6000_legitimize_tls_address (tmp, model);
6972 tmp = gen_rtx_PLUS (mode, tmp, addend);
6973 tmp = force_operand (tmp, operands[0]);
6978 /* Handle the case where reload calls us with an invalid address. */
6979 if (reload_in_progress && mode == Pmode
6980 && (! general_operand (operands[1], mode)
6981 || ! nonimmediate_operand (operands[0], mode)))
6984 /* 128-bit constant floating-point values on Darwin should really be
6985 loaded as two parts. */
6986 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
6987 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
6989 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
6990 know how to get a DFmode SUBREG of a TFmode. */
6991 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
6992 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
6993 simplify_gen_subreg (imode, operands[1], mode, 0),
6995 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
6996 GET_MODE_SIZE (imode)),
6997 simplify_gen_subreg (imode, operands[1], mode,
6998 GET_MODE_SIZE (imode)),
7003 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
7004 cfun->machine->sdmode_stack_slot =
7005 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
7007 if (reload_in_progress
7009 && MEM_P (operands[0])
7010 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
7011 && REG_P (operands[1]))
7013 if (FP_REGNO_P (REGNO (operands[1])))
7015 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
7016 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7017 emit_insn (gen_movsd_store (mem, operands[1]));
7019 else if (INT_REGNO_P (REGNO (operands[1])))
7021 rtx mem = adjust_address_nv (operands[0], mode, 4);
7022 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7023 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
7029 if (reload_in_progress
7031 && REG_P (operands[0])
7032 && MEM_P (operands[1])
7033 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
7035 if (FP_REGNO_P (REGNO (operands[0])))
7037 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
7038 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7039 emit_insn (gen_movsd_load (operands[0], mem));
7041 else if (INT_REGNO_P (REGNO (operands[0])))
7043 rtx mem = adjust_address_nv (operands[1], mode, 4);
7044 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7045 emit_insn (gen_movsd_hardfloat (operands[0], mem));
7052 /* FIXME: In the long term, this switch statement should go away
7053 and be replaced by a sequence of tests based on things like
7059 if (CONSTANT_P (operands[1])
7060 && GET_CODE (operands[1]) != CONST_INT)
7061 operands[1] = force_const_mem (mode, operands[1]);
7066 rs6000_eliminate_indexed_memrefs (operands);
7073 if (CONSTANT_P (operands[1])
7074 && ! easy_fp_constant (operands[1], mode))
7075 operands[1] = force_const_mem (mode, operands[1]);
7088 if (CONSTANT_P (operands[1])
7089 && !easy_vector_constant (operands[1], mode))
7090 operands[1] = force_const_mem (mode, operands[1]);
7095 /* Use default pattern for address of ELF small data */
7098 && DEFAULT_ABI == ABI_V4
7099 && (GET_CODE (operands[1]) == SYMBOL_REF
7100 || GET_CODE (operands[1]) == CONST)
7101 && small_data_operand (operands[1], mode))
7103 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7107 if (DEFAULT_ABI == ABI_V4
7108 && mode == Pmode && mode == SImode
7109 && flag_pic == 1 && got_operand (operands[1], mode))
7111 emit_insn (gen_movsi_got (operands[0], operands[1]));
7115 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
7119 && CONSTANT_P (operands[1])
7120 && GET_CODE (operands[1]) != HIGH
7121 && GET_CODE (operands[1]) != CONST_INT)
7123 rtx target = (!can_create_pseudo_p ()
7125 : gen_reg_rtx (mode));
7127 /* If this is a function address on -mcall-aixdesc,
7128 convert it to the address of the descriptor. */
7129 if (DEFAULT_ABI == ABI_AIX
7130 && GET_CODE (operands[1]) == SYMBOL_REF
7131 && XSTR (operands[1], 0)[0] == '.')
7133 const char *name = XSTR (operands[1], 0);
7135 while (*name == '.')
7137 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
7138 CONSTANT_POOL_ADDRESS_P (new_ref)
7139 = CONSTANT_POOL_ADDRESS_P (operands[1]);
7140 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
7141 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
7142 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
7143 operands[1] = new_ref;
7146 if (DEFAULT_ABI == ABI_DARWIN)
7149 if (MACHO_DYNAMIC_NO_PIC_P)
7151 /* Take care of any required data indirection. */
7152 operands[1] = rs6000_machopic_legitimize_pic_address (
7153 operands[1], mode, operands[0]);
7154 if (operands[0] != operands[1])
7155 emit_insn (gen_rtx_SET (VOIDmode,
7156 operands[0], operands[1]));
7160 emit_insn (gen_macho_high (target, operands[1]));
7161 emit_insn (gen_macho_low (operands[0], target, operands[1]));
7165 emit_insn (gen_elf_high (target, operands[1]));
7166 emit_insn (gen_elf_low (operands[0], target, operands[1]));
7170 /* If this is a SYMBOL_REF that refers to a constant pool entry,
7171 and we have put it in the TOC, we just need to make a TOC-relative
7174 && GET_CODE (operands[1]) == SYMBOL_REF
7175 && constant_pool_expr_p (operands[1])
7176 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
7177 get_pool_mode (operands[1])))
7178 || (TARGET_CMODEL == CMODEL_MEDIUM
7179 && GET_CODE (operands[1]) == SYMBOL_REF
7180 && !CONSTANT_POOL_ADDRESS_P (operands[1])
7181 && SYMBOL_REF_LOCAL_P (operands[1])))
7184 if (TARGET_CMODEL != CMODEL_SMALL)
7186 if (can_create_pseudo_p ())
7187 reg = gen_reg_rtx (Pmode);
7191 operands[1] = create_TOC_reference (operands[1], reg);
7193 else if (mode == Pmode
7194 && CONSTANT_P (operands[1])
7195 && GET_CODE (operands[1]) != HIGH
7196 && !(TARGET_CMODEL != CMODEL_SMALL
7197 && GET_CODE (operands[1]) == CONST
7198 && GET_CODE (XEXP (operands[1], 0)) == PLUS
7199 && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == HIGH)
7200 && ((GET_CODE (operands[1]) != CONST_INT
7201 && ! easy_fp_constant (operands[1], mode))
7202 || (GET_CODE (operands[1]) == CONST_INT
7203 && (num_insns_constant (operands[1], mode)
7204 > (TARGET_CMODEL != CMODEL_SMALL ? 3 : 2)))
7205 || (GET_CODE (operands[0]) == REG
7206 && FP_REGNO_P (REGNO (operands[0]))))
7207 && ! legitimate_constant_pool_address_p (operands[1], mode,
7209 && ! toc_relative_expr_p (operands[1])
7210 && (TARGET_CMODEL == CMODEL_SMALL
7211 || can_create_pseudo_p ()
7212 || (REG_P (operands[0])
7213 && INT_REG_OK_FOR_BASE_P (operands[0], true))))
7217 /* Darwin uses a special PIC legitimizer. */
7218 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
7221 rs6000_machopic_legitimize_pic_address (operands[1], mode,
7223 if (operands[0] != operands[1])
7224 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7229 /* If we are to limit the number of things we put in the TOC and
7230 this is a symbol plus a constant we can add in one insn,
7231 just put the symbol in the TOC and add the constant. Don't do
7232 this if reload is in progress. */
7233 if (GET_CODE (operands[1]) == CONST
7234 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
7235 && GET_CODE (XEXP (operands[1], 0)) == PLUS
7236 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
7237 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
7238 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
7239 && ! side_effects_p (operands[0]))
7242 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
7243 rtx other = XEXP (XEXP (operands[1], 0), 1);
7245 sym = force_reg (mode, sym);
7246 emit_insn (gen_add3_insn (operands[0], sym, other));
7250 operands[1] = force_const_mem (mode, operands[1]);
7253 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7254 && constant_pool_expr_p (XEXP (operands[1], 0))
7255 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
7256 get_pool_constant (XEXP (operands[1], 0)),
7257 get_pool_mode (XEXP (operands[1], 0))))
7261 if (TARGET_CMODEL != CMODEL_SMALL)
7263 if (can_create_pseudo_p ())
7264 reg = gen_reg_rtx (Pmode);
7268 tocref = create_TOC_reference (XEXP (operands[1], 0), reg);
7269 operands[1] = gen_const_mem (mode, tocref);
7270 set_mem_alias_set (operands[1], get_TOC_alias_set ());
7276 rs6000_eliminate_indexed_memrefs (operands);
7280 emit_insn (gen_rtx_PARALLEL (VOIDmode,
7282 gen_rtx_SET (VOIDmode,
7283 operands[0], operands[1]),
7284 gen_rtx_CLOBBER (VOIDmode,
7285 gen_rtx_SCRATCH (SImode)))));
7291 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
7294 /* Above, we may have called force_const_mem which may have returned
7295 an invalid address. If we can, fix this up; otherwise, reload will
7296 have to deal with it. */
7297 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
7298 operands[1] = validize_mem (operands[1]);
7301 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7304 /* Nonzero if we can use a floating-point register to pass this arg. */
7305 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
7306 (SCALAR_FLOAT_MODE_P (MODE) \
7307 && (CUM)->fregno <= FP_ARG_MAX_REG \
7308 && TARGET_HARD_FLOAT && TARGET_FPRS)
7310 /* Nonzero if we can use an AltiVec register to pass this arg. */
7311 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
7312 (ALTIVEC_OR_VSX_VECTOR_MODE (MODE) \
7313 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
7314 && TARGET_ALTIVEC_ABI \
7317 /* Return a nonzero value to say to return the function value in
7318 memory, just as large structures are always returned. TYPE will be
7319 the data type of the value, and FNTYPE will be the type of the
7320 function doing the returning, or @code{NULL} for libcalls.
7322 The AIX ABI for the RS/6000 specifies that all structures are
7323 returned in memory. The Darwin ABI does the same.
7325 For the Darwin 64 Bit ABI, a function result can be returned in
7326 registers or in memory, depending on the size of the return data
7327 type. If it is returned in registers, the value occupies the same
7328 registers as it would if it were the first and only function
7329 argument. Otherwise, the function places its result in memory at
7330 the location pointed to by GPR3.
7332 The SVR4 ABI specifies that structures <= 8 bytes are returned in r3/r4,
7333 but a draft put them in memory, and GCC used to implement the draft
7334 instead of the final standard. Therefore, aix_struct_return
7335 controls this instead of DEFAULT_ABI; V.4 targets needing backward
7336 compatibility can change DRAFT_V4_STRUCT_RET to override the
7337 default, and -m switches get the final word. See
7338 rs6000_option_override_internal for more details.
7340 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
7341 long double support is enabled. These values are returned in memory.
7343 int_size_in_bytes returns -1 for variable size objects, which go in
7344 memory always. The cast to unsigned makes -1 > 8. */
7347 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
7349 /* For the Darwin64 ABI, test if we can fit the return value in regs. */
7351 && rs6000_darwin64_abi
7352 && TREE_CODE (type) == RECORD_TYPE
7353 && int_size_in_bytes (type) > 0)
7355 CUMULATIVE_ARGS valcum;
7359 valcum.fregno = FP_ARG_MIN_REG;
7360 valcum.vregno = ALTIVEC_ARG_MIN_REG;
7361 /* Do a trial code generation as if this were going to be passed
7362 as an argument; if any part goes in memory, we return NULL. */
7363 valret = rs6000_darwin64_record_arg (&valcum, type, true, true);
7366 /* Otherwise fall through to more conventional ABI rules. */
7369 if (AGGREGATE_TYPE_P (type)
7370 && (aix_struct_return
7371 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
7374 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7375 modes only exist for GCC vector types if -maltivec. */
7376 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
7377 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
7380 /* Return synthetic vectors in memory. */
7381 if (TREE_CODE (type) == VECTOR_TYPE
7382 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
7384 static bool warned_for_return_big_vectors = false;
7385 if (!warned_for_return_big_vectors)
7387 warning (0, "GCC vector returned by reference: "
7388 "non-standard ABI extension with no compatibility guarantee");
7389 warned_for_return_big_vectors = true;
7394 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
7400 #ifdef HAVE_AS_GNU_ATTRIBUTE
7401 /* Return TRUE if a call to function FNDECL may be one that
7402 potentially affects the function calling ABI of the object file. */
7405 call_ABI_of_interest (tree fndecl)
7407 if (cgraph_state == CGRAPH_STATE_EXPANSION)
7409 struct cgraph_node *c_node;
7411 /* Libcalls are always interesting. */
7412 if (fndecl == NULL_TREE)
7415 /* Any call to an external function is interesting. */
7416 if (DECL_EXTERNAL (fndecl))
7419 /* Interesting functions that we are emitting in this object file. */
7420 c_node = cgraph_get_node (fndecl);
7421 c_node = cgraph_function_or_thunk_node (c_node, NULL);
7422 return !cgraph_only_called_directly_p (c_node);
7428 /* Initialize a variable CUM of type CUMULATIVE_ARGS
7429 for a call to a function whose data type is FNTYPE.
7430 For a library call, FNTYPE is 0 and RETURN_MODE the return value mode.
7432 For incoming args we set the number of arguments in the prototype large
7433 so we never return a PARALLEL. */
7436 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
7437 rtx libname ATTRIBUTE_UNUSED, int incoming,
7438 int libcall, int n_named_args,
7439 tree fndecl ATTRIBUTE_UNUSED,
7440 enum machine_mode return_mode ATTRIBUTE_UNUSED)
7442 static CUMULATIVE_ARGS zero_cumulative;
7444 *cum = zero_cumulative;
7446 cum->fregno = FP_ARG_MIN_REG;
7447 cum->vregno = ALTIVEC_ARG_MIN_REG;
7448 cum->prototype = (fntype && prototype_p (fntype));
7449 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
7450 ? CALL_LIBCALL : CALL_NORMAL);
7451 cum->sysv_gregno = GP_ARG_MIN_REG;
7452 cum->stdarg = stdarg_p (fntype);
7454 cum->nargs_prototype = 0;
7455 if (incoming || cum->prototype)
7456 cum->nargs_prototype = n_named_args;
7458 /* Check for a longcall attribute. */
7459 if ((!fntype && rs6000_default_long_calls)
7461 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
7462 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
7463 cum->call_cookie |= CALL_LONG;
7465 if (TARGET_DEBUG_ARG)
7467 fprintf (stderr, "\ninit_cumulative_args:");
7470 tree ret_type = TREE_TYPE (fntype);
7471 fprintf (stderr, " ret code = %s,",
7472 tree_code_name[ (int)TREE_CODE (ret_type) ]);
7475 if (cum->call_cookie & CALL_LONG)
7476 fprintf (stderr, " longcall,");
7478 fprintf (stderr, " proto = %d, nargs = %d\n",
7479 cum->prototype, cum->nargs_prototype);
7482 #ifdef HAVE_AS_GNU_ATTRIBUTE
7483 if (DEFAULT_ABI == ABI_V4)
7485 cum->escapes = call_ABI_of_interest (fndecl);
7492 return_type = TREE_TYPE (fntype);
7493 return_mode = TYPE_MODE (return_type);
7496 return_type = lang_hooks.types.type_for_mode (return_mode, 0);
7498 if (return_type != NULL)
7500 if (TREE_CODE (return_type) == RECORD_TYPE
7501 && TYPE_TRANSPARENT_AGGR (return_type))
7503 return_type = TREE_TYPE (first_field (return_type));
7504 return_mode = TYPE_MODE (return_type);
7506 if (AGGREGATE_TYPE_P (return_type)
7507 && ((unsigned HOST_WIDE_INT) int_size_in_bytes (return_type)
7509 rs6000_returns_struct = true;
7511 if (SCALAR_FLOAT_MODE_P (return_mode))
7512 rs6000_passes_float = true;
7513 else if (ALTIVEC_OR_VSX_VECTOR_MODE (return_mode)
7514 || SPE_VECTOR_MODE (return_mode))
7515 rs6000_passes_vector = true;
7522 && TARGET_ALTIVEC_ABI
7523 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
7525 error ("cannot return value in vector register because"
7526 " altivec instructions are disabled, use -maltivec"
7531 /* Return true if TYPE must be passed on the stack and not in registers. */
7534 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
7536 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
7537 return must_pass_in_stack_var_size (mode, type);
7539 return must_pass_in_stack_var_size_or_pad (mode, type);
7542 /* If defined, a C expression which determines whether, and in which
7543 direction, to pad out an argument with extra space. The value
7544 should be of type `enum direction': either `upward' to pad above
7545 the argument, `downward' to pad below, or `none' to inhibit
7548 For the AIX ABI structs are always stored left shifted in their
7552 function_arg_padding (enum machine_mode mode, const_tree type)
7554 #ifndef AGGREGATE_PADDING_FIXED
7555 #define AGGREGATE_PADDING_FIXED 0
7557 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
7558 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
7561 if (!AGGREGATE_PADDING_FIXED)
7563 /* GCC used to pass structures of the same size as integer types as
7564 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
7565 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
7566 passed padded downward, except that -mstrict-align further
7567 muddied the water in that multi-component structures of 2 and 4
7568 bytes in size were passed padded upward.
7570 The following arranges for best compatibility with previous
7571 versions of gcc, but removes the -mstrict-align dependency. */
7572 if (BYTES_BIG_ENDIAN)
7574 HOST_WIDE_INT size = 0;
7576 if (mode == BLKmode)
7578 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
7579 size = int_size_in_bytes (type);
7582 size = GET_MODE_SIZE (mode);
7584 if (size == 1 || size == 2 || size == 4)
7590 if (AGGREGATES_PAD_UPWARD_ALWAYS)
7592 if (type != 0 && AGGREGATE_TYPE_P (type))
7596 /* Fall back to the default. */
7597 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
7600 /* If defined, a C expression that gives the alignment boundary, in bits,
7601 of an argument with the specified mode and type. If it is not defined,
7602 PARM_BOUNDARY is used for all arguments.
7604 V.4 wants long longs and doubles to be double word aligned. Just
7605 testing the mode size is a boneheaded way to do this as it means
7606 that other types such as complex int are also double word aligned.
7607 However, we're stuck with this because changing the ABI might break
7608 existing library interfaces.
7610 Doubleword align SPE vectors.
7611 Quadword align Altivec/VSX vectors.
7612 Quadword align large synthetic vector types. */
7615 rs6000_function_arg_boundary (enum machine_mode mode, const_tree type)
7617 if (DEFAULT_ABI == ABI_V4
7618 && (GET_MODE_SIZE (mode) == 8
7619 || (TARGET_HARD_FLOAT
7621 && (mode == TFmode || mode == TDmode))))
7623 else if (SPE_VECTOR_MODE (mode)
7624 || (type && TREE_CODE (type) == VECTOR_TYPE
7625 && int_size_in_bytes (type) >= 8
7626 && int_size_in_bytes (type) < 16))
7628 else if (ALTIVEC_OR_VSX_VECTOR_MODE (mode)
7629 || (type && TREE_CODE (type) == VECTOR_TYPE
7630 && int_size_in_bytes (type) >= 16))
7632 else if (TARGET_MACHO
7633 && rs6000_darwin64_abi
7635 && type && TYPE_ALIGN (type) > 64)
7638 return PARM_BOUNDARY;
7641 /* For a function parm of MODE and TYPE, return the starting word in
7642 the parameter area. NWORDS of the parameter area are already used. */
7645 rs6000_parm_start (enum machine_mode mode, const_tree type,
7646 unsigned int nwords)
7649 unsigned int parm_offset;
7651 align = rs6000_function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
7652 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
7653 return nwords + (-(parm_offset + nwords) & align);
7656 /* Compute the size (in words) of a function argument. */
7658 static unsigned long
7659 rs6000_arg_size (enum machine_mode mode, const_tree type)
7663 if (mode != BLKmode)
7664 size = GET_MODE_SIZE (mode);
7666 size = int_size_in_bytes (type);
7669 return (size + 3) >> 2;
7671 return (size + 7) >> 3;
7674 /* Use this to flush pending int fields. */
7677 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
7678 HOST_WIDE_INT bitpos, int final)
7680 unsigned int startbit, endbit;
7681 int intregs, intoffset;
7682 enum machine_mode mode;
7684 /* Handle the situations where a float is taking up the first half
7685 of the GPR, and the other half is empty (typically due to
7686 alignment restrictions). We can detect this by a 8-byte-aligned
7687 int field, or by seeing that this is the final flush for this
7688 argument. Count the word and continue on. */
7689 if (cum->floats_in_gpr == 1
7690 && (cum->intoffset % 64 == 0
7691 || (cum->intoffset == -1 && final)))
7694 cum->floats_in_gpr = 0;
7697 if (cum->intoffset == -1)
7700 intoffset = cum->intoffset;
7701 cum->intoffset = -1;
7702 cum->floats_in_gpr = 0;
7704 if (intoffset % BITS_PER_WORD != 0)
7706 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7708 if (mode == BLKmode)
7710 /* We couldn't find an appropriate mode, which happens,
7711 e.g., in packed structs when there are 3 bytes to load.
7712 Back intoffset back to the beginning of the word in this
7714 intoffset = intoffset & -BITS_PER_WORD;
7718 startbit = intoffset & -BITS_PER_WORD;
7719 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7720 intregs = (endbit - startbit) / BITS_PER_WORD;
7721 cum->words += intregs;
7722 /* words should be unsigned. */
7723 if ((unsigned)cum->words < (endbit/BITS_PER_WORD))
7725 int pad = (endbit/BITS_PER_WORD) - cum->words;
7730 /* The darwin64 ABI calls for us to recurse down through structs,
7731 looking for elements passed in registers. Unfortunately, we have
7732 to track int register count here also because of misalignments
7733 in powerpc alignment mode. */
7736 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
7738 HOST_WIDE_INT startbitpos)
7742 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
7743 if (TREE_CODE (f) == FIELD_DECL)
7745 HOST_WIDE_INT bitpos = startbitpos;
7746 tree ftype = TREE_TYPE (f);
7747 enum machine_mode mode;
7748 if (ftype == error_mark_node)
7750 mode = TYPE_MODE (ftype);
7752 if (DECL_SIZE (f) != 0
7753 && host_integerp (bit_position (f), 1))
7754 bitpos += int_bit_position (f);
7756 /* ??? FIXME: else assume zero offset. */
7758 if (TREE_CODE (ftype) == RECORD_TYPE)
7759 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
7760 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
7762 unsigned n_fpregs = (GET_MODE_SIZE (mode) + 7) >> 3;
7763 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
7764 cum->fregno += n_fpregs;
7765 /* Single-precision floats present a special problem for
7766 us, because they are smaller than an 8-byte GPR, and so
7767 the structure-packing rules combined with the standard
7768 varargs behavior mean that we want to pack float/float
7769 and float/int combinations into a single register's
7770 space. This is complicated by the arg advance flushing,
7771 which works on arbitrarily large groups of int-type
7775 if (cum->floats_in_gpr == 1)
7777 /* Two floats in a word; count the word and reset
7780 cum->floats_in_gpr = 0;
7782 else if (bitpos % 64 == 0)
7784 /* A float at the beginning of an 8-byte word;
7785 count it and put off adjusting cum->words until
7786 we see if a arg advance flush is going to do it
7788 cum->floats_in_gpr++;
7792 /* The float is at the end of a word, preceded
7793 by integer fields, so the arg advance flush
7794 just above has already set cum->words and
7795 everything is taken care of. */
7799 cum->words += n_fpregs;
7801 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
7803 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
7807 else if (cum->intoffset == -1)
7808 cum->intoffset = bitpos;
7812 /* Check for an item that needs to be considered specially under the darwin 64
7813 bit ABI. These are record types where the mode is BLK or the structure is
7816 rs6000_darwin64_struct_check_p (enum machine_mode mode, const_tree type)
7818 return rs6000_darwin64_abi
7819 && ((mode == BLKmode
7820 && TREE_CODE (type) == RECORD_TYPE
7821 && int_size_in_bytes (type) > 0)
7822 || (type && TREE_CODE (type) == RECORD_TYPE
7823 && int_size_in_bytes (type) == 8)) ? 1 : 0;
7826 /* Update the data in CUM to advance over an argument
7827 of mode MODE and data type TYPE.
7828 (TYPE is null for libcalls where that information may not be available.)
7830 Note that for args passed by reference, function_arg will be called
7831 with MODE and TYPE set to that of the pointer to the arg, not the arg
7835 rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7836 const_tree type, bool named, int depth)
7838 /* Only tick off an argument if we're not recursing. */
7840 cum->nargs_prototype--;
7842 #ifdef HAVE_AS_GNU_ATTRIBUTE
7843 if (DEFAULT_ABI == ABI_V4
7846 if (SCALAR_FLOAT_MODE_P (mode))
7847 rs6000_passes_float = true;
7848 else if (named && ALTIVEC_OR_VSX_VECTOR_MODE (mode))
7849 rs6000_passes_vector = true;
7850 else if (SPE_VECTOR_MODE (mode)
7852 && cum->sysv_gregno <= GP_ARG_MAX_REG)
7853 rs6000_passes_vector = true;
7857 if (TARGET_ALTIVEC_ABI
7858 && (ALTIVEC_OR_VSX_VECTOR_MODE (mode)
7859 || (type && TREE_CODE (type) == VECTOR_TYPE
7860 && int_size_in_bytes (type) == 16)))
7864 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
7867 if (!TARGET_ALTIVEC)
7868 error ("cannot pass argument in vector register because"
7869 " altivec instructions are disabled, use -maltivec"
7872 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
7873 even if it is going to be passed in a vector register.
7874 Darwin does the same for variable-argument functions. */
7875 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
7876 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
7886 /* Vector parameters must be 16-byte aligned. This places
7887 them at 2 mod 4 in terms of words in 32-bit mode, since
7888 the parameter save area starts at offset 24 from the
7889 stack. In 64-bit mode, they just have to start on an
7890 even word, since the parameter save area is 16-byte
7891 aligned. Space for GPRs is reserved even if the argument
7892 will be passed in memory. */
7894 align = (2 - cum->words) & 3;
7896 align = cum->words & 1;
7897 cum->words += align + rs6000_arg_size (mode, type);
7899 if (TARGET_DEBUG_ARG)
7901 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
7903 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
7904 cum->nargs_prototype, cum->prototype,
7905 GET_MODE_NAME (mode));
7909 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
7911 && cum->sysv_gregno <= GP_ARG_MAX_REG)
7914 else if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
7916 int size = int_size_in_bytes (type);
7917 /* Variable sized types have size == -1 and are
7918 treated as if consisting entirely of ints.
7919 Pad to 16 byte boundary if needed. */
7920 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7921 && (cum->words % 2) != 0)
7923 /* For varargs, we can just go up by the size of the struct. */
7925 cum->words += (size + 7) / 8;
7928 /* It is tempting to say int register count just goes up by
7929 sizeof(type)/8, but this is wrong in a case such as
7930 { int; double; int; } [powerpc alignment]. We have to
7931 grovel through the fields for these too. */
7933 cum->floats_in_gpr = 0;
7934 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
7935 rs6000_darwin64_record_arg_advance_flush (cum,
7936 size * BITS_PER_UNIT, 1);
7938 if (TARGET_DEBUG_ARG)
7940 fprintf (stderr, "function_adv: words = %2d, align=%d, size=%d",
7941 cum->words, TYPE_ALIGN (type), size);
7943 "nargs = %4d, proto = %d, mode = %4s (darwin64 abi)\n",
7944 cum->nargs_prototype, cum->prototype,
7945 GET_MODE_NAME (mode));
7948 else if (DEFAULT_ABI == ABI_V4)
7950 if (TARGET_HARD_FLOAT && TARGET_FPRS
7951 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
7952 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
7953 || (mode == TFmode && !TARGET_IEEEQUAD)
7954 || mode == SDmode || mode == DDmode || mode == TDmode))
7956 /* _Decimal128 must use an even/odd register pair. This assumes
7957 that the register number is odd when fregno is odd. */
7958 if (mode == TDmode && (cum->fregno % 2) == 1)
7961 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7962 <= FP_ARG_V4_MAX_REG)
7963 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7966 cum->fregno = FP_ARG_V4_MAX_REG + 1;
7967 if (mode == DFmode || mode == TFmode
7968 || mode == DDmode || mode == TDmode)
7969 cum->words += cum->words & 1;
7970 cum->words += rs6000_arg_size (mode, type);
7975 int n_words = rs6000_arg_size (mode, type);
7976 int gregno = cum->sysv_gregno;
7978 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7979 (r7,r8) or (r9,r10). As does any other 2 word item such
7980 as complex int due to a historical mistake. */
7982 gregno += (1 - gregno) & 1;
7984 /* Multi-reg args are not split between registers and stack. */
7985 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7987 /* Long long and SPE vectors are aligned on the stack.
7988 So are other 2 word items such as complex int due to
7989 a historical mistake. */
7991 cum->words += cum->words & 1;
7992 cum->words += n_words;
7995 /* Note: continuing to accumulate gregno past when we've started
7996 spilling to the stack indicates the fact that we've started
7997 spilling to the stack to expand_builtin_saveregs. */
7998 cum->sysv_gregno = gregno + n_words;
8001 if (TARGET_DEBUG_ARG)
8003 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8004 cum->words, cum->fregno);
8005 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
8006 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
8007 fprintf (stderr, "mode = %4s, named = %d\n",
8008 GET_MODE_NAME (mode), named);
8013 int n_words = rs6000_arg_size (mode, type);
8014 int start_words = cum->words;
8015 int align_words = rs6000_parm_start (mode, type, start_words);
8017 cum->words = align_words + n_words;
8019 if (SCALAR_FLOAT_MODE_P (mode)
8020 && TARGET_HARD_FLOAT && TARGET_FPRS)
8022 /* _Decimal128 must be passed in an even/odd float register pair.
8023 This assumes that the register number is odd when fregno is
8025 if (mode == TDmode && (cum->fregno % 2) == 1)
8027 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8030 if (TARGET_DEBUG_ARG)
8032 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8033 cum->words, cum->fregno);
8034 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
8035 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
8036 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
8037 named, align_words - start_words, depth);
8043 rs6000_function_arg_advance (cumulative_args_t cum, enum machine_mode mode,
8044 const_tree type, bool named)
8046 rs6000_function_arg_advance_1 (get_cumulative_args (cum), mode, type, named,
8051 spe_build_register_parallel (enum machine_mode mode, int gregno)
8058 r1 = gen_rtx_REG (DImode, gregno);
8059 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8060 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
8064 r1 = gen_rtx_REG (DImode, gregno);
8065 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8066 r3 = gen_rtx_REG (DImode, gregno + 2);
8067 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8068 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
8071 r1 = gen_rtx_REG (DImode, gregno);
8072 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8073 r3 = gen_rtx_REG (DImode, gregno + 2);
8074 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8075 r5 = gen_rtx_REG (DImode, gregno + 4);
8076 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
8077 r7 = gen_rtx_REG (DImode, gregno + 6);
8078 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
8079 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
8086 /* Determine where to put a SIMD argument on the SPE. */
8088 rs6000_spe_function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
8091 int gregno = cum->sysv_gregno;
8093 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
8094 are passed and returned in a pair of GPRs for ABI compatibility. */
8095 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
8096 || mode == DCmode || mode == TCmode))
8098 int n_words = rs6000_arg_size (mode, type);
8100 /* Doubles go in an odd/even register pair (r5/r6, etc). */
8102 gregno += (1 - gregno) & 1;
8104 /* Multi-reg args are not split between registers and stack. */
8105 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8108 return spe_build_register_parallel (mode, gregno);
8112 int n_words = rs6000_arg_size (mode, type);
8114 /* SPE vectors are put in odd registers. */
8115 if (n_words == 2 && (gregno & 1) == 0)
8118 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
8121 enum machine_mode m = SImode;
8123 r1 = gen_rtx_REG (m, gregno);
8124 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
8125 r2 = gen_rtx_REG (m, gregno + 1);
8126 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
8127 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
8134 if (gregno <= GP_ARG_MAX_REG)
8135 return gen_rtx_REG (mode, gregno);
8141 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
8142 structure between cum->intoffset and bitpos to integer registers. */
8145 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
8146 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
8148 enum machine_mode mode;
8150 unsigned int startbit, endbit;
8151 int this_regno, intregs, intoffset;
8154 if (cum->intoffset == -1)
8157 intoffset = cum->intoffset;
8158 cum->intoffset = -1;
8160 /* If this is the trailing part of a word, try to only load that
8161 much into the register. Otherwise load the whole register. Note
8162 that in the latter case we may pick up unwanted bits. It's not a
8163 problem at the moment but may wish to revisit. */
8165 if (intoffset % BITS_PER_WORD != 0)
8167 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
8169 if (mode == BLKmode)
8171 /* We couldn't find an appropriate mode, which happens,
8172 e.g., in packed structs when there are 3 bytes to load.
8173 Back intoffset back to the beginning of the word in this
8175 intoffset = intoffset & -BITS_PER_WORD;
8182 startbit = intoffset & -BITS_PER_WORD;
8183 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
8184 intregs = (endbit - startbit) / BITS_PER_WORD;
8185 this_regno = cum->words + intoffset / BITS_PER_WORD;
8187 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
8190 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
8194 intoffset /= BITS_PER_UNIT;
8197 regno = GP_ARG_MIN_REG + this_regno;
8198 reg = gen_rtx_REG (mode, regno);
8200 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
8203 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
8207 while (intregs > 0);
8210 /* Recursive workhorse for the following. */
8213 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
8214 HOST_WIDE_INT startbitpos, rtx rvec[],
8219 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
8220 if (TREE_CODE (f) == FIELD_DECL)
8222 HOST_WIDE_INT bitpos = startbitpos;
8223 tree ftype = TREE_TYPE (f);
8224 enum machine_mode mode;
8225 if (ftype == error_mark_node)
8227 mode = TYPE_MODE (ftype);
8229 if (DECL_SIZE (f) != 0
8230 && host_integerp (bit_position (f), 1))
8231 bitpos += int_bit_position (f);
8233 /* ??? FIXME: else assume zero offset. */
8235 if (TREE_CODE (ftype) == RECORD_TYPE)
8236 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
8237 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
8239 unsigned n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
8243 case SCmode: mode = SFmode; break;
8244 case DCmode: mode = DFmode; break;
8245 case TCmode: mode = TFmode; break;
8249 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8250 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
8252 gcc_assert (cum->fregno == FP_ARG_MAX_REG
8253 && (mode == TFmode || mode == TDmode));
8254 /* Long double or _Decimal128 split over regs and memory. */
8255 mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : DFmode;
8259 = gen_rtx_EXPR_LIST (VOIDmode,
8260 gen_rtx_REG (mode, cum->fregno++),
8261 GEN_INT (bitpos / BITS_PER_UNIT));
8262 if (mode == TFmode || mode == TDmode)
8265 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
8267 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8269 = gen_rtx_EXPR_LIST (VOIDmode,
8270 gen_rtx_REG (mode, cum->vregno++),
8271 GEN_INT (bitpos / BITS_PER_UNIT));
8273 else if (cum->intoffset == -1)
8274 cum->intoffset = bitpos;
8278 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
8279 the register(s) to be used for each field and subfield of a struct
8280 being passed by value, along with the offset of where the
8281 register's value may be found in the block. FP fields go in FP
8282 register, vector fields go in vector registers, and everything
8283 else goes in int registers, packed as in memory.
8285 This code is also used for function return values. RETVAL indicates
8286 whether this is the case.
8288 Much of this is taken from the SPARC V9 port, which has a similar
8289 calling convention. */
8292 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
8293 bool named, bool retval)
8295 rtx rvec[FIRST_PSEUDO_REGISTER];
8296 int k = 1, kbase = 1;
8297 HOST_WIDE_INT typesize = int_size_in_bytes (type);
8298 /* This is a copy; modifications are not visible to our caller. */
8299 CUMULATIVE_ARGS copy_cum = *orig_cum;
8300 CUMULATIVE_ARGS *cum = ©_cum;
8302 /* Pad to 16 byte boundary if needed. */
8303 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8304 && (cum->words % 2) != 0)
8311 /* Put entries into rvec[] for individual FP and vector fields, and
8312 for the chunks of memory that go in int regs. Note we start at
8313 element 1; 0 is reserved for an indication of using memory, and
8314 may or may not be filled in below. */
8315 rs6000_darwin64_record_arg_recurse (cum, type, /* startbit pos= */ 0, rvec, &k);
8316 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
8318 /* If any part of the struct went on the stack put all of it there.
8319 This hack is because the generic code for
8320 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
8321 parts of the struct are not at the beginning. */
8325 return NULL_RTX; /* doesn't go in registers at all */
8327 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8329 if (k > 1 || cum->use_stack)
8330 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
8335 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
8338 rs6000_mixed_function_arg (enum machine_mode mode, const_tree type,
8343 rtx rvec[GP_ARG_NUM_REG + 1];
8345 if (align_words >= GP_ARG_NUM_REG)
8348 n_units = rs6000_arg_size (mode, type);
8350 /* Optimize the simple case where the arg fits in one gpr, except in
8351 the case of BLKmode due to assign_parms assuming that registers are
8352 BITS_PER_WORD wide. */
8354 || (n_units == 1 && mode != BLKmode))
8355 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8358 if (align_words + n_units > GP_ARG_NUM_REG)
8359 /* Not all of the arg fits in gprs. Say that it goes in memory too,
8360 using a magic NULL_RTX component.
8361 This is not strictly correct. Only some of the arg belongs in
8362 memory, not all of it. However, the normal scheme using
8363 function_arg_partial_nregs can result in unusual subregs, eg.
8364 (subreg:SI (reg:DF) 4), which are not handled well. The code to
8365 store the whole arg to memory is often more efficient than code
8366 to store pieces, and we know that space is available in the right
8367 place for the whole arg. */
8368 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8373 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
8374 rtx off = GEN_INT (i++ * 4);
8375 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8377 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
8379 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8382 /* Determine where to put an argument to a function.
8383 Value is zero to push the argument on the stack,
8384 or a hard register in which to store the argument.
8386 MODE is the argument's machine mode.
8387 TYPE is the data type of the argument (as a tree).
8388 This is null for libcalls where that information may
8390 CUM is a variable of type CUMULATIVE_ARGS which gives info about
8391 the preceding args and about the function being called. It is
8392 not modified in this routine.
8393 NAMED is nonzero if this argument is a named parameter
8394 (otherwise it is an extra parameter matching an ellipsis).
8396 On RS/6000 the first eight words of non-FP are normally in registers
8397 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
8398 Under V.4, the first 8 FP args are in registers.
8400 If this is floating-point and no prototype is specified, we use
8401 both an FP and integer register (or possibly FP reg and stack). Library
8402 functions (when CALL_LIBCALL is set) always have the proper types for args,
8403 so we can pass the FP value just in one register. emit_library_function
8404 doesn't support PARALLEL anyway.
8406 Note that for args passed by reference, function_arg will be called
8407 with MODE and TYPE set to that of the pointer to the arg, not the arg
8411 rs6000_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
8412 const_tree type, bool named)
8414 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
8415 enum rs6000_abi abi = DEFAULT_ABI;
8417 /* Return a marker to indicate whether CR1 needs to set or clear the
8418 bit that V.4 uses to say fp args were passed in registers.
8419 Assume that we don't need the marker for software floating point,
8420 or compiler generated library calls. */
8421 if (mode == VOIDmode)
8424 && (cum->call_cookie & CALL_LIBCALL) == 0
8426 || (cum->nargs_prototype < 0
8427 && (cum->prototype || TARGET_NO_PROTOTYPE))))
8429 /* For the SPE, we need to crxor CR6 always. */
8431 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
8432 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
8433 return GEN_INT (cum->call_cookie
8434 | ((cum->fregno == FP_ARG_MIN_REG)
8435 ? CALL_V4_SET_FP_ARGS
8436 : CALL_V4_CLEAR_FP_ARGS));
8439 return GEN_INT (cum->call_cookie & ~CALL_LIBCALL);
8442 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8444 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, /*retval= */false);
8445 if (rslt != NULL_RTX)
8447 /* Else fall through to usual handling. */
8450 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
8451 if (TARGET_64BIT && ! cum->prototype)
8453 /* Vector parameters get passed in vector register
8454 and also in GPRs or memory, in absence of prototype. */
8457 align_words = (cum->words + 1) & ~1;
8459 if (align_words >= GP_ARG_NUM_REG)
8465 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8467 return gen_rtx_PARALLEL (mode,
8469 gen_rtx_EXPR_LIST (VOIDmode,
8471 gen_rtx_EXPR_LIST (VOIDmode,
8472 gen_rtx_REG (mode, cum->vregno),
8476 return gen_rtx_REG (mode, cum->vregno);
8477 else if (TARGET_ALTIVEC_ABI
8478 && (ALTIVEC_OR_VSX_VECTOR_MODE (mode)
8479 || (type && TREE_CODE (type) == VECTOR_TYPE
8480 && int_size_in_bytes (type) == 16)))
8482 if (named || abi == ABI_V4)
8486 /* Vector parameters to varargs functions under AIX or Darwin
8487 get passed in memory and possibly also in GPRs. */
8488 int align, align_words, n_words;
8489 enum machine_mode part_mode;
8491 /* Vector parameters must be 16-byte aligned. This places them at
8492 2 mod 4 in terms of words in 32-bit mode, since the parameter
8493 save area starts at offset 24 from the stack. In 64-bit mode,
8494 they just have to start on an even word, since the parameter
8495 save area is 16-byte aligned. */
8497 align = (2 - cum->words) & 3;
8499 align = cum->words & 1;
8500 align_words = cum->words + align;
8502 /* Out of registers? Memory, then. */
8503 if (align_words >= GP_ARG_NUM_REG)
8506 if (TARGET_32BIT && TARGET_POWERPC64)
8507 return rs6000_mixed_function_arg (mode, type, align_words);
8509 /* The vector value goes in GPRs. Only the part of the
8510 value in GPRs is reported here. */
8512 n_words = rs6000_arg_size (mode, type);
8513 if (align_words + n_words > GP_ARG_NUM_REG)
8514 /* Fortunately, there are only two possibilities, the value
8515 is either wholly in GPRs or half in GPRs and half not. */
8518 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
8521 else if (TARGET_SPE_ABI && TARGET_SPE
8522 && (SPE_VECTOR_MODE (mode)
8523 || (TARGET_E500_DOUBLE && (mode == DFmode
8526 || mode == TCmode))))
8527 return rs6000_spe_function_arg (cum, mode, type);
8529 else if (abi == ABI_V4)
8531 if (TARGET_HARD_FLOAT && TARGET_FPRS
8532 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8533 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8534 || (mode == TFmode && !TARGET_IEEEQUAD)
8535 || mode == SDmode || mode == DDmode || mode == TDmode))
8537 /* _Decimal128 must use an even/odd register pair. This assumes
8538 that the register number is odd when fregno is odd. */
8539 if (mode == TDmode && (cum->fregno % 2) == 1)
8542 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8543 <= FP_ARG_V4_MAX_REG)
8544 return gen_rtx_REG (mode, cum->fregno);
8550 int n_words = rs6000_arg_size (mode, type);
8551 int gregno = cum->sysv_gregno;
8553 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8554 (r7,r8) or (r9,r10). As does any other 2 word item such
8555 as complex int due to a historical mistake. */
8557 gregno += (1 - gregno) & 1;
8559 /* Multi-reg args are not split between registers and stack. */
8560 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8563 if (TARGET_32BIT && TARGET_POWERPC64)
8564 return rs6000_mixed_function_arg (mode, type,
8565 gregno - GP_ARG_MIN_REG);
8566 return gen_rtx_REG (mode, gregno);
8571 int align_words = rs6000_parm_start (mode, type, cum->words);
8573 /* _Decimal128 must be passed in an even/odd float register pair.
8574 This assumes that the register number is odd when fregno is odd. */
8575 if (mode == TDmode && (cum->fregno % 2) == 1)
8578 if (USE_FP_FOR_ARG_P (cum, mode, type))
8580 rtx rvec[GP_ARG_NUM_REG + 1];
8584 enum machine_mode fmode = mode;
8585 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
8587 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
8589 /* Currently, we only ever need one reg here because complex
8590 doubles are split. */
8591 gcc_assert (cum->fregno == FP_ARG_MAX_REG
8592 && (fmode == TFmode || fmode == TDmode));
8594 /* Long double or _Decimal128 split over regs and memory. */
8595 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
8598 /* Do we also need to pass this arg in the parameter save
8601 && (cum->nargs_prototype <= 0
8602 || (DEFAULT_ABI == ABI_AIX
8604 && align_words >= GP_ARG_NUM_REG)));
8606 if (!needs_psave && mode == fmode)
8607 return gen_rtx_REG (fmode, cum->fregno);
8612 /* Describe the part that goes in gprs or the stack.
8613 This piece must come first, before the fprs. */
8614 if (align_words < GP_ARG_NUM_REG)
8616 unsigned long n_words = rs6000_arg_size (mode, type);
8618 if (align_words + n_words > GP_ARG_NUM_REG
8619 || (TARGET_32BIT && TARGET_POWERPC64))
8621 /* If this is partially on the stack, then we only
8622 include the portion actually in registers here. */
8623 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
8626 if (align_words + n_words > GP_ARG_NUM_REG)
8627 /* Not all of the arg fits in gprs. Say that it
8628 goes in memory too, using a magic NULL_RTX
8629 component. Also see comment in
8630 rs6000_mixed_function_arg for why the normal
8631 function_arg_partial_nregs scheme doesn't work
8633 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
8637 r = gen_rtx_REG (rmode,
8638 GP_ARG_MIN_REG + align_words);
8639 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
8640 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8642 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
8646 /* The whole arg fits in gprs. */
8647 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8648 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8652 /* It's entirely in memory. */
8653 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8656 /* Describe where this piece goes in the fprs. */
8657 r = gen_rtx_REG (fmode, cum->fregno);
8658 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8660 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8662 else if (align_words < GP_ARG_NUM_REG)
8664 if (TARGET_32BIT && TARGET_POWERPC64)
8665 return rs6000_mixed_function_arg (mode, type, align_words);
8667 if (mode == BLKmode)
8670 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8677 /* For an arg passed partly in registers and partly in memory, this is
8678 the number of bytes passed in registers. For args passed entirely in
8679 registers or entirely in memory, zero. When an arg is described by a
8680 PARALLEL, perhaps using more than one register type, this function
8681 returns the number of bytes used by the first element of the PARALLEL. */
8684 rs6000_arg_partial_bytes (cumulative_args_t cum_v, enum machine_mode mode,
8685 tree type, bool named)
8687 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
8691 if (DEFAULT_ABI == ABI_V4)
8694 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
8695 && cum->nargs_prototype >= 0)
8698 /* In this complicated case we just disable the partial_nregs code. */
8699 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8702 align_words = rs6000_parm_start (mode, type, cum->words);
8704 if (USE_FP_FOR_ARG_P (cum, mode, type))
8706 /* If we are passing this arg in the fixed parameter save area
8707 (gprs or memory) as well as fprs, then this function should
8708 return the number of partial bytes passed in the parameter
8709 save area rather than partial bytes passed in fprs. */
8711 && (cum->nargs_prototype <= 0
8712 || (DEFAULT_ABI == ABI_AIX
8714 && align_words >= GP_ARG_NUM_REG)))
8716 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
8717 > FP_ARG_MAX_REG + 1)
8718 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
8719 else if (cum->nargs_prototype >= 0)
8723 if (align_words < GP_ARG_NUM_REG
8724 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
8725 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
8727 if (ret != 0 && TARGET_DEBUG_ARG)
8728 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
8733 /* A C expression that indicates when an argument must be passed by
8734 reference. If nonzero for an argument, a copy of that argument is
8735 made in memory and a pointer to the argument is passed instead of
8736 the argument itself. The pointer is passed in whatever way is
8737 appropriate for passing a pointer to that type.
8739 Under V.4, aggregates and long double are passed by reference.
8741 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
8742 reference unless the AltiVec vector extension ABI is in force.
8744 As an extension to all ABIs, variable sized types are passed by
8748 rs6000_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED,
8749 enum machine_mode mode, const_tree type,
8750 bool named ATTRIBUTE_UNUSED)
8752 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
8754 if (TARGET_DEBUG_ARG)
8755 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
8762 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
8764 if (TARGET_DEBUG_ARG)
8765 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
8769 if (int_size_in_bytes (type) < 0)
8771 if (TARGET_DEBUG_ARG)
8772 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
8776 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
8777 modes only exist for GCC vector types if -maltivec. */
8778 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
8780 if (TARGET_DEBUG_ARG)
8781 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
8785 /* Pass synthetic vectors in memory. */
8786 if (TREE_CODE (type) == VECTOR_TYPE
8787 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
8789 static bool warned_for_pass_big_vectors = false;
8790 if (TARGET_DEBUG_ARG)
8791 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
8792 if (!warned_for_pass_big_vectors)
8794 warning (0, "GCC vector passed by reference: "
8795 "non-standard ABI extension with no compatibility guarantee");
8796 warned_for_pass_big_vectors = true;
8805 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
8808 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
8813 for (i = 0; i < nregs; i++)
8815 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
8816 if (reload_completed)
8818 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
8821 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
8822 i * GET_MODE_SIZE (reg_mode));
8825 tem = replace_equiv_address (tem, XEXP (tem, 0));
8829 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
8833 /* Perform any needed actions needed for a function that is receiving a
8834 variable number of arguments.
8838 MODE and TYPE are the mode and type of the current parameter.
8840 PRETEND_SIZE is a variable that should be set to the amount of stack
8841 that must be pushed by the prolog to pretend that our caller pushed
8844 Normally, this macro will push all remaining incoming registers on the
8845 stack and set PRETEND_SIZE to the length of the registers pushed. */
8848 setup_incoming_varargs (cumulative_args_t cum, enum machine_mode mode,
8849 tree type, int *pretend_size ATTRIBUTE_UNUSED,
8852 CUMULATIVE_ARGS next_cum;
8853 int reg_size = TARGET_32BIT ? 4 : 8;
8854 rtx save_area = NULL_RTX, mem;
8855 int first_reg_offset;
8858 /* Skip the last named argument. */
8859 next_cum = *get_cumulative_args (cum);
8860 rs6000_function_arg_advance_1 (&next_cum, mode, type, true, 0);
8862 if (DEFAULT_ABI == ABI_V4)
8864 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
8868 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
8869 HOST_WIDE_INT offset = 0;
8871 /* Try to optimize the size of the varargs save area.
8872 The ABI requires that ap.reg_save_area is doubleword
8873 aligned, but we don't need to allocate space for all
8874 the bytes, only those to which we actually will save
8876 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
8877 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
8878 if (TARGET_HARD_FLOAT && TARGET_FPRS
8879 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8880 && cfun->va_list_fpr_size)
8883 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
8884 * UNITS_PER_FP_WORD;
8885 if (cfun->va_list_fpr_size
8886 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8887 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
8889 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8890 * UNITS_PER_FP_WORD;
8894 offset = -((first_reg_offset * reg_size) & ~7);
8895 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
8897 gpr_reg_num = cfun->va_list_gpr_size;
8898 if (reg_size == 4 && (first_reg_offset & 1))
8901 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
8904 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
8906 - (int) (GP_ARG_NUM_REG * reg_size);
8908 if (gpr_size + fpr_size)
8911 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
8912 gcc_assert (GET_CODE (reg_save_area) == MEM);
8913 reg_save_area = XEXP (reg_save_area, 0);
8914 if (GET_CODE (reg_save_area) == PLUS)
8916 gcc_assert (XEXP (reg_save_area, 0)
8917 == virtual_stack_vars_rtx);
8918 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
8919 offset += INTVAL (XEXP (reg_save_area, 1));
8922 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
8925 cfun->machine->varargs_save_offset = offset;
8926 save_area = plus_constant (virtual_stack_vars_rtx, offset);
8931 first_reg_offset = next_cum.words;
8932 save_area = virtual_incoming_args_rtx;
8934 if (targetm.calls.must_pass_in_stack (mode, type))
8935 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
8938 set = get_varargs_alias_set ();
8939 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
8940 && cfun->va_list_gpr_size)
8942 int nregs = GP_ARG_NUM_REG - first_reg_offset;
8944 if (va_list_gpr_counter_field)
8946 /* V4 va_list_gpr_size counts number of registers needed. */
8947 if (nregs > cfun->va_list_gpr_size)
8948 nregs = cfun->va_list_gpr_size;
8952 /* char * va_list instead counts number of bytes needed. */
8953 if (nregs > cfun->va_list_gpr_size / reg_size)
8954 nregs = cfun->va_list_gpr_size / reg_size;
8957 mem = gen_rtx_MEM (BLKmode,
8958 plus_constant (save_area,
8959 first_reg_offset * reg_size));
8960 MEM_NOTRAP_P (mem) = 1;
8961 set_mem_alias_set (mem, set);
8962 set_mem_align (mem, BITS_PER_WORD);
8964 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
8968 /* Save FP registers if needed. */
8969 if (DEFAULT_ABI == ABI_V4
8970 && TARGET_HARD_FLOAT && TARGET_FPRS
8972 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8973 && cfun->va_list_fpr_size)
8975 int fregno = next_cum.fregno, nregs;
8976 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
8977 rtx lab = gen_label_rtx ();
8978 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
8979 * UNITS_PER_FP_WORD);
8982 (gen_rtx_SET (VOIDmode,
8984 gen_rtx_IF_THEN_ELSE (VOIDmode,
8985 gen_rtx_NE (VOIDmode, cr1,
8987 gen_rtx_LABEL_REF (VOIDmode, lab),
8991 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
8992 fregno++, off += UNITS_PER_FP_WORD, nregs++)
8994 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8996 plus_constant (save_area, off));
8997 MEM_NOTRAP_P (mem) = 1;
8998 set_mem_alias_set (mem, set);
8999 set_mem_align (mem, GET_MODE_ALIGNMENT (
9000 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9001 ? DFmode : SFmode));
9002 emit_move_insn (mem, gen_rtx_REG (
9003 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9004 ? DFmode : SFmode, fregno));
9011 /* Create the va_list data type. */
9014 rs6000_build_builtin_va_list (void)
9016 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
9018 /* For AIX, prefer 'char *' because that's what the system
9019 header files like. */
9020 if (DEFAULT_ABI != ABI_V4)
9021 return build_pointer_type (char_type_node);
9023 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
9024 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
9025 get_identifier ("__va_list_tag"), record);
9027 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
9028 unsigned_char_type_node);
9029 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
9030 unsigned_char_type_node);
9031 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
9033 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9034 get_identifier ("reserved"), short_unsigned_type_node);
9035 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9036 get_identifier ("overflow_arg_area"),
9038 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9039 get_identifier ("reg_save_area"),
9042 va_list_gpr_counter_field = f_gpr;
9043 va_list_fpr_counter_field = f_fpr;
9045 DECL_FIELD_CONTEXT (f_gpr) = record;
9046 DECL_FIELD_CONTEXT (f_fpr) = record;
9047 DECL_FIELD_CONTEXT (f_res) = record;
9048 DECL_FIELD_CONTEXT (f_ovf) = record;
9049 DECL_FIELD_CONTEXT (f_sav) = record;
9051 TYPE_STUB_DECL (record) = type_decl;
9052 TYPE_NAME (record) = type_decl;
9053 TYPE_FIELDS (record) = f_gpr;
9054 DECL_CHAIN (f_gpr) = f_fpr;
9055 DECL_CHAIN (f_fpr) = f_res;
9056 DECL_CHAIN (f_res) = f_ovf;
9057 DECL_CHAIN (f_ovf) = f_sav;
9059 layout_type (record);
9061 /* The correct type is an array type of one element. */
9062 return build_array_type (record, build_index_type (size_zero_node));
9065 /* Implement va_start. */
9068 rs6000_va_start (tree valist, rtx nextarg)
9070 HOST_WIDE_INT words, n_gpr, n_fpr;
9071 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9072 tree gpr, fpr, ovf, sav, t;
9074 /* Only SVR4 needs something special. */
9075 if (DEFAULT_ABI != ABI_V4)
9077 std_expand_builtin_va_start (valist, nextarg);
9081 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9082 f_fpr = DECL_CHAIN (f_gpr);
9083 f_res = DECL_CHAIN (f_fpr);
9084 f_ovf = DECL_CHAIN (f_res);
9085 f_sav = DECL_CHAIN (f_ovf);
9087 valist = build_simple_mem_ref (valist);
9088 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9089 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9091 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9093 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9096 /* Count number of gp and fp argument registers used. */
9097 words = crtl->args.info.words;
9098 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
9100 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
9103 if (TARGET_DEBUG_ARG)
9104 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
9105 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
9106 words, n_gpr, n_fpr);
9108 if (cfun->va_list_gpr_size)
9110 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
9111 build_int_cst (NULL_TREE, n_gpr));
9112 TREE_SIDE_EFFECTS (t) = 1;
9113 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9116 if (cfun->va_list_fpr_size)
9118 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
9119 build_int_cst (NULL_TREE, n_fpr));
9120 TREE_SIDE_EFFECTS (t) = 1;
9121 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9123 #ifdef HAVE_AS_GNU_ATTRIBUTE
9124 if (call_ABI_of_interest (cfun->decl))
9125 rs6000_passes_float = true;
9129 /* Find the overflow area. */
9130 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
9132 t = fold_build_pointer_plus_hwi (t, words * UNITS_PER_WORD);
9133 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
9134 TREE_SIDE_EFFECTS (t) = 1;
9135 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9137 /* If there were no va_arg invocations, don't set up the register
9139 if (!cfun->va_list_gpr_size
9140 && !cfun->va_list_fpr_size
9141 && n_gpr < GP_ARG_NUM_REG
9142 && n_fpr < FP_ARG_V4_MAX_REG)
9145 /* Find the register save area. */
9146 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
9147 if (cfun->machine->varargs_save_offset)
9148 t = fold_build_pointer_plus_hwi (t, cfun->machine->varargs_save_offset);
9149 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
9150 TREE_SIDE_EFFECTS (t) = 1;
9151 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9154 /* Implement va_arg. */
9157 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
9160 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9161 tree gpr, fpr, ovf, sav, reg, t, u;
9162 int size, rsize, n_reg, sav_ofs, sav_scale;
9163 tree lab_false, lab_over, addr;
9165 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
9169 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
9171 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
9172 return build_va_arg_indirect_ref (t);
9175 /* We need to deal with the fact that the darwin ppc64 ABI is defined by an
9176 earlier version of gcc, with the property that it always applied alignment
9177 adjustments to the va-args (even for zero-sized types). The cheapest way
9178 to deal with this is to replicate the effect of the part of
9179 std_gimplify_va_arg_expr that carries out the align adjust, for the case
9181 We don't need to check for pass-by-reference because of the test above.
9182 We can return a simplifed answer, since we know there's no offset to add. */
9185 && rs6000_darwin64_abi
9186 && integer_zerop (TYPE_SIZE (type)))
9188 unsigned HOST_WIDE_INT align, boundary;
9189 tree valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
9190 align = PARM_BOUNDARY / BITS_PER_UNIT;
9191 boundary = rs6000_function_arg_boundary (TYPE_MODE (type), type);
9192 if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
9193 boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
9194 boundary /= BITS_PER_UNIT;
9195 if (boundary > align)
9198 /* This updates arg ptr by the amount that would be necessary
9199 to align the zero-sized (but not zero-alignment) item. */
9200 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9201 fold_build_pointer_plus_hwi (valist_tmp, boundary - 1));
9202 gimplify_and_add (t, pre_p);
9204 t = fold_convert (sizetype, valist_tmp);
9205 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9206 fold_convert (TREE_TYPE (valist),
9207 fold_build2 (BIT_AND_EXPR, sizetype, t,
9208 size_int (-boundary))));
9209 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
9210 gimplify_and_add (t, pre_p);
9212 /* Since it is zero-sized there's no increment for the item itself. */
9213 valist_tmp = fold_convert (build_pointer_type (type), valist_tmp);
9214 return build_va_arg_indirect_ref (valist_tmp);
9217 if (DEFAULT_ABI != ABI_V4)
9219 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
9221 tree elem_type = TREE_TYPE (type);
9222 enum machine_mode elem_mode = TYPE_MODE (elem_type);
9223 int elem_size = GET_MODE_SIZE (elem_mode);
9225 if (elem_size < UNITS_PER_WORD)
9227 tree real_part, imag_part;
9228 gimple_seq post = NULL;
9230 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9232 /* Copy the value into a temporary, lest the formal temporary
9233 be reused out from under us. */
9234 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
9235 gimple_seq_add_seq (pre_p, post);
9237 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9240 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
9244 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
9247 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9248 f_fpr = DECL_CHAIN (f_gpr);
9249 f_res = DECL_CHAIN (f_fpr);
9250 f_ovf = DECL_CHAIN (f_res);
9251 f_sav = DECL_CHAIN (f_ovf);
9253 valist = build_va_arg_indirect_ref (valist);
9254 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9255 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9257 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9259 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9262 size = int_size_in_bytes (type);
9263 rsize = (size + 3) / 4;
9266 if (TARGET_HARD_FLOAT && TARGET_FPRS
9267 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
9268 || (TARGET_DOUBLE_FLOAT
9269 && (TYPE_MODE (type) == DFmode
9270 || TYPE_MODE (type) == TFmode
9271 || TYPE_MODE (type) == SDmode
9272 || TYPE_MODE (type) == DDmode
9273 || TYPE_MODE (type) == TDmode))))
9275 /* FP args go in FP registers, if present. */
9277 n_reg = (size + 7) / 8;
9278 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
9279 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
9280 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
9285 /* Otherwise into GP registers. */
9294 /* Pull the value out of the saved registers.... */
9297 addr = create_tmp_var (ptr_type_node, "addr");
9299 /* AltiVec vectors never go in registers when -mabi=altivec. */
9300 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
9304 lab_false = create_artificial_label (input_location);
9305 lab_over = create_artificial_label (input_location);
9307 /* Long long and SPE vectors are aligned in the registers.
9308 As are any other 2 gpr item such as complex int due to a
9309 historical mistake. */
9311 if (n_reg == 2 && reg == gpr)
9314 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9315 build_int_cst (TREE_TYPE (reg), n_reg - 1));
9316 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
9317 unshare_expr (reg), u);
9319 /* _Decimal128 is passed in even/odd fpr pairs; the stored
9320 reg number is 0 for f1, so we want to make it odd. */
9321 else if (reg == fpr && TYPE_MODE (type) == TDmode)
9323 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9324 build_int_cst (TREE_TYPE (reg), 1));
9325 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
9328 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
9329 t = build2 (GE_EXPR, boolean_type_node, u, t);
9330 u = build1 (GOTO_EXPR, void_type_node, lab_false);
9331 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
9332 gimplify_and_add (t, pre_p);
9336 t = fold_build_pointer_plus_hwi (sav, sav_ofs);
9338 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9339 build_int_cst (TREE_TYPE (reg), n_reg));
9340 u = fold_convert (sizetype, u);
9341 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
9342 t = fold_build_pointer_plus (t, u);
9344 /* _Decimal32 varargs are located in the second word of the 64-bit
9345 FP register for 32-bit binaries. */
9346 if (!TARGET_POWERPC64
9347 && TARGET_HARD_FLOAT && TARGET_FPRS
9348 && TYPE_MODE (type) == SDmode)
9349 t = fold_build_pointer_plus_hwi (t, size);
9351 gimplify_assign (addr, t, pre_p);
9353 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
9355 stmt = gimple_build_label (lab_false);
9356 gimple_seq_add_stmt (pre_p, stmt);
9358 if ((n_reg == 2 && !regalign) || n_reg > 2)
9360 /* Ensure that we don't find any more args in regs.
9361 Alignment has taken care of for special cases. */
9362 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
9366 /* ... otherwise out of the overflow area. */
9368 /* Care for on-stack alignment if needed. */
9372 t = fold_build_pointer_plus_hwi (t, align - 1);
9373 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
9374 build_int_cst (TREE_TYPE (t), -align));
9376 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
9378 gimplify_assign (unshare_expr (addr), t, pre_p);
9380 t = fold_build_pointer_plus_hwi (t, size);
9381 gimplify_assign (unshare_expr (ovf), t, pre_p);
9385 stmt = gimple_build_label (lab_over);
9386 gimple_seq_add_stmt (pre_p, stmt);
9389 if (STRICT_ALIGNMENT
9390 && (TYPE_ALIGN (type)
9391 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
9393 /* The value (of type complex double, for example) may not be
9394 aligned in memory in the saved registers, so copy via a
9395 temporary. (This is the same code as used for SPARC.) */
9396 tree tmp = create_tmp_var (type, "va_arg_tmp");
9397 tree dest_addr = build_fold_addr_expr (tmp);
9399 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
9400 3, dest_addr, addr, size_int (rsize * 4));
9402 gimplify_and_add (copy, pre_p);
9406 addr = fold_convert (ptrtype, addr);
9407 return build_va_arg_indirect_ref (addr);
9413 def_builtin (int mask, const char *name, tree type, int code)
9415 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
9418 if (rs6000_builtin_decls[code])
9419 fatal_error ("internal error: builtin function to %s already processed",
9422 rs6000_builtin_decls[code] = t =
9423 add_builtin_function (name, type, code, BUILT_IN_MD,
9426 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT);
9427 switch (builtin_classify[code])
9432 /* assume builtin can do anything. */
9433 case RS6000_BTC_MISC:
9436 /* const function, function only depends on the inputs. */
9437 case RS6000_BTC_CONST:
9438 TREE_READONLY (t) = 1;
9439 TREE_NOTHROW (t) = 1;
9442 /* pure function, function can read global memory. */
9443 case RS6000_BTC_PURE:
9444 DECL_PURE_P (t) = 1;
9445 TREE_NOTHROW (t) = 1;
9448 /* Function is a math function. If rounding mode is on, then treat
9449 the function as not reading global memory, but it can have
9450 arbitrary side effects. If it is off, then assume the function is
9451 a const function. This mimics the ATTR_MATHFN_FPROUNDING
9452 attribute in builtin-attribute.def that is used for the math
9454 case RS6000_BTC_FP_PURE:
9455 TREE_NOTHROW (t) = 1;
9456 if (flag_rounding_math)
9458 DECL_PURE_P (t) = 1;
9459 DECL_IS_NOVOPS (t) = 1;
9462 TREE_READONLY (t) = 1;
9468 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
9470 static const struct builtin_description bdesc_3arg[] =
9472 { MASK_ALTIVEC, CODE_FOR_fmav4sf4, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
9473 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
9474 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
9475 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
9476 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
9477 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
9478 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
9479 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
9480 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
9481 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
9482 { MASK_ALTIVEC, CODE_FOR_nfmsv4sf4, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
9483 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
9484 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
9485 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
9486 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
9487 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
9488 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
9489 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
9490 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
9491 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
9492 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
9493 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
9494 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
9495 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
9496 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
9497 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
9498 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
9499 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
9500 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
9501 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
9502 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
9503 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
9504 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
9505 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
9506 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
9508 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
9509 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
9510 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
9511 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
9512 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
9513 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
9514 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
9515 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
9516 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
9517 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
9518 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
9519 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
9520 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
9521 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
9522 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
9524 { MASK_VSX, CODE_FOR_fmav2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
9525 { MASK_VSX, CODE_FOR_fmsv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
9526 { MASK_VSX, CODE_FOR_nfmav2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
9527 { MASK_VSX, CODE_FOR_nfmsv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
9529 { MASK_VSX, CODE_FOR_fmav4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
9530 { MASK_VSX, CODE_FOR_fmsv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
9531 { MASK_VSX, CODE_FOR_nfmav4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
9532 { MASK_VSX, CODE_FOR_nfmsv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
9534 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
9535 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
9537 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
9538 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
9539 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
9540 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
9541 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
9542 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
9543 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
9544 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
9545 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
9546 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
9548 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
9549 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
9550 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
9551 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
9552 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
9553 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
9554 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
9555 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
9556 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
9557 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
9559 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
9560 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
9561 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
9562 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
9563 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
9564 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
9565 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
9566 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
9567 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
9569 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
9570 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
9571 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
9572 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
9573 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
9574 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
9575 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
9577 { 0, CODE_FOR_fmsv2sf4, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
9578 { 0, CODE_FOR_fmav2sf4, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
9579 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
9580 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
9581 { 0, CODE_FOR_nfmsv2sf4, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
9582 { 0, CODE_FOR_nfmav2sf4, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
9583 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
9584 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
9585 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
9588 /* DST operations: void foo (void *, const int, const char). */
9590 static const struct builtin_description bdesc_dst[] =
9592 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
9593 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
9594 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
9595 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
9597 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
9598 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
9599 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
9600 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
9603 /* Simple binary operations: VECc = foo (VECa, VECb). */
9605 static struct builtin_description bdesc_2arg[] =
9607 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
9608 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
9609 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
9610 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
9611 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
9612 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
9613 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
9614 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
9615 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
9616 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
9617 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
9618 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
9619 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
9620 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
9621 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
9622 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
9623 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
9624 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
9625 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
9626 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
9627 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
9628 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
9629 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
9630 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
9631 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
9632 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
9633 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
9634 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
9635 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
9636 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
9637 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
9638 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
9639 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
9640 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
9641 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
9642 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
9643 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
9644 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
9645 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
9646 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
9647 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
9648 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
9649 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
9650 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
9651 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
9652 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
9653 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
9654 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
9655 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
9656 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
9657 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
9658 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
9659 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
9660 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
9661 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
9662 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
9663 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
9664 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
9665 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
9666 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
9667 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
9668 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
9669 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
9670 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
9671 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
9672 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
9673 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
9674 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
9675 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
9676 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
9677 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
9678 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
9679 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
9680 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
9681 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
9682 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
9683 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
9684 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
9685 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
9686 { MASK_ALTIVEC, CODE_FOR_recipv4sf3, "__builtin_altivec_vrecipdivfp", ALTIVEC_BUILTIN_VRECIPFP },
9687 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
9688 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
9689 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
9690 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
9691 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
9692 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
9693 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
9694 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
9695 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
9696 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
9697 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
9698 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
9699 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
9700 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
9701 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
9702 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
9703 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
9704 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
9705 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
9706 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
9707 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
9708 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
9709 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
9710 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
9711 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
9712 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
9713 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
9714 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
9715 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
9716 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
9717 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
9718 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
9719 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
9720 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
9721 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
9722 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
9723 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
9725 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
9726 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
9727 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
9728 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
9729 { MASK_VSX, CODE_FOR_recipv2df3, "__builtin_vsx_xvrecipdivdp", VSX_BUILTIN_RECIP_V2DF },
9730 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
9731 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
9732 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
9733 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
9734 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
9735 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
9736 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
9738 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
9739 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
9740 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
9741 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
9742 { MASK_VSX, CODE_FOR_recipv4sf3, "__builtin_vsx_xvrecipdivsp", VSX_BUILTIN_RECIP_V4SF },
9743 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
9744 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
9745 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
9746 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
9747 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
9748 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
9749 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
9751 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
9752 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
9753 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
9754 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
9755 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
9756 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
9758 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
9759 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
9760 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
9761 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
9762 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
9763 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
9764 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
9765 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
9766 { MASK_VSX, CODE_FOR_vec_interleave_lowv2df, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF },
9767 { MASK_VSX, CODE_FOR_vec_interleave_lowv2di, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI },
9768 { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF },
9769 { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI },
9771 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
9772 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
9773 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
9774 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
9775 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
9776 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
9777 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
9778 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
9779 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
9780 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
9781 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
9782 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
9783 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
9784 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
9785 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
9786 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
9787 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
9788 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
9789 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
9790 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
9791 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
9792 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
9793 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
9794 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
9795 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
9796 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
9797 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
9798 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
9799 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
9800 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
9801 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
9802 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
9803 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
9804 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
9805 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
9806 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
9807 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
9808 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
9809 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
9810 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
9811 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
9812 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
9813 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
9814 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
9815 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
9816 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
9817 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
9818 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
9819 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
9820 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
9821 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
9822 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
9823 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
9824 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
9825 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
9826 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
9827 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
9828 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
9829 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
9830 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
9831 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
9832 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
9833 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
9834 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
9835 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
9836 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
9837 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
9838 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
9839 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
9840 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
9841 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
9842 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
9843 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
9844 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
9845 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
9846 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
9847 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
9848 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
9849 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
9850 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
9851 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
9852 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
9853 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
9854 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
9855 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
9856 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
9857 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
9858 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
9859 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_recipdiv", ALTIVEC_BUILTIN_VEC_RECIP },
9860 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
9861 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
9862 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
9863 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
9864 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
9865 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
9866 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
9867 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
9868 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
9869 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
9870 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
9871 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
9872 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
9873 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
9874 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
9875 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
9876 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
9877 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
9878 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
9879 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
9880 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
9881 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
9882 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
9883 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
9884 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
9885 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
9886 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
9887 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
9888 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
9889 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
9890 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
9891 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
9892 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
9893 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
9894 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
9895 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
9896 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
9897 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
9898 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
9899 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
9901 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
9902 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
9904 { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
9905 { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
9906 { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
9907 { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
9908 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
9909 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
9910 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
9911 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
9912 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
9913 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
9915 /* Place holder, leave as first spe builtin. */
9916 { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
9917 { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
9918 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
9919 { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
9920 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
9921 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
9922 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
9923 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
9924 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
9925 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
9926 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
9927 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
9928 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
9929 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
9930 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
9931 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
9932 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
9933 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
9934 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
9935 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
9936 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
9937 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
9938 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
9939 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
9940 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
9941 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
9942 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
9943 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
9944 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
9945 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
9946 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
9947 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
9948 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
9949 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
9950 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
9951 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
9952 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
9953 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
9954 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
9955 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
9956 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
9957 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
9958 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
9959 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
9960 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
9961 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
9962 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
9963 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
9964 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
9965 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
9966 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
9967 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
9968 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
9969 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
9970 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
9971 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
9972 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
9973 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
9974 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
9975 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
9976 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
9977 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
9978 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
9979 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
9980 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
9981 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
9982 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
9983 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
9984 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
9985 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
9986 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
9987 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
9988 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
9989 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
9990 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
9991 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
9992 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
9993 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
9994 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
9995 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
9996 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
9997 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
9998 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
9999 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
10000 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
10001 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
10002 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
10003 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
10004 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
10005 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
10006 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
10007 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
10008 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
10009 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
10010 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
10011 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
10012 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
10013 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
10014 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
10015 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
10016 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
10017 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
10018 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
10019 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
10020 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
10021 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
10022 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
10023 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
10024 { 0, CODE_FOR_subv2si3, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
10026 /* SPE binary operations expecting a 5-bit unsigned literal. */
10027 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
10029 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
10030 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
10031 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
10032 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
10033 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
10034 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
10035 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
10036 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
10037 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
10038 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
10039 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
10040 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
10041 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
10042 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
10043 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
10044 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
10045 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
10046 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
10047 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
10048 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
10049 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
10050 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
10051 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
10052 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
10053 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
10054 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
10056 /* Place-holder. Leave as last binary SPE builtin. */
10057 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
10060 /* AltiVec predicates. */
10062 struct builtin_description_predicates
10064 const unsigned int mask;
10065 const enum insn_code icode;
10066 const char *const name;
10067 const enum rs6000_builtins code;
10070 static const struct builtin_description_predicates bdesc_altivec_preds[] =
10072 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
10073 ALTIVEC_BUILTIN_VCMPBFP_P },
10074 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
10075 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
10076 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
10077 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
10078 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
10079 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
10080 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
10081 ALTIVEC_BUILTIN_VCMPEQUW_P },
10082 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
10083 ALTIVEC_BUILTIN_VCMPGTSW_P },
10084 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
10085 ALTIVEC_BUILTIN_VCMPGTUW_P },
10086 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
10087 ALTIVEC_BUILTIN_VCMPEQUH_P },
10088 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
10089 ALTIVEC_BUILTIN_VCMPGTSH_P },
10090 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
10091 ALTIVEC_BUILTIN_VCMPGTUH_P },
10092 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
10093 ALTIVEC_BUILTIN_VCMPEQUB_P },
10094 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
10095 ALTIVEC_BUILTIN_VCMPGTSB_P },
10096 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
10097 ALTIVEC_BUILTIN_VCMPGTUB_P },
10099 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
10100 VSX_BUILTIN_XVCMPEQSP_P },
10101 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
10102 VSX_BUILTIN_XVCMPGESP_P },
10103 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
10104 VSX_BUILTIN_XVCMPGTSP_P },
10105 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
10106 VSX_BUILTIN_XVCMPEQDP_P },
10107 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
10108 VSX_BUILTIN_XVCMPGEDP_P },
10109 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
10110 VSX_BUILTIN_XVCMPGTDP_P },
10112 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
10113 ALTIVEC_BUILTIN_VCMPEQ_P },
10114 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
10115 ALTIVEC_BUILTIN_VCMPGT_P },
10116 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
10117 ALTIVEC_BUILTIN_VCMPGE_P }
10120 /* SPE predicates. */
10121 static struct builtin_description bdesc_spe_predicates[] =
10123 /* Place-holder. Leave as first. */
10124 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
10125 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
10126 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
10127 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
10128 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
10129 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
10130 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
10131 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
10132 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
10133 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
10134 /* Place-holder. Leave as last. */
10135 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
10138 /* SPE evsel predicates. */
10139 static struct builtin_description bdesc_spe_evsel[] =
10141 /* Place-holder. Leave as first. */
10142 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
10143 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
10144 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
10145 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
10146 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
10147 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
10148 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
10149 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
10150 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
10151 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
10152 /* Place-holder. Leave as last. */
10153 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
10156 /* PAIRED predicates. */
10157 static const struct builtin_description bdesc_paired_preds[] =
10159 /* Place-holder. Leave as first. */
10160 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
10161 /* Place-holder. Leave as last. */
10162 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
10165 /* ABS* operations. */
10167 static const struct builtin_description bdesc_abs[] =
10169 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
10170 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
10171 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
10172 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
10173 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
10174 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
10175 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
10176 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
10177 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
10178 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
10179 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
10182 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
10185 static struct builtin_description bdesc_1arg[] =
10187 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
10188 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
10189 { MASK_ALTIVEC, CODE_FOR_rev4sf2, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
10190 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
10191 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
10192 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
10193 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
10194 { MASK_ALTIVEC, CODE_FOR_rsqrtv4sf2, "__builtin_altivec_vrsqrtfp", ALTIVEC_BUILTIN_VRSQRTFP },
10195 { MASK_ALTIVEC, CODE_FOR_rsqrtev4sf2, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
10196 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
10197 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
10198 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
10199 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
10200 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
10201 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
10202 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
10203 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
10204 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
10206 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
10207 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
10208 { MASK_VSX, CODE_FOR_rsqrtv2df2, "__builtin_vsx_xvrsqrtdp", VSX_BUILTIN_VEC_RSQRT_V2DF },
10209 { MASK_VSX, CODE_FOR_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
10210 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
10211 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
10212 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
10214 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
10215 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
10216 { MASK_VSX, CODE_FOR_rsqrtv4sf2, "__builtin_vsx_xvrsqrtsp", VSX_BUILTIN_VEC_RSQRT_V4SF },
10217 { MASK_VSX, CODE_FOR_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
10218 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
10219 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
10220 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
10222 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
10223 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
10224 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
10225 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
10226 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
10227 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
10229 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
10230 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
10231 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
10232 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
10233 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
10234 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
10236 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
10237 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
10238 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
10239 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
10241 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
10242 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
10243 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
10244 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
10245 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
10246 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
10247 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
10248 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
10249 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
10251 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
10252 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
10253 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
10254 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
10255 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
10256 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
10257 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
10258 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
10259 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
10261 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
10262 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
10263 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
10264 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
10265 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
10267 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
10268 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
10269 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
10270 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
10271 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
10272 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
10273 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
10274 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
10275 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
10276 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrt", ALTIVEC_BUILTIN_VEC_RSQRT },
10277 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
10278 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
10279 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
10280 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
10281 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
10282 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
10283 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
10284 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
10285 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
10286 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
10288 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
10289 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
10290 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
10292 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
10293 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
10294 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
10295 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
10297 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
10298 end with SPE_BUILTIN_EVSUBFUSIAAW. */
10299 { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
10300 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
10301 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
10302 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
10303 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
10304 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
10305 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
10306 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
10307 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
10308 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
10309 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
10310 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
10311 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
10312 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
10313 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
10314 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
10315 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
10316 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
10317 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
10318 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
10319 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
10320 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
10321 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
10322 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
10323 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
10324 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
10325 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
10326 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
10328 /* Place-holder. Leave as last unary SPE builtin. */
10329 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
10331 { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
10332 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
10333 { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
10334 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
10335 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
10339 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
10342 tree arg0 = CALL_EXPR_ARG (exp, 0);
10343 rtx op0 = expand_normal (arg0);
10344 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10345 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10347 if (icode == CODE_FOR_nothing)
10348 /* Builtin not supported on this processor. */
10351 /* If we got invalid arguments bail out before generating bad rtl. */
10352 if (arg0 == error_mark_node)
10355 if (icode == CODE_FOR_altivec_vspltisb
10356 || icode == CODE_FOR_altivec_vspltish
10357 || icode == CODE_FOR_altivec_vspltisw
10358 || icode == CODE_FOR_spe_evsplatfi
10359 || icode == CODE_FOR_spe_evsplati)
10361 /* Only allow 5-bit *signed* literals. */
10362 if (GET_CODE (op0) != CONST_INT
10363 || INTVAL (op0) > 15
10364 || INTVAL (op0) < -16)
10366 error ("argument 1 must be a 5-bit signed literal");
10372 || GET_MODE (target) != tmode
10373 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10374 target = gen_reg_rtx (tmode);
10376 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10377 op0 = copy_to_mode_reg (mode0, op0);
10379 pat = GEN_FCN (icode) (target, op0);
10388 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
10390 rtx pat, scratch1, scratch2;
10391 tree arg0 = CALL_EXPR_ARG (exp, 0);
10392 rtx op0 = expand_normal (arg0);
10393 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10394 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10396 /* If we have invalid arguments, bail out before generating bad rtl. */
10397 if (arg0 == error_mark_node)
10401 || GET_MODE (target) != tmode
10402 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10403 target = gen_reg_rtx (tmode);
10405 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10406 op0 = copy_to_mode_reg (mode0, op0);
10408 scratch1 = gen_reg_rtx (mode0);
10409 scratch2 = gen_reg_rtx (mode0);
10411 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
10420 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
10423 tree arg0 = CALL_EXPR_ARG (exp, 0);
10424 tree arg1 = CALL_EXPR_ARG (exp, 1);
10425 rtx op0 = expand_normal (arg0);
10426 rtx op1 = expand_normal (arg1);
10427 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10428 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10429 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10431 if (icode == CODE_FOR_nothing)
10432 /* Builtin not supported on this processor. */
10435 /* If we got invalid arguments bail out before generating bad rtl. */
10436 if (arg0 == error_mark_node || arg1 == error_mark_node)
10439 if (icode == CODE_FOR_altivec_vcfux
10440 || icode == CODE_FOR_altivec_vcfsx
10441 || icode == CODE_FOR_altivec_vctsxs
10442 || icode == CODE_FOR_altivec_vctuxs
10443 || icode == CODE_FOR_altivec_vspltb
10444 || icode == CODE_FOR_altivec_vsplth
10445 || icode == CODE_FOR_altivec_vspltw
10446 || icode == CODE_FOR_spe_evaddiw
10447 || icode == CODE_FOR_spe_evldd
10448 || icode == CODE_FOR_spe_evldh
10449 || icode == CODE_FOR_spe_evldw
10450 || icode == CODE_FOR_spe_evlhhesplat
10451 || icode == CODE_FOR_spe_evlhhossplat
10452 || icode == CODE_FOR_spe_evlhhousplat
10453 || icode == CODE_FOR_spe_evlwhe
10454 || icode == CODE_FOR_spe_evlwhos
10455 || icode == CODE_FOR_spe_evlwhou
10456 || icode == CODE_FOR_spe_evlwhsplat
10457 || icode == CODE_FOR_spe_evlwwsplat
10458 || icode == CODE_FOR_spe_evrlwi
10459 || icode == CODE_FOR_spe_evslwi
10460 || icode == CODE_FOR_spe_evsrwis
10461 || icode == CODE_FOR_spe_evsubifw
10462 || icode == CODE_FOR_spe_evsrwiu)
10464 /* Only allow 5-bit unsigned literals. */
10466 if (TREE_CODE (arg1) != INTEGER_CST
10467 || TREE_INT_CST_LOW (arg1) & ~0x1f)
10469 error ("argument 2 must be a 5-bit unsigned literal");
10475 || GET_MODE (target) != tmode
10476 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10477 target = gen_reg_rtx (tmode);
10479 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10480 op0 = copy_to_mode_reg (mode0, op0);
10481 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10482 op1 = copy_to_mode_reg (mode1, op1);
10484 pat = GEN_FCN (icode) (target, op0, op1);
10493 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10496 tree cr6_form = CALL_EXPR_ARG (exp, 0);
10497 tree arg0 = CALL_EXPR_ARG (exp, 1);
10498 tree arg1 = CALL_EXPR_ARG (exp, 2);
10499 rtx op0 = expand_normal (arg0);
10500 rtx op1 = expand_normal (arg1);
10501 enum machine_mode tmode = SImode;
10502 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10503 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10506 if (TREE_CODE (cr6_form) != INTEGER_CST)
10508 error ("argument 1 of __builtin_altivec_predicate must be a constant");
10512 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
10514 gcc_assert (mode0 == mode1);
10516 /* If we have invalid arguments, bail out before generating bad rtl. */
10517 if (arg0 == error_mark_node || arg1 == error_mark_node)
10521 || GET_MODE (target) != tmode
10522 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10523 target = gen_reg_rtx (tmode);
10525 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10526 op0 = copy_to_mode_reg (mode0, op0);
10527 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10528 op1 = copy_to_mode_reg (mode1, op1);
10530 scratch = gen_reg_rtx (mode0);
10532 pat = GEN_FCN (icode) (scratch, op0, op1);
10537 /* The vec_any* and vec_all* predicates use the same opcodes for two
10538 different operations, but the bits in CR6 will be different
10539 depending on what information we want. So we have to play tricks
10540 with CR6 to get the right bits out.
10542 If you think this is disgusting, look at the specs for the
10543 AltiVec predicates. */
10545 switch (cr6_form_int)
10548 emit_insn (gen_cr6_test_for_zero (target));
10551 emit_insn (gen_cr6_test_for_zero_reverse (target));
10554 emit_insn (gen_cr6_test_for_lt (target));
10557 emit_insn (gen_cr6_test_for_lt_reverse (target));
10560 error ("argument 1 of __builtin_altivec_predicate is out of range");
10568 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
10571 tree arg0 = CALL_EXPR_ARG (exp, 0);
10572 tree arg1 = CALL_EXPR_ARG (exp, 1);
10573 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10574 enum machine_mode mode0 = Pmode;
10575 enum machine_mode mode1 = Pmode;
10576 rtx op0 = expand_normal (arg0);
10577 rtx op1 = expand_normal (arg1);
10579 if (icode == CODE_FOR_nothing)
10580 /* Builtin not supported on this processor. */
10583 /* If we got invalid arguments bail out before generating bad rtl. */
10584 if (arg0 == error_mark_node || arg1 == error_mark_node)
10588 || GET_MODE (target) != tmode
10589 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10590 target = gen_reg_rtx (tmode);
10592 op1 = copy_to_mode_reg (mode1, op1);
10594 if (op0 == const0_rtx)
10596 addr = gen_rtx_MEM (tmode, op1);
10600 op0 = copy_to_mode_reg (mode0, op0);
10601 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
10604 pat = GEN_FCN (icode) (target, addr);
10614 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
10617 tree arg0 = CALL_EXPR_ARG (exp, 0);
10618 tree arg1 = CALL_EXPR_ARG (exp, 1);
10619 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10620 enum machine_mode mode0 = Pmode;
10621 enum machine_mode mode1 = Pmode;
10622 rtx op0 = expand_normal (arg0);
10623 rtx op1 = expand_normal (arg1);
10625 if (icode == CODE_FOR_nothing)
10626 /* Builtin not supported on this processor. */
10629 /* If we got invalid arguments bail out before generating bad rtl. */
10630 if (arg0 == error_mark_node || arg1 == error_mark_node)
10634 || GET_MODE (target) != tmode
10635 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10636 target = gen_reg_rtx (tmode);
10638 op1 = copy_to_mode_reg (mode1, op1);
10640 if (op0 == const0_rtx)
10642 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
10646 op0 = copy_to_mode_reg (mode0, op0);
10647 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
10650 pat = GEN_FCN (icode) (target, addr);
10660 spe_expand_stv_builtin (enum insn_code icode, tree exp)
10662 tree arg0 = CALL_EXPR_ARG (exp, 0);
10663 tree arg1 = CALL_EXPR_ARG (exp, 1);
10664 tree arg2 = CALL_EXPR_ARG (exp, 2);
10665 rtx op0 = expand_normal (arg0);
10666 rtx op1 = expand_normal (arg1);
10667 rtx op2 = expand_normal (arg2);
10669 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
10670 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
10671 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
10673 /* Invalid arguments. Bail before doing anything stoopid! */
10674 if (arg0 == error_mark_node
10675 || arg1 == error_mark_node
10676 || arg2 == error_mark_node)
10679 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
10680 op0 = copy_to_mode_reg (mode2, op0);
10681 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
10682 op1 = copy_to_mode_reg (mode0, op1);
10683 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
10684 op2 = copy_to_mode_reg (mode1, op2);
10686 pat = GEN_FCN (icode) (op1, op2, op0);
10693 paired_expand_stv_builtin (enum insn_code icode, tree exp)
10695 tree arg0 = CALL_EXPR_ARG (exp, 0);
10696 tree arg1 = CALL_EXPR_ARG (exp, 1);
10697 tree arg2 = CALL_EXPR_ARG (exp, 2);
10698 rtx op0 = expand_normal (arg0);
10699 rtx op1 = expand_normal (arg1);
10700 rtx op2 = expand_normal (arg2);
10702 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10703 enum machine_mode mode1 = Pmode;
10704 enum machine_mode mode2 = Pmode;
10706 /* Invalid arguments. Bail before doing anything stoopid! */
10707 if (arg0 == error_mark_node
10708 || arg1 == error_mark_node
10709 || arg2 == error_mark_node)
10712 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
10713 op0 = copy_to_mode_reg (tmode, op0);
10715 op2 = copy_to_mode_reg (mode2, op2);
10717 if (op1 == const0_rtx)
10719 addr = gen_rtx_MEM (tmode, op2);
10723 op1 = copy_to_mode_reg (mode1, op1);
10724 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
10727 pat = GEN_FCN (icode) (addr, op0);
10734 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
10736 tree arg0 = CALL_EXPR_ARG (exp, 0);
10737 tree arg1 = CALL_EXPR_ARG (exp, 1);
10738 tree arg2 = CALL_EXPR_ARG (exp, 2);
10739 rtx op0 = expand_normal (arg0);
10740 rtx op1 = expand_normal (arg1);
10741 rtx op2 = expand_normal (arg2);
10743 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10744 enum machine_mode smode = insn_data[icode].operand[1].mode;
10745 enum machine_mode mode1 = Pmode;
10746 enum machine_mode mode2 = Pmode;
10748 /* Invalid arguments. Bail before doing anything stoopid! */
10749 if (arg0 == error_mark_node
10750 || arg1 == error_mark_node
10751 || arg2 == error_mark_node)
10754 if (! (*insn_data[icode].operand[1].predicate) (op0, smode))
10755 op0 = copy_to_mode_reg (smode, op0);
10757 op2 = copy_to_mode_reg (mode2, op2);
10759 if (op1 == const0_rtx)
10761 addr = gen_rtx_MEM (tmode, op2);
10765 op1 = copy_to_mode_reg (mode1, op1);
10766 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
10769 pat = GEN_FCN (icode) (addr, op0);
10776 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
10779 tree arg0 = CALL_EXPR_ARG (exp, 0);
10780 tree arg1 = CALL_EXPR_ARG (exp, 1);
10781 tree arg2 = CALL_EXPR_ARG (exp, 2);
10782 rtx op0 = expand_normal (arg0);
10783 rtx op1 = expand_normal (arg1);
10784 rtx op2 = expand_normal (arg2);
10785 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10786 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10787 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10788 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
10790 if (icode == CODE_FOR_nothing)
10791 /* Builtin not supported on this processor. */
10794 /* If we got invalid arguments bail out before generating bad rtl. */
10795 if (arg0 == error_mark_node
10796 || arg1 == error_mark_node
10797 || arg2 == error_mark_node)
10800 /* Check and prepare argument depending on the instruction code.
10802 Note that a switch statement instead of the sequence of tests
10803 would be incorrect as many of the CODE_FOR values could be
10804 CODE_FOR_nothing and that would yield multiple alternatives
10805 with identical values. We'd never reach here at runtime in
10807 if (icode == CODE_FOR_altivec_vsldoi_v4sf
10808 || icode == CODE_FOR_altivec_vsldoi_v4si
10809 || icode == CODE_FOR_altivec_vsldoi_v8hi
10810 || icode == CODE_FOR_altivec_vsldoi_v16qi)
10812 /* Only allow 4-bit unsigned literals. */
10814 if (TREE_CODE (arg2) != INTEGER_CST
10815 || TREE_INT_CST_LOW (arg2) & ~0xf)
10817 error ("argument 3 must be a 4-bit unsigned literal");
10821 else if (icode == CODE_FOR_vsx_xxpermdi_v2df
10822 || icode == CODE_FOR_vsx_xxpermdi_v2di
10823 || icode == CODE_FOR_vsx_xxsldwi_v16qi
10824 || icode == CODE_FOR_vsx_xxsldwi_v8hi
10825 || icode == CODE_FOR_vsx_xxsldwi_v4si
10826 || icode == CODE_FOR_vsx_xxsldwi_v4sf
10827 || icode == CODE_FOR_vsx_xxsldwi_v2di
10828 || icode == CODE_FOR_vsx_xxsldwi_v2df)
10830 /* Only allow 2-bit unsigned literals. */
10832 if (TREE_CODE (arg2) != INTEGER_CST
10833 || TREE_INT_CST_LOW (arg2) & ~0x3)
10835 error ("argument 3 must be a 2-bit unsigned literal");
10839 else if (icode == CODE_FOR_vsx_set_v2df
10840 || icode == CODE_FOR_vsx_set_v2di)
10842 /* Only allow 1-bit unsigned literals. */
10844 if (TREE_CODE (arg2) != INTEGER_CST
10845 || TREE_INT_CST_LOW (arg2) & ~0x1)
10847 error ("argument 3 must be a 1-bit unsigned literal");
10853 || GET_MODE (target) != tmode
10854 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10855 target = gen_reg_rtx (tmode);
10857 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10858 op0 = copy_to_mode_reg (mode0, op0);
10859 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10860 op1 = copy_to_mode_reg (mode1, op1);
10861 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
10862 op2 = copy_to_mode_reg (mode2, op2);
10864 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
10865 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
10867 pat = GEN_FCN (icode) (target, op0, op1, op2);
10875 /* Expand the lvx builtins. */
10877 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
10879 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10880 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10882 enum machine_mode tmode, mode0;
10884 enum insn_code icode;
10888 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
10889 icode = CODE_FOR_vector_altivec_load_v16qi;
10891 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
10892 icode = CODE_FOR_vector_altivec_load_v8hi;
10894 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
10895 icode = CODE_FOR_vector_altivec_load_v4si;
10897 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
10898 icode = CODE_FOR_vector_altivec_load_v4sf;
10900 case ALTIVEC_BUILTIN_LD_INTERNAL_2df:
10901 icode = CODE_FOR_vector_altivec_load_v2df;
10903 case ALTIVEC_BUILTIN_LD_INTERNAL_2di:
10904 icode = CODE_FOR_vector_altivec_load_v2di;
10907 *expandedp = false;
10913 arg0 = CALL_EXPR_ARG (exp, 0);
10914 op0 = expand_normal (arg0);
10915 tmode = insn_data[icode].operand[0].mode;
10916 mode0 = insn_data[icode].operand[1].mode;
10919 || GET_MODE (target) != tmode
10920 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10921 target = gen_reg_rtx (tmode);
10923 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10924 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10926 pat = GEN_FCN (icode) (target, op0);
10933 /* Expand the stvx builtins. */
10935 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10938 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10939 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10941 enum machine_mode mode0, mode1;
10943 enum insn_code icode;
10947 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
10948 icode = CODE_FOR_vector_altivec_store_v16qi;
10950 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
10951 icode = CODE_FOR_vector_altivec_store_v8hi;
10953 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
10954 icode = CODE_FOR_vector_altivec_store_v4si;
10956 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
10957 icode = CODE_FOR_vector_altivec_store_v4sf;
10959 case ALTIVEC_BUILTIN_ST_INTERNAL_2df:
10960 icode = CODE_FOR_vector_altivec_store_v2df;
10962 case ALTIVEC_BUILTIN_ST_INTERNAL_2di:
10963 icode = CODE_FOR_vector_altivec_store_v2di;
10966 *expandedp = false;
10970 arg0 = CALL_EXPR_ARG (exp, 0);
10971 arg1 = CALL_EXPR_ARG (exp, 1);
10972 op0 = expand_normal (arg0);
10973 op1 = expand_normal (arg1);
10974 mode0 = insn_data[icode].operand[0].mode;
10975 mode1 = insn_data[icode].operand[1].mode;
10977 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10978 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10979 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
10980 op1 = copy_to_mode_reg (mode1, op1);
10982 pat = GEN_FCN (icode) (op0, op1);
10990 /* Expand the dst builtins. */
10992 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10995 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10996 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10997 tree arg0, arg1, arg2;
10998 enum machine_mode mode0, mode1;
10999 rtx pat, op0, op1, op2;
11000 const struct builtin_description *d;
11003 *expandedp = false;
11005 /* Handle DST variants. */
11007 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
11008 if (d->code == fcode)
11010 arg0 = CALL_EXPR_ARG (exp, 0);
11011 arg1 = CALL_EXPR_ARG (exp, 1);
11012 arg2 = CALL_EXPR_ARG (exp, 2);
11013 op0 = expand_normal (arg0);
11014 op1 = expand_normal (arg1);
11015 op2 = expand_normal (arg2);
11016 mode0 = insn_data[d->icode].operand[0].mode;
11017 mode1 = insn_data[d->icode].operand[1].mode;
11019 /* Invalid arguments, bail out before generating bad rtl. */
11020 if (arg0 == error_mark_node
11021 || arg1 == error_mark_node
11022 || arg2 == error_mark_node)
11027 if (TREE_CODE (arg2) != INTEGER_CST
11028 || TREE_INT_CST_LOW (arg2) & ~0x3)
11030 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
11034 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
11035 op0 = copy_to_mode_reg (Pmode, op0);
11036 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
11037 op1 = copy_to_mode_reg (mode1, op1);
11039 pat = GEN_FCN (d->icode) (op0, op1, op2);
11049 /* Expand vec_init builtin. */
11051 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
11053 enum machine_mode tmode = TYPE_MODE (type);
11054 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
11055 int i, n_elt = GET_MODE_NUNITS (tmode);
11056 rtvec v = rtvec_alloc (n_elt);
11058 gcc_assert (VECTOR_MODE_P (tmode));
11059 gcc_assert (n_elt == call_expr_nargs (exp));
11061 for (i = 0; i < n_elt; ++i)
11063 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
11064 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
11067 if (!target || !register_operand (target, tmode))
11068 target = gen_reg_rtx (tmode);
11070 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
11074 /* Return the integer constant in ARG. Constrain it to be in the range
11075 of the subparts of VEC_TYPE; issue an error if not. */
11078 get_element_number (tree vec_type, tree arg)
11080 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
11082 if (!host_integerp (arg, 1)
11083 || (elt = tree_low_cst (arg, 1), elt > max))
11085 error ("selector must be an integer constant in the range 0..%wi", max);
11092 /* Expand vec_set builtin. */
11094 altivec_expand_vec_set_builtin (tree exp)
11096 enum machine_mode tmode, mode1;
11097 tree arg0, arg1, arg2;
11101 arg0 = CALL_EXPR_ARG (exp, 0);
11102 arg1 = CALL_EXPR_ARG (exp, 1);
11103 arg2 = CALL_EXPR_ARG (exp, 2);
11105 tmode = TYPE_MODE (TREE_TYPE (arg0));
11106 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11107 gcc_assert (VECTOR_MODE_P (tmode));
11109 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
11110 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
11111 elt = get_element_number (TREE_TYPE (arg0), arg2);
11113 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
11114 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
11116 op0 = force_reg (tmode, op0);
11117 op1 = force_reg (mode1, op1);
11119 rs6000_expand_vector_set (op0, op1, elt);
11124 /* Expand vec_ext builtin. */
11126 altivec_expand_vec_ext_builtin (tree exp, rtx target)
11128 enum machine_mode tmode, mode0;
11133 arg0 = CALL_EXPR_ARG (exp, 0);
11134 arg1 = CALL_EXPR_ARG (exp, 1);
11136 op0 = expand_normal (arg0);
11137 elt = get_element_number (TREE_TYPE (arg0), arg1);
11139 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11140 mode0 = TYPE_MODE (TREE_TYPE (arg0));
11141 gcc_assert (VECTOR_MODE_P (mode0));
11143 op0 = force_reg (mode0, op0);
11145 if (optimize || !target || !register_operand (target, tmode))
11146 target = gen_reg_rtx (tmode);
11148 rs6000_expand_vector_extract (target, op0, elt);
11153 /* Expand the builtin in EXP and store the result in TARGET. Store
11154 true in *EXPANDEDP if we found a builtin to expand. */
11156 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
11158 const struct builtin_description *d;
11159 const struct builtin_description_predicates *dp;
11161 enum insn_code icode;
11162 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11165 enum machine_mode tmode, mode0;
11166 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11168 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11169 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11170 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
11171 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
11174 error ("unresolved overload for Altivec builtin %qF", fndecl);
11178 target = altivec_expand_ld_builtin (exp, target, expandedp);
11182 target = altivec_expand_st_builtin (exp, target, expandedp);
11186 target = altivec_expand_dst_builtin (exp, target, expandedp);
11194 case ALTIVEC_BUILTIN_STVX:
11195 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v4si, exp);
11196 case ALTIVEC_BUILTIN_STVEBX:
11197 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
11198 case ALTIVEC_BUILTIN_STVEHX:
11199 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
11200 case ALTIVEC_BUILTIN_STVEWX:
11201 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
11202 case ALTIVEC_BUILTIN_STVXL:
11203 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
11205 case ALTIVEC_BUILTIN_STVLX:
11206 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
11207 case ALTIVEC_BUILTIN_STVLXL:
11208 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
11209 case ALTIVEC_BUILTIN_STVRX:
11210 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
11211 case ALTIVEC_BUILTIN_STVRXL:
11212 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
11214 case VSX_BUILTIN_STXVD2X_V2DF:
11215 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2df, exp);
11216 case VSX_BUILTIN_STXVD2X_V2DI:
11217 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2di, exp);
11218 case VSX_BUILTIN_STXVW4X_V4SF:
11219 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4sf, exp);
11220 case VSX_BUILTIN_STXVW4X_V4SI:
11221 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4si, exp);
11222 case VSX_BUILTIN_STXVW4X_V8HI:
11223 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v8hi, exp);
11224 case VSX_BUILTIN_STXVW4X_V16QI:
11225 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v16qi, exp);
11227 case ALTIVEC_BUILTIN_MFVSCR:
11228 icode = CODE_FOR_altivec_mfvscr;
11229 tmode = insn_data[icode].operand[0].mode;
11232 || GET_MODE (target) != tmode
11233 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11234 target = gen_reg_rtx (tmode);
11236 pat = GEN_FCN (icode) (target);
11242 case ALTIVEC_BUILTIN_MTVSCR:
11243 icode = CODE_FOR_altivec_mtvscr;
11244 arg0 = CALL_EXPR_ARG (exp, 0);
11245 op0 = expand_normal (arg0);
11246 mode0 = insn_data[icode].operand[0].mode;
11248 /* If we got invalid arguments bail out before generating bad rtl. */
11249 if (arg0 == error_mark_node)
11252 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11253 op0 = copy_to_mode_reg (mode0, op0);
11255 pat = GEN_FCN (icode) (op0);
11260 case ALTIVEC_BUILTIN_DSSALL:
11261 emit_insn (gen_altivec_dssall ());
11264 case ALTIVEC_BUILTIN_DSS:
11265 icode = CODE_FOR_altivec_dss;
11266 arg0 = CALL_EXPR_ARG (exp, 0);
11268 op0 = expand_normal (arg0);
11269 mode0 = insn_data[icode].operand[0].mode;
11271 /* If we got invalid arguments bail out before generating bad rtl. */
11272 if (arg0 == error_mark_node)
11275 if (TREE_CODE (arg0) != INTEGER_CST
11276 || TREE_INT_CST_LOW (arg0) & ~0x3)
11278 error ("argument to dss must be a 2-bit unsigned literal");
11282 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11283 op0 = copy_to_mode_reg (mode0, op0);
11285 emit_insn (gen_altivec_dss (op0));
11288 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
11289 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
11290 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
11291 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
11292 case VSX_BUILTIN_VEC_INIT_V2DF:
11293 case VSX_BUILTIN_VEC_INIT_V2DI:
11294 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
11296 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
11297 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
11298 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
11299 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
11300 case VSX_BUILTIN_VEC_SET_V2DF:
11301 case VSX_BUILTIN_VEC_SET_V2DI:
11302 return altivec_expand_vec_set_builtin (exp);
11304 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
11305 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
11306 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
11307 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
11308 case VSX_BUILTIN_VEC_EXT_V2DF:
11309 case VSX_BUILTIN_VEC_EXT_V2DI:
11310 return altivec_expand_vec_ext_builtin (exp, target);
11314 /* Fall through. */
11317 /* Expand abs* operations. */
11319 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11320 if (d->code == fcode)
11321 return altivec_expand_abs_builtin (d->icode, exp, target);
11323 /* Expand the AltiVec predicates. */
11324 dp = bdesc_altivec_preds;
11325 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11326 if (dp->code == fcode)
11327 return altivec_expand_predicate_builtin (dp->icode, exp, target);
11329 /* LV* are funky. We initialized them differently. */
11332 case ALTIVEC_BUILTIN_LVSL:
11333 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
11334 exp, target, false);
11335 case ALTIVEC_BUILTIN_LVSR:
11336 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
11337 exp, target, false);
11338 case ALTIVEC_BUILTIN_LVEBX:
11339 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
11340 exp, target, false);
11341 case ALTIVEC_BUILTIN_LVEHX:
11342 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
11343 exp, target, false);
11344 case ALTIVEC_BUILTIN_LVEWX:
11345 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
11346 exp, target, false);
11347 case ALTIVEC_BUILTIN_LVXL:
11348 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
11349 exp, target, false);
11350 case ALTIVEC_BUILTIN_LVX:
11351 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v4si,
11352 exp, target, false);
11353 case ALTIVEC_BUILTIN_LVLX:
11354 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
11355 exp, target, true);
11356 case ALTIVEC_BUILTIN_LVLXL:
11357 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
11358 exp, target, true);
11359 case ALTIVEC_BUILTIN_LVRX:
11360 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
11361 exp, target, true);
11362 case ALTIVEC_BUILTIN_LVRXL:
11363 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
11364 exp, target, true);
11365 case VSX_BUILTIN_LXVD2X_V2DF:
11366 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2df,
11367 exp, target, false);
11368 case VSX_BUILTIN_LXVD2X_V2DI:
11369 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2di,
11370 exp, target, false);
11371 case VSX_BUILTIN_LXVW4X_V4SF:
11372 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4sf,
11373 exp, target, false);
11374 case VSX_BUILTIN_LXVW4X_V4SI:
11375 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4si,
11376 exp, target, false);
11377 case VSX_BUILTIN_LXVW4X_V8HI:
11378 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v8hi,
11379 exp, target, false);
11380 case VSX_BUILTIN_LXVW4X_V16QI:
11381 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v16qi,
11382 exp, target, false);
11386 /* Fall through. */
11389 *expandedp = false;
11393 /* Expand the builtin in EXP and store the result in TARGET. Store
11394 true in *EXPANDEDP if we found a builtin to expand. */
11396 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
11398 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11399 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11400 const struct builtin_description *d;
11407 case PAIRED_BUILTIN_STX:
11408 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
11409 case PAIRED_BUILTIN_LX:
11410 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
11413 /* Fall through. */
11416 /* Expand the paired predicates. */
11417 d = bdesc_paired_preds;
11418 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
11419 if (d->code == fcode)
11420 return paired_expand_predicate_builtin (d->icode, exp, target);
11422 *expandedp = false;
11426 /* Binops that need to be initialized manually, but can be expanded
11427 automagically by rs6000_expand_binop_builtin. */
11428 static struct builtin_description bdesc_2arg_spe[] =
11430 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
11431 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
11432 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
11433 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
11434 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
11435 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
11436 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
11437 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
11438 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
11439 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
11440 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
11441 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
11442 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
11443 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
11444 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
11445 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
11446 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
11447 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
11448 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
11449 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
11450 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
11451 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
11454 /* Expand the builtin in EXP and store the result in TARGET. Store
11455 true in *EXPANDEDP if we found a builtin to expand.
11457 This expands the SPE builtins that are not simple unary and binary
11460 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
11462 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11464 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11465 enum insn_code icode;
11466 enum machine_mode tmode, mode0;
11468 struct builtin_description *d;
11473 /* Syntax check for a 5-bit unsigned immediate. */
11476 case SPE_BUILTIN_EVSTDD:
11477 case SPE_BUILTIN_EVSTDH:
11478 case SPE_BUILTIN_EVSTDW:
11479 case SPE_BUILTIN_EVSTWHE:
11480 case SPE_BUILTIN_EVSTWHO:
11481 case SPE_BUILTIN_EVSTWWE:
11482 case SPE_BUILTIN_EVSTWWO:
11483 arg1 = CALL_EXPR_ARG (exp, 2);
11484 if (TREE_CODE (arg1) != INTEGER_CST
11485 || TREE_INT_CST_LOW (arg1) & ~0x1f)
11487 error ("argument 2 must be a 5-bit unsigned literal");
11495 /* The evsplat*i instructions are not quite generic. */
11498 case SPE_BUILTIN_EVSPLATFI:
11499 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
11501 case SPE_BUILTIN_EVSPLATI:
11502 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
11508 d = (struct builtin_description *) bdesc_2arg_spe;
11509 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
11510 if (d->code == fcode)
11511 return rs6000_expand_binop_builtin (d->icode, exp, target);
11513 d = (struct builtin_description *) bdesc_spe_predicates;
11514 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
11515 if (d->code == fcode)
11516 return spe_expand_predicate_builtin (d->icode, exp, target);
11518 d = (struct builtin_description *) bdesc_spe_evsel;
11519 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
11520 if (d->code == fcode)
11521 return spe_expand_evsel_builtin (d->icode, exp, target);
11525 case SPE_BUILTIN_EVSTDDX:
11526 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
11527 case SPE_BUILTIN_EVSTDHX:
11528 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
11529 case SPE_BUILTIN_EVSTDWX:
11530 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
11531 case SPE_BUILTIN_EVSTWHEX:
11532 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
11533 case SPE_BUILTIN_EVSTWHOX:
11534 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
11535 case SPE_BUILTIN_EVSTWWEX:
11536 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
11537 case SPE_BUILTIN_EVSTWWOX:
11538 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
11539 case SPE_BUILTIN_EVSTDD:
11540 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
11541 case SPE_BUILTIN_EVSTDH:
11542 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
11543 case SPE_BUILTIN_EVSTDW:
11544 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
11545 case SPE_BUILTIN_EVSTWHE:
11546 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
11547 case SPE_BUILTIN_EVSTWHO:
11548 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
11549 case SPE_BUILTIN_EVSTWWE:
11550 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
11551 case SPE_BUILTIN_EVSTWWO:
11552 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
11553 case SPE_BUILTIN_MFSPEFSCR:
11554 icode = CODE_FOR_spe_mfspefscr;
11555 tmode = insn_data[icode].operand[0].mode;
11558 || GET_MODE (target) != tmode
11559 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11560 target = gen_reg_rtx (tmode);
11562 pat = GEN_FCN (icode) (target);
11567 case SPE_BUILTIN_MTSPEFSCR:
11568 icode = CODE_FOR_spe_mtspefscr;
11569 arg0 = CALL_EXPR_ARG (exp, 0);
11570 op0 = expand_normal (arg0);
11571 mode0 = insn_data[icode].operand[0].mode;
11573 if (arg0 == error_mark_node)
11576 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11577 op0 = copy_to_mode_reg (mode0, op0);
11579 pat = GEN_FCN (icode) (op0);
11587 *expandedp = false;
11592 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11594 rtx pat, scratch, tmp;
11595 tree form = CALL_EXPR_ARG (exp, 0);
11596 tree arg0 = CALL_EXPR_ARG (exp, 1);
11597 tree arg1 = CALL_EXPR_ARG (exp, 2);
11598 rtx op0 = expand_normal (arg0);
11599 rtx op1 = expand_normal (arg1);
11600 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11601 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11603 enum rtx_code code;
11605 if (TREE_CODE (form) != INTEGER_CST)
11607 error ("argument 1 of __builtin_paired_predicate must be a constant");
11611 form_int = TREE_INT_CST_LOW (form);
11613 gcc_assert (mode0 == mode1);
11615 if (arg0 == error_mark_node || arg1 == error_mark_node)
11619 || GET_MODE (target) != SImode
11620 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
11621 target = gen_reg_rtx (SImode);
11622 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
11623 op0 = copy_to_mode_reg (mode0, op0);
11624 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
11625 op1 = copy_to_mode_reg (mode1, op1);
11627 scratch = gen_reg_rtx (CCFPmode);
11629 pat = GEN_FCN (icode) (scratch, op0, op1);
11651 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11654 error ("argument 1 of __builtin_paired_predicate is out of range");
11658 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11659 emit_move_insn (target, tmp);
11664 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11666 rtx pat, scratch, tmp;
11667 tree form = CALL_EXPR_ARG (exp, 0);
11668 tree arg0 = CALL_EXPR_ARG (exp, 1);
11669 tree arg1 = CALL_EXPR_ARG (exp, 2);
11670 rtx op0 = expand_normal (arg0);
11671 rtx op1 = expand_normal (arg1);
11672 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11673 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11675 enum rtx_code code;
11677 if (TREE_CODE (form) != INTEGER_CST)
11679 error ("argument 1 of __builtin_spe_predicate must be a constant");
11683 form_int = TREE_INT_CST_LOW (form);
11685 gcc_assert (mode0 == mode1);
11687 if (arg0 == error_mark_node || arg1 == error_mark_node)
11691 || GET_MODE (target) != SImode
11692 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
11693 target = gen_reg_rtx (SImode);
11695 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11696 op0 = copy_to_mode_reg (mode0, op0);
11697 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11698 op1 = copy_to_mode_reg (mode1, op1);
11700 scratch = gen_reg_rtx (CCmode);
11702 pat = GEN_FCN (icode) (scratch, op0, op1);
11707 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
11708 _lower_. We use one compare, but look in different bits of the
11709 CR for each variant.
11711 There are 2 elements in each SPE simd type (upper/lower). The CR
11712 bits are set as follows:
11714 BIT0 | BIT 1 | BIT 2 | BIT 3
11715 U | L | (U | L) | (U & L)
11717 So, for an "all" relationship, BIT 3 would be set.
11718 For an "any" relationship, BIT 2 would be set. Etc.
11720 Following traditional nomenclature, these bits map to:
11722 BIT0 | BIT 1 | BIT 2 | BIT 3
11725 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
11730 /* All variant. OV bit. */
11732 /* We need to get to the OV bit, which is the ORDERED bit. We
11733 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
11734 that's ugly and will make validate_condition_mode die.
11735 So let's just use another pattern. */
11736 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11738 /* Any variant. EQ bit. */
11742 /* Upper variant. LT bit. */
11746 /* Lower variant. GT bit. */
11751 error ("argument 1 of __builtin_spe_predicate is out of range");
11755 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11756 emit_move_insn (target, tmp);
11761 /* The evsel builtins look like this:
11763 e = __builtin_spe_evsel_OP (a, b, c, d);
11765 and work like this:
11767 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
11768 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
11772 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
11775 tree arg0 = CALL_EXPR_ARG (exp, 0);
11776 tree arg1 = CALL_EXPR_ARG (exp, 1);
11777 tree arg2 = CALL_EXPR_ARG (exp, 2);
11778 tree arg3 = CALL_EXPR_ARG (exp, 3);
11779 rtx op0 = expand_normal (arg0);
11780 rtx op1 = expand_normal (arg1);
11781 rtx op2 = expand_normal (arg2);
11782 rtx op3 = expand_normal (arg3);
11783 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11784 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11786 gcc_assert (mode0 == mode1);
11788 if (arg0 == error_mark_node || arg1 == error_mark_node
11789 || arg2 == error_mark_node || arg3 == error_mark_node)
11793 || GET_MODE (target) != mode0
11794 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
11795 target = gen_reg_rtx (mode0);
11797 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11798 op0 = copy_to_mode_reg (mode0, op0);
11799 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11800 op1 = copy_to_mode_reg (mode0, op1);
11801 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
11802 op2 = copy_to_mode_reg (mode0, op2);
11803 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
11804 op3 = copy_to_mode_reg (mode0, op3);
11806 /* Generate the compare. */
11807 scratch = gen_reg_rtx (CCmode);
11808 pat = GEN_FCN (icode) (scratch, op0, op1);
11813 if (mode0 == V2SImode)
11814 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
11816 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
11821 /* Expand an expression EXP that calls a built-in function,
11822 with result going to TARGET if that's convenient
11823 (and in mode MODE if that's convenient).
11824 SUBTARGET may be used as the target for computing one of EXP's operands.
11825 IGNORE is nonzero if the value is to be ignored. */
11828 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
11829 enum machine_mode mode ATTRIBUTE_UNUSED,
11830 int ignore ATTRIBUTE_UNUSED)
11832 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11833 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11834 const struct builtin_description *d;
11841 case RS6000_BUILTIN_RECIP:
11842 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
11844 case RS6000_BUILTIN_RECIPF:
11845 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
11847 case RS6000_BUILTIN_RSQRTF:
11848 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
11850 case RS6000_BUILTIN_RSQRT:
11851 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2, exp, target);
11853 case RS6000_BUILTIN_BSWAP_HI:
11854 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
11856 case POWER7_BUILTIN_BPERMD:
11857 return rs6000_expand_binop_builtin (((TARGET_64BIT)
11858 ? CODE_FOR_bpermd_di
11859 : CODE_FOR_bpermd_si), exp, target);
11861 case ALTIVEC_BUILTIN_MASK_FOR_LOAD:
11862 case ALTIVEC_BUILTIN_MASK_FOR_STORE:
11864 int icode = (int) CODE_FOR_altivec_lvsr;
11865 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11866 enum machine_mode mode = insn_data[icode].operand[1].mode;
11870 gcc_assert (TARGET_ALTIVEC);
11872 arg = CALL_EXPR_ARG (exp, 0);
11873 gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg)));
11874 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
11875 addr = memory_address (mode, op);
11876 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
11880 /* For the load case need to negate the address. */
11881 op = gen_reg_rtx (GET_MODE (addr));
11882 emit_insn (gen_rtx_SET (VOIDmode, op,
11883 gen_rtx_NEG (GET_MODE (addr), addr)));
11885 op = gen_rtx_MEM (mode, op);
11888 || GET_MODE (target) != tmode
11889 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11890 target = gen_reg_rtx (tmode);
11892 /*pat = gen_altivec_lvsr (target, op);*/
11893 pat = GEN_FCN (icode) (target, op);
11901 case ALTIVEC_BUILTIN_VCFUX:
11902 case ALTIVEC_BUILTIN_VCFSX:
11903 case ALTIVEC_BUILTIN_VCTUXS:
11904 case ALTIVEC_BUILTIN_VCTSXS:
11905 /* FIXME: There's got to be a nicer way to handle this case than
11906 constructing a new CALL_EXPR. */
11907 if (call_expr_nargs (exp) == 1)
11909 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
11910 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
11918 if (TARGET_ALTIVEC)
11920 ret = altivec_expand_builtin (exp, target, &success);
11927 ret = spe_expand_builtin (exp, target, &success);
11932 if (TARGET_PAIRED_FLOAT)
11934 ret = paired_expand_builtin (exp, target, &success);
11940 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
11942 /* Handle simple unary operations. */
11943 d = (struct builtin_description *) bdesc_1arg;
11944 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
11945 if (d->code == fcode)
11946 return rs6000_expand_unop_builtin (d->icode, exp, target);
11948 /* Handle simple binary operations. */
11949 d = (struct builtin_description *) bdesc_2arg;
11950 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
11951 if (d->code == fcode)
11952 return rs6000_expand_binop_builtin (d->icode, exp, target);
11954 /* Handle simple ternary operations. */
11956 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
11957 if (d->code == fcode)
11958 return rs6000_expand_ternop_builtin (d->icode, exp, target);
11960 gcc_unreachable ();
11964 rs6000_init_builtins (void)
11969 V2SI_type_node = build_vector_type (intSI_type_node, 2);
11970 V2SF_type_node = build_vector_type (float_type_node, 2);
11971 V2DI_type_node = build_vector_type (intDI_type_node, 2);
11972 V2DF_type_node = build_vector_type (double_type_node, 2);
11973 V4HI_type_node = build_vector_type (intHI_type_node, 4);
11974 V4SI_type_node = build_vector_type (intSI_type_node, 4);
11975 V4SF_type_node = build_vector_type (float_type_node, 4);
11976 V8HI_type_node = build_vector_type (intHI_type_node, 8);
11977 V16QI_type_node = build_vector_type (intQI_type_node, 16);
11979 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
11980 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
11981 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
11982 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
11984 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
11985 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
11986 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
11987 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
11989 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
11990 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
11991 'vector unsigned short'. */
11993 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
11994 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
11995 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
11996 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
11997 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
11999 long_integer_type_internal_node = long_integer_type_node;
12000 long_unsigned_type_internal_node = long_unsigned_type_node;
12001 long_long_integer_type_internal_node = long_long_integer_type_node;
12002 long_long_unsigned_type_internal_node = long_long_unsigned_type_node;
12003 intQI_type_internal_node = intQI_type_node;
12004 uintQI_type_internal_node = unsigned_intQI_type_node;
12005 intHI_type_internal_node = intHI_type_node;
12006 uintHI_type_internal_node = unsigned_intHI_type_node;
12007 intSI_type_internal_node = intSI_type_node;
12008 uintSI_type_internal_node = unsigned_intSI_type_node;
12009 intDI_type_internal_node = intDI_type_node;
12010 uintDI_type_internal_node = unsigned_intDI_type_node;
12011 float_type_internal_node = float_type_node;
12012 double_type_internal_node = double_type_node;
12013 void_type_internal_node = void_type_node;
12015 /* Initialize the modes for builtin_function_type, mapping a machine mode to
12017 builtin_mode_to_type[QImode][0] = integer_type_node;
12018 builtin_mode_to_type[HImode][0] = integer_type_node;
12019 builtin_mode_to_type[SImode][0] = intSI_type_node;
12020 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
12021 builtin_mode_to_type[DImode][0] = intDI_type_node;
12022 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
12023 builtin_mode_to_type[SFmode][0] = float_type_node;
12024 builtin_mode_to_type[DFmode][0] = double_type_node;
12025 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
12026 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
12027 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
12028 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
12029 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
12030 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
12031 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
12032 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
12033 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
12034 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
12035 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
12036 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
12037 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
12039 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12040 get_identifier ("__bool char"),
12041 bool_char_type_node);
12042 TYPE_NAME (bool_char_type_node) = tdecl;
12043 (*lang_hooks.decls.pushdecl) (tdecl);
12044 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12045 get_identifier ("__bool short"),
12046 bool_short_type_node);
12047 TYPE_NAME (bool_short_type_node) = tdecl;
12048 (*lang_hooks.decls.pushdecl) (tdecl);
12049 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12050 get_identifier ("__bool int"),
12051 bool_int_type_node);
12052 TYPE_NAME (bool_int_type_node) = tdecl;
12053 (*lang_hooks.decls.pushdecl) (tdecl);
12054 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
12056 TYPE_NAME (pixel_type_node) = tdecl;
12057 (*lang_hooks.decls.pushdecl) (tdecl);
12059 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
12060 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
12061 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
12062 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
12063 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
12065 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12066 get_identifier ("__vector unsigned char"),
12067 unsigned_V16QI_type_node);
12068 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
12069 (*lang_hooks.decls.pushdecl) (tdecl);
12070 tdecl = build_decl (BUILTINS_LOCATION,
12071 TYPE_DECL, get_identifier ("__vector signed char"),
12073 TYPE_NAME (V16QI_type_node) = tdecl;
12074 (*lang_hooks.decls.pushdecl) (tdecl);
12075 tdecl = build_decl (BUILTINS_LOCATION,
12076 TYPE_DECL, get_identifier ("__vector __bool char"),
12077 bool_V16QI_type_node);
12078 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
12079 (*lang_hooks.decls.pushdecl) (tdecl);
12081 tdecl = build_decl (BUILTINS_LOCATION,
12082 TYPE_DECL, get_identifier ("__vector unsigned short"),
12083 unsigned_V8HI_type_node);
12084 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
12085 (*lang_hooks.decls.pushdecl) (tdecl);
12086 tdecl = build_decl (BUILTINS_LOCATION,
12087 TYPE_DECL, get_identifier ("__vector signed short"),
12089 TYPE_NAME (V8HI_type_node) = tdecl;
12090 (*lang_hooks.decls.pushdecl) (tdecl);
12091 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12092 get_identifier ("__vector __bool short"),
12093 bool_V8HI_type_node);
12094 TYPE_NAME (bool_V8HI_type_node) = tdecl;
12095 (*lang_hooks.decls.pushdecl) (tdecl);
12097 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12098 get_identifier ("__vector unsigned int"),
12099 unsigned_V4SI_type_node);
12100 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
12101 (*lang_hooks.decls.pushdecl) (tdecl);
12102 tdecl = build_decl (BUILTINS_LOCATION,
12103 TYPE_DECL, get_identifier ("__vector signed int"),
12105 TYPE_NAME (V4SI_type_node) = tdecl;
12106 (*lang_hooks.decls.pushdecl) (tdecl);
12107 tdecl = build_decl (BUILTINS_LOCATION,
12108 TYPE_DECL, get_identifier ("__vector __bool int"),
12109 bool_V4SI_type_node);
12110 TYPE_NAME (bool_V4SI_type_node) = tdecl;
12111 (*lang_hooks.decls.pushdecl) (tdecl);
12113 tdecl = build_decl (BUILTINS_LOCATION,
12114 TYPE_DECL, get_identifier ("__vector float"),
12116 TYPE_NAME (V4SF_type_node) = tdecl;
12117 (*lang_hooks.decls.pushdecl) (tdecl);
12118 tdecl = build_decl (BUILTINS_LOCATION,
12119 TYPE_DECL, get_identifier ("__vector __pixel"),
12120 pixel_V8HI_type_node);
12121 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
12122 (*lang_hooks.decls.pushdecl) (tdecl);
12126 tdecl = build_decl (BUILTINS_LOCATION,
12127 TYPE_DECL, get_identifier ("__vector double"),
12129 TYPE_NAME (V2DF_type_node) = tdecl;
12130 (*lang_hooks.decls.pushdecl) (tdecl);
12132 tdecl = build_decl (BUILTINS_LOCATION,
12133 TYPE_DECL, get_identifier ("__vector long"),
12135 TYPE_NAME (V2DI_type_node) = tdecl;
12136 (*lang_hooks.decls.pushdecl) (tdecl);
12138 tdecl = build_decl (BUILTINS_LOCATION,
12139 TYPE_DECL, get_identifier ("__vector unsigned long"),
12140 unsigned_V2DI_type_node);
12141 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
12142 (*lang_hooks.decls.pushdecl) (tdecl);
12144 tdecl = build_decl (BUILTINS_LOCATION,
12145 TYPE_DECL, get_identifier ("__vector __bool long"),
12146 bool_V2DI_type_node);
12147 TYPE_NAME (bool_V2DI_type_node) = tdecl;
12148 (*lang_hooks.decls.pushdecl) (tdecl);
12151 if (TARGET_PAIRED_FLOAT)
12152 paired_init_builtins ();
12154 spe_init_builtins ();
12155 if (TARGET_ALTIVEC)
12156 altivec_init_builtins ();
12157 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
12158 rs6000_common_init_builtins ();
12161 ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
12162 RS6000_BUILTIN_RECIP,
12163 "__builtin_recipdiv");
12164 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
12165 RS6000_BUILTIN_RECIP);
12169 ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
12170 RS6000_BUILTIN_RECIPF,
12171 "__builtin_recipdivf");
12172 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
12173 RS6000_BUILTIN_RECIPF);
12175 if (TARGET_FRSQRTE)
12177 ftype = builtin_function_type (DFmode, DFmode, VOIDmode, VOIDmode,
12178 RS6000_BUILTIN_RSQRT,
12179 "__builtin_rsqrt");
12180 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrt", ftype,
12181 RS6000_BUILTIN_RSQRT);
12183 if (TARGET_FRSQRTES)
12185 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
12186 RS6000_BUILTIN_RSQRTF,
12187 "__builtin_rsqrtf");
12188 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
12189 RS6000_BUILTIN_RSQRTF);
12191 if (TARGET_POPCNTD)
12193 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
12194 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
12195 POWER7_BUILTIN_BPERMD,
12196 "__builtin_bpermd");
12197 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
12198 POWER7_BUILTIN_BPERMD);
12200 if (TARGET_POWERPC)
12202 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
12203 tree ftype = build_function_type_list (unsigned_intHI_type_node,
12204 unsigned_intHI_type_node,
12206 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
12207 RS6000_BUILTIN_BSWAP_HI);
12211 /* AIX libm provides clog as __clog. */
12212 if (built_in_decls [BUILT_IN_CLOG])
12213 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
12216 #ifdef SUBTARGET_INIT_BUILTINS
12217 SUBTARGET_INIT_BUILTINS;
12221 /* Returns the rs6000 builtin decl for CODE. */
12224 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
12226 if (code >= RS6000_BUILTIN_COUNT)
12227 return error_mark_node;
12229 return rs6000_builtin_decls[code];
12232 /* Search through a set of builtins and enable the mask bits.
12233 DESC is an array of builtins.
12234 SIZE is the total number of builtins.
12235 START is the builtin enum at which to start.
12236 END is the builtin enum at which to end. */
12238 enable_mask_for_builtins (struct builtin_description *desc, int size,
12239 enum rs6000_builtins start,
12240 enum rs6000_builtins end)
12244 for (i = 0; i < size; ++i)
12245 if (desc[i].code == start)
12251 for (; i < size; ++i)
12253 /* Flip all the bits on. */
12254 desc[i].mask = target_flags;
12255 if (desc[i].code == end)
12261 spe_init_builtins (void)
12263 tree puint_type_node = build_pointer_type (unsigned_type_node);
12264 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
12265 struct builtin_description *d;
12268 tree v2si_ftype_4_v2si
12269 = build_function_type_list (opaque_V2SI_type_node,
12270 opaque_V2SI_type_node,
12271 opaque_V2SI_type_node,
12272 opaque_V2SI_type_node,
12273 opaque_V2SI_type_node,
12276 tree v2sf_ftype_4_v2sf
12277 = build_function_type_list (opaque_V2SF_type_node,
12278 opaque_V2SF_type_node,
12279 opaque_V2SF_type_node,
12280 opaque_V2SF_type_node,
12281 opaque_V2SF_type_node,
12284 tree int_ftype_int_v2si_v2si
12285 = build_function_type_list (integer_type_node,
12287 opaque_V2SI_type_node,
12288 opaque_V2SI_type_node,
12291 tree int_ftype_int_v2sf_v2sf
12292 = build_function_type_list (integer_type_node,
12294 opaque_V2SF_type_node,
12295 opaque_V2SF_type_node,
12298 tree void_ftype_v2si_puint_int
12299 = build_function_type_list (void_type_node,
12300 opaque_V2SI_type_node,
12305 tree void_ftype_v2si_puint_char
12306 = build_function_type_list (void_type_node,
12307 opaque_V2SI_type_node,
12312 tree void_ftype_v2si_pv2si_int
12313 = build_function_type_list (void_type_node,
12314 opaque_V2SI_type_node,
12315 opaque_p_V2SI_type_node,
12319 tree void_ftype_v2si_pv2si_char
12320 = build_function_type_list (void_type_node,
12321 opaque_V2SI_type_node,
12322 opaque_p_V2SI_type_node,
12326 tree void_ftype_int
12327 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
12329 tree int_ftype_void
12330 = build_function_type_list (integer_type_node, NULL_TREE);
12332 tree v2si_ftype_pv2si_int
12333 = build_function_type_list (opaque_V2SI_type_node,
12334 opaque_p_V2SI_type_node,
12338 tree v2si_ftype_puint_int
12339 = build_function_type_list (opaque_V2SI_type_node,
12344 tree v2si_ftype_pushort_int
12345 = build_function_type_list (opaque_V2SI_type_node,
12350 tree v2si_ftype_signed_char
12351 = build_function_type_list (opaque_V2SI_type_node,
12352 signed_char_type_node,
12355 /* The initialization of the simple binary and unary builtins is
12356 done in rs6000_common_init_builtins, but we have to enable the
12357 mask bits here manually because we have run out of `target_flags'
12358 bits. We really need to redesign this mask business. */
12360 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
12361 ARRAY_SIZE (bdesc_2arg),
12362 SPE_BUILTIN_EVADDW,
12363 SPE_BUILTIN_EVXOR);
12364 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
12365 ARRAY_SIZE (bdesc_1arg),
12367 SPE_BUILTIN_EVSUBFUSIAAW);
12368 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
12369 ARRAY_SIZE (bdesc_spe_predicates),
12370 SPE_BUILTIN_EVCMPEQ,
12371 SPE_BUILTIN_EVFSTSTLT);
12372 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
12373 ARRAY_SIZE (bdesc_spe_evsel),
12374 SPE_BUILTIN_EVSEL_CMPGTS,
12375 SPE_BUILTIN_EVSEL_FSTSTEQ);
12377 (*lang_hooks.decls.pushdecl)
12378 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
12379 get_identifier ("__ev64_opaque__"),
12380 opaque_V2SI_type_node));
12382 /* Initialize irregular SPE builtins. */
12384 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
12385 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
12386 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
12387 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
12388 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
12389 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
12390 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
12391 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
12392 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
12393 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
12394 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
12395 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
12396 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
12397 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
12398 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
12399 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
12400 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
12401 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
12404 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
12405 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
12406 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
12407 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
12408 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
12409 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
12410 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
12411 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
12412 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
12413 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
12414 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
12415 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
12416 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
12417 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
12418 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
12419 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
12420 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
12421 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
12422 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
12423 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
12424 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
12425 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
12428 d = (struct builtin_description *) bdesc_spe_predicates;
12429 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
12433 switch (insn_data[d->icode].operand[1].mode)
12436 type = int_ftype_int_v2si_v2si;
12439 type = int_ftype_int_v2sf_v2sf;
12442 gcc_unreachable ();
12445 def_builtin (d->mask, d->name, type, d->code);
12448 /* Evsel predicates. */
12449 d = (struct builtin_description *) bdesc_spe_evsel;
12450 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
12454 switch (insn_data[d->icode].operand[1].mode)
12457 type = v2si_ftype_4_v2si;
12460 type = v2sf_ftype_4_v2sf;
12463 gcc_unreachable ();
12466 def_builtin (d->mask, d->name, type, d->code);
12471 paired_init_builtins (void)
12473 const struct builtin_description *d;
12476 tree int_ftype_int_v2sf_v2sf
12477 = build_function_type_list (integer_type_node,
12482 tree pcfloat_type_node =
12483 build_pointer_type (build_qualified_type
12484 (float_type_node, TYPE_QUAL_CONST));
12486 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
12487 long_integer_type_node,
12490 tree void_ftype_v2sf_long_pcfloat =
12491 build_function_type_list (void_type_node,
12493 long_integer_type_node,
12498 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
12499 PAIRED_BUILTIN_LX);
12502 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
12503 PAIRED_BUILTIN_STX);
12506 d = bdesc_paired_preds;
12507 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
12511 switch (insn_data[d->icode].operand[1].mode)
12514 type = int_ftype_int_v2sf_v2sf;
12517 gcc_unreachable ();
12520 def_builtin (d->mask, d->name, type, d->code);
12525 altivec_init_builtins (void)
12527 const struct builtin_description *d;
12528 const struct builtin_description_predicates *dp;
12532 tree pvoid_type_node = build_pointer_type (void_type_node);
12534 tree pcvoid_type_node
12535 = build_pointer_type (build_qualified_type (void_type_node,
12538 tree int_ftype_opaque
12539 = build_function_type_list (integer_type_node,
12540 opaque_V4SI_type_node, NULL_TREE);
12541 tree opaque_ftype_opaque
12542 = build_function_type_list (integer_type_node, NULL_TREE);
12543 tree opaque_ftype_opaque_int
12544 = build_function_type_list (opaque_V4SI_type_node,
12545 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
12546 tree opaque_ftype_opaque_opaque_int
12547 = build_function_type_list (opaque_V4SI_type_node,
12548 opaque_V4SI_type_node, opaque_V4SI_type_node,
12549 integer_type_node, NULL_TREE);
12550 tree int_ftype_int_opaque_opaque
12551 = build_function_type_list (integer_type_node,
12552 integer_type_node, opaque_V4SI_type_node,
12553 opaque_V4SI_type_node, NULL_TREE);
12554 tree int_ftype_int_v4si_v4si
12555 = build_function_type_list (integer_type_node,
12556 integer_type_node, V4SI_type_node,
12557 V4SI_type_node, NULL_TREE);
12558 tree void_ftype_v4si
12559 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
12560 tree v8hi_ftype_void
12561 = build_function_type_list (V8HI_type_node, NULL_TREE);
12562 tree void_ftype_void
12563 = build_function_type_list (void_type_node, NULL_TREE);
12564 tree void_ftype_int
12565 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
12567 tree opaque_ftype_long_pcvoid
12568 = build_function_type_list (opaque_V4SI_type_node,
12569 long_integer_type_node, pcvoid_type_node,
12571 tree v16qi_ftype_long_pcvoid
12572 = build_function_type_list (V16QI_type_node,
12573 long_integer_type_node, pcvoid_type_node,
12575 tree v8hi_ftype_long_pcvoid
12576 = build_function_type_list (V8HI_type_node,
12577 long_integer_type_node, pcvoid_type_node,
12579 tree v4si_ftype_long_pcvoid
12580 = build_function_type_list (V4SI_type_node,
12581 long_integer_type_node, pcvoid_type_node,
12583 tree v4sf_ftype_long_pcvoid
12584 = build_function_type_list (V4SF_type_node,
12585 long_integer_type_node, pcvoid_type_node,
12587 tree v2df_ftype_long_pcvoid
12588 = build_function_type_list (V2DF_type_node,
12589 long_integer_type_node, pcvoid_type_node,
12591 tree v2di_ftype_long_pcvoid
12592 = build_function_type_list (V2DI_type_node,
12593 long_integer_type_node, pcvoid_type_node,
12596 tree void_ftype_opaque_long_pvoid
12597 = build_function_type_list (void_type_node,
12598 opaque_V4SI_type_node, long_integer_type_node,
12599 pvoid_type_node, NULL_TREE);
12600 tree void_ftype_v4si_long_pvoid
12601 = build_function_type_list (void_type_node,
12602 V4SI_type_node, long_integer_type_node,
12603 pvoid_type_node, NULL_TREE);
12604 tree void_ftype_v16qi_long_pvoid
12605 = build_function_type_list (void_type_node,
12606 V16QI_type_node, long_integer_type_node,
12607 pvoid_type_node, NULL_TREE);
12608 tree void_ftype_v8hi_long_pvoid
12609 = build_function_type_list (void_type_node,
12610 V8HI_type_node, long_integer_type_node,
12611 pvoid_type_node, NULL_TREE);
12612 tree void_ftype_v4sf_long_pvoid
12613 = build_function_type_list (void_type_node,
12614 V4SF_type_node, long_integer_type_node,
12615 pvoid_type_node, NULL_TREE);
12616 tree void_ftype_v2df_long_pvoid
12617 = build_function_type_list (void_type_node,
12618 V2DF_type_node, long_integer_type_node,
12619 pvoid_type_node, NULL_TREE);
12620 tree void_ftype_v2di_long_pvoid
12621 = build_function_type_list (void_type_node,
12622 V2DI_type_node, long_integer_type_node,
12623 pvoid_type_node, NULL_TREE);
12624 tree int_ftype_int_v8hi_v8hi
12625 = build_function_type_list (integer_type_node,
12626 integer_type_node, V8HI_type_node,
12627 V8HI_type_node, NULL_TREE);
12628 tree int_ftype_int_v16qi_v16qi
12629 = build_function_type_list (integer_type_node,
12630 integer_type_node, V16QI_type_node,
12631 V16QI_type_node, NULL_TREE);
12632 tree int_ftype_int_v4sf_v4sf
12633 = build_function_type_list (integer_type_node,
12634 integer_type_node, V4SF_type_node,
12635 V4SF_type_node, NULL_TREE);
12636 tree int_ftype_int_v2df_v2df
12637 = build_function_type_list (integer_type_node,
12638 integer_type_node, V2DF_type_node,
12639 V2DF_type_node, NULL_TREE);
12640 tree v4si_ftype_v4si
12641 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
12642 tree v8hi_ftype_v8hi
12643 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
12644 tree v16qi_ftype_v16qi
12645 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
12646 tree v4sf_ftype_v4sf
12647 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
12648 tree v2df_ftype_v2df
12649 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
12650 tree void_ftype_pcvoid_int_int
12651 = build_function_type_list (void_type_node,
12652 pcvoid_type_node, integer_type_node,
12653 integer_type_node, NULL_TREE);
12655 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
12656 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
12657 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
12658 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
12659 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
12660 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
12661 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
12662 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
12663 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
12664 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
12665 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
12666 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
12667 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
12668 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
12669 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
12670 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
12671 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
12672 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
12673 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
12674 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
12675 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
12676 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
12677 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
12678 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
12679 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
12680 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
12681 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
12682 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
12683 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
12684 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
12686 def_builtin (MASK_VSX, "__builtin_vsx_lxvd2x_v2df", v2df_ftype_long_pcvoid,
12687 VSX_BUILTIN_LXVD2X_V2DF);
12688 def_builtin (MASK_VSX, "__builtin_vsx_lxvd2x_v2di", v2di_ftype_long_pcvoid,
12689 VSX_BUILTIN_LXVD2X_V2DI);
12690 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v4sf", v4sf_ftype_long_pcvoid,
12691 VSX_BUILTIN_LXVW4X_V4SF);
12692 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v4si", v4si_ftype_long_pcvoid,
12693 VSX_BUILTIN_LXVW4X_V4SI);
12694 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v8hi",
12695 v8hi_ftype_long_pcvoid, VSX_BUILTIN_LXVW4X_V8HI);
12696 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v16qi",
12697 v16qi_ftype_long_pcvoid, VSX_BUILTIN_LXVW4X_V16QI);
12698 def_builtin (MASK_VSX, "__builtin_vsx_stxvd2x_v2df",
12699 void_ftype_v2df_long_pvoid, VSX_BUILTIN_STXVD2X_V2DF);
12700 def_builtin (MASK_VSX, "__builtin_vsx_stxvd2x_v2di",
12701 void_ftype_v2di_long_pvoid, VSX_BUILTIN_STXVD2X_V2DI);
12702 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v4sf",
12703 void_ftype_v4sf_long_pvoid, VSX_BUILTIN_STXVW4X_V4SF);
12704 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v4si",
12705 void_ftype_v4si_long_pvoid, VSX_BUILTIN_STXVW4X_V4SI);
12706 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v8hi",
12707 void_ftype_v8hi_long_pvoid, VSX_BUILTIN_STXVW4X_V8HI);
12708 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v16qi",
12709 void_ftype_v16qi_long_pvoid, VSX_BUILTIN_STXVW4X_V16QI);
12710 def_builtin (MASK_VSX, "__builtin_vec_vsx_ld", opaque_ftype_long_pcvoid,
12711 VSX_BUILTIN_VEC_LD);
12712 def_builtin (MASK_VSX, "__builtin_vec_vsx_st", void_ftype_opaque_long_pvoid,
12713 VSX_BUILTIN_VEC_ST);
12715 if (rs6000_cpu == PROCESSOR_CELL)
12717 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
12718 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
12719 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
12720 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
12722 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
12723 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
12724 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
12725 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
12727 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
12728 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
12729 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
12730 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
12732 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
12733 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
12734 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
12735 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
12737 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
12738 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
12739 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
12741 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
12742 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
12743 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
12744 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
12745 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
12746 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
12747 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
12748 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
12749 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
12750 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
12751 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
12752 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
12754 /* Add the DST variants. */
12756 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
12757 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
12759 /* Initialize the predicates. */
12760 dp = bdesc_altivec_preds;
12761 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
12763 enum machine_mode mode1;
12765 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12766 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12767 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
12768 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
12773 mode1 = insn_data[dp->icode].operand[1].mode;
12778 type = int_ftype_int_opaque_opaque;
12781 type = int_ftype_int_v4si_v4si;
12784 type = int_ftype_int_v8hi_v8hi;
12787 type = int_ftype_int_v16qi_v16qi;
12790 type = int_ftype_int_v4sf_v4sf;
12793 type = int_ftype_int_v2df_v2df;
12796 gcc_unreachable ();
12799 def_builtin (dp->mask, dp->name, type, dp->code);
12802 /* Initialize the abs* operators. */
12804 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
12806 enum machine_mode mode0;
12809 mode0 = insn_data[d->icode].operand[0].mode;
12814 type = v4si_ftype_v4si;
12817 type = v8hi_ftype_v8hi;
12820 type = v16qi_ftype_v16qi;
12823 type = v4sf_ftype_v4sf;
12826 type = v2df_ftype_v2df;
12829 gcc_unreachable ();
12832 def_builtin (d->mask, d->name, type, d->code);
12835 if (TARGET_ALTIVEC)
12839 /* Initialize target builtin that implements
12840 targetm.vectorize.builtin_mask_for_load. */
12842 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
12843 v16qi_ftype_long_pcvoid,
12844 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
12845 BUILT_IN_MD, NULL, NULL_TREE);
12846 TREE_READONLY (decl) = 1;
12847 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
12848 altivec_builtin_mask_for_load = decl;
12851 /* Access to the vec_init patterns. */
12852 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
12853 integer_type_node, integer_type_node,
12854 integer_type_node, NULL_TREE);
12855 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
12856 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
12858 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
12859 short_integer_type_node,
12860 short_integer_type_node,
12861 short_integer_type_node,
12862 short_integer_type_node,
12863 short_integer_type_node,
12864 short_integer_type_node,
12865 short_integer_type_node, NULL_TREE);
12866 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
12867 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
12869 ftype = build_function_type_list (V16QI_type_node, char_type_node,
12870 char_type_node, char_type_node,
12871 char_type_node, char_type_node,
12872 char_type_node, char_type_node,
12873 char_type_node, char_type_node,
12874 char_type_node, char_type_node,
12875 char_type_node, char_type_node,
12876 char_type_node, char_type_node,
12877 char_type_node, NULL_TREE);
12878 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
12879 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
12881 ftype = build_function_type_list (V4SF_type_node, float_type_node,
12882 float_type_node, float_type_node,
12883 float_type_node, NULL_TREE);
12884 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
12885 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
12889 ftype = build_function_type_list (V2DF_type_node, double_type_node,
12890 double_type_node, NULL_TREE);
12891 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
12892 VSX_BUILTIN_VEC_INIT_V2DF);
12894 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
12895 intDI_type_node, NULL_TREE);
12896 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
12897 VSX_BUILTIN_VEC_INIT_V2DI);
12900 /* Access to the vec_set patterns. */
12901 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
12903 integer_type_node, NULL_TREE);
12904 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
12905 ALTIVEC_BUILTIN_VEC_SET_V4SI);
12907 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
12909 integer_type_node, NULL_TREE);
12910 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
12911 ALTIVEC_BUILTIN_VEC_SET_V8HI);
12913 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
12915 integer_type_node, NULL_TREE);
12916 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
12917 ALTIVEC_BUILTIN_VEC_SET_V16QI);
12919 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
12921 integer_type_node, NULL_TREE);
12922 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
12923 ALTIVEC_BUILTIN_VEC_SET_V4SF);
12927 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
12929 integer_type_node, NULL_TREE);
12930 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
12931 VSX_BUILTIN_VEC_SET_V2DF);
12933 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
12935 integer_type_node, NULL_TREE);
12936 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
12937 VSX_BUILTIN_VEC_SET_V2DI);
12940 /* Access to the vec_extract patterns. */
12941 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
12942 integer_type_node, NULL_TREE);
12943 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
12944 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
12946 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
12947 integer_type_node, NULL_TREE);
12948 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
12949 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
12951 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
12952 integer_type_node, NULL_TREE);
12953 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
12954 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
12956 ftype = build_function_type_list (float_type_node, V4SF_type_node,
12957 integer_type_node, NULL_TREE);
12958 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
12959 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
12963 ftype = build_function_type_list (double_type_node, V2DF_type_node,
12964 integer_type_node, NULL_TREE);
12965 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
12966 VSX_BUILTIN_VEC_EXT_V2DF);
12968 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
12969 integer_type_node, NULL_TREE);
12970 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
12971 VSX_BUILTIN_VEC_EXT_V2DI);
12975 /* Hash function for builtin functions with up to 3 arguments and a return
12978 builtin_hash_function (const void *hash_entry)
12982 const struct builtin_hash_struct *bh =
12983 (const struct builtin_hash_struct *) hash_entry;
12985 for (i = 0; i < 4; i++)
12987 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
12988 ret = (ret * 2) + bh->uns_p[i];
12994 /* Compare builtin hash entries H1 and H2 for equivalence. */
12996 builtin_hash_eq (const void *h1, const void *h2)
12998 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
12999 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
13001 return ((p1->mode[0] == p2->mode[0])
13002 && (p1->mode[1] == p2->mode[1])
13003 && (p1->mode[2] == p2->mode[2])
13004 && (p1->mode[3] == p2->mode[3])
13005 && (p1->uns_p[0] == p2->uns_p[0])
13006 && (p1->uns_p[1] == p2->uns_p[1])
13007 && (p1->uns_p[2] == p2->uns_p[2])
13008 && (p1->uns_p[3] == p2->uns_p[3]));
13011 /* Map types for builtin functions with an explicit return type and up to 3
13012 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
13013 of the argument. */
13015 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
13016 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
13017 enum rs6000_builtins builtin, const char *name)
13019 struct builtin_hash_struct h;
13020 struct builtin_hash_struct *h2;
13024 tree ret_type = NULL_TREE;
13025 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
13027 /* Create builtin_hash_table. */
13028 if (builtin_hash_table == NULL)
13029 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
13030 builtin_hash_eq, NULL);
13032 h.type = NULL_TREE;
13033 h.mode[0] = mode_ret;
13034 h.mode[1] = mode_arg0;
13035 h.mode[2] = mode_arg1;
13036 h.mode[3] = mode_arg2;
13042 /* If the builtin is a type that produces unsigned results or takes unsigned
13043 arguments, and it is returned as a decl for the vectorizer (such as
13044 widening multiplies, permute), make sure the arguments and return value
13045 are type correct. */
13048 /* unsigned 2 argument functions. */
13049 case ALTIVEC_BUILTIN_VMULEUB_UNS:
13050 case ALTIVEC_BUILTIN_VMULEUH_UNS:
13051 case ALTIVEC_BUILTIN_VMULOUB_UNS:
13052 case ALTIVEC_BUILTIN_VMULOUH_UNS:
13058 /* unsigned 3 argument functions. */
13059 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
13060 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
13061 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
13062 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
13063 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
13064 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
13065 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
13066 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
13067 case VSX_BUILTIN_VPERM_16QI_UNS:
13068 case VSX_BUILTIN_VPERM_8HI_UNS:
13069 case VSX_BUILTIN_VPERM_4SI_UNS:
13070 case VSX_BUILTIN_VPERM_2DI_UNS:
13071 case VSX_BUILTIN_XXSEL_16QI_UNS:
13072 case VSX_BUILTIN_XXSEL_8HI_UNS:
13073 case VSX_BUILTIN_XXSEL_4SI_UNS:
13074 case VSX_BUILTIN_XXSEL_2DI_UNS:
13081 /* signed permute functions with unsigned char mask. */
13082 case ALTIVEC_BUILTIN_VPERM_16QI:
13083 case ALTIVEC_BUILTIN_VPERM_8HI:
13084 case ALTIVEC_BUILTIN_VPERM_4SI:
13085 case ALTIVEC_BUILTIN_VPERM_4SF:
13086 case ALTIVEC_BUILTIN_VPERM_2DI:
13087 case ALTIVEC_BUILTIN_VPERM_2DF:
13088 case VSX_BUILTIN_VPERM_16QI:
13089 case VSX_BUILTIN_VPERM_8HI:
13090 case VSX_BUILTIN_VPERM_4SI:
13091 case VSX_BUILTIN_VPERM_4SF:
13092 case VSX_BUILTIN_VPERM_2DI:
13093 case VSX_BUILTIN_VPERM_2DF:
13097 /* unsigned args, signed return. */
13098 case VSX_BUILTIN_XVCVUXDDP_UNS:
13099 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
13103 /* signed args, unsigned return. */
13104 case VSX_BUILTIN_XVCVDPUXDS_UNS:
13105 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
13113 /* Figure out how many args are present. */
13114 while (num_args > 0 && h.mode[num_args] == VOIDmode)
13118 fatal_error ("internal error: builtin function %s had no type", name);
13120 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
13121 if (!ret_type && h.uns_p[0])
13122 ret_type = builtin_mode_to_type[h.mode[0]][0];
13125 fatal_error ("internal error: builtin function %s had an unexpected "
13126 "return type %s", name, GET_MODE_NAME (h.mode[0]));
13128 for (i = 0; i < (int) ARRAY_SIZE (arg_type); i++)
13129 arg_type[i] = NULL_TREE;
13131 for (i = 0; i < num_args; i++)
13133 int m = (int) h.mode[i+1];
13134 int uns_p = h.uns_p[i+1];
13136 arg_type[i] = builtin_mode_to_type[m][uns_p];
13137 if (!arg_type[i] && uns_p)
13138 arg_type[i] = builtin_mode_to_type[m][0];
13141 fatal_error ("internal error: builtin function %s, argument %d "
13142 "had unexpected argument type %s", name, i,
13143 GET_MODE_NAME (m));
13146 found = htab_find_slot (builtin_hash_table, &h, INSERT);
13147 if (*found == NULL)
13149 h2 = ggc_alloc_builtin_hash_struct ();
13151 *found = (void *)h2;
13153 h2->type = build_function_type_list (ret_type, arg_type[0], arg_type[1],
13154 arg_type[2], NULL_TREE);
13157 return ((struct builtin_hash_struct *)(*found))->type;
13161 rs6000_common_init_builtins (void)
13163 const struct builtin_description *d;
13166 tree opaque_ftype_opaque = NULL_TREE;
13167 tree opaque_ftype_opaque_opaque = NULL_TREE;
13168 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
13169 tree v2si_ftype_qi = NULL_TREE;
13170 tree v2si_ftype_v2si_qi = NULL_TREE;
13171 tree v2si_ftype_int_qi = NULL_TREE;
13173 if (!TARGET_PAIRED_FLOAT)
13175 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
13176 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
13179 /* Add the ternary operators. */
13181 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
13184 int mask = d->mask;
13186 if ((mask != 0 && (mask & target_flags) == 0)
13187 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13190 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13191 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13192 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13193 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13195 if (! (type = opaque_ftype_opaque_opaque_opaque))
13196 type = opaque_ftype_opaque_opaque_opaque
13197 = build_function_type_list (opaque_V4SI_type_node,
13198 opaque_V4SI_type_node,
13199 opaque_V4SI_type_node,
13200 opaque_V4SI_type_node,
13205 enum insn_code icode = d->icode;
13206 if (d->name == 0 || icode == CODE_FOR_nothing)
13209 type = builtin_function_type (insn_data[icode].operand[0].mode,
13210 insn_data[icode].operand[1].mode,
13211 insn_data[icode].operand[2].mode,
13212 insn_data[icode].operand[3].mode,
13216 def_builtin (d->mask, d->name, type, d->code);
13219 /* Add the binary operators. */
13221 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
13223 enum machine_mode mode0, mode1, mode2;
13225 int mask = d->mask;
13227 if ((mask != 0 && (mask & target_flags) == 0)
13228 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13231 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13232 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13233 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13234 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13236 if (! (type = opaque_ftype_opaque_opaque))
13237 type = opaque_ftype_opaque_opaque
13238 = build_function_type_list (opaque_V4SI_type_node,
13239 opaque_V4SI_type_node,
13240 opaque_V4SI_type_node,
13245 enum insn_code icode = d->icode;
13246 if (d->name == 0 || icode == CODE_FOR_nothing)
13249 mode0 = insn_data[icode].operand[0].mode;
13250 mode1 = insn_data[icode].operand[1].mode;
13251 mode2 = insn_data[icode].operand[2].mode;
13253 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
13255 if (! (type = v2si_ftype_v2si_qi))
13256 type = v2si_ftype_v2si_qi
13257 = build_function_type_list (opaque_V2SI_type_node,
13258 opaque_V2SI_type_node,
13263 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
13264 && mode2 == QImode)
13266 if (! (type = v2si_ftype_int_qi))
13267 type = v2si_ftype_int_qi
13268 = build_function_type_list (opaque_V2SI_type_node,
13275 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
13279 def_builtin (d->mask, d->name, type, d->code);
13282 /* Add the simple unary operators. */
13283 d = (struct builtin_description *) bdesc_1arg;
13284 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
13286 enum machine_mode mode0, mode1;
13288 int mask = d->mask;
13290 if ((mask != 0 && (mask & target_flags) == 0)
13291 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13294 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13295 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13296 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13297 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13299 if (! (type = opaque_ftype_opaque))
13300 type = opaque_ftype_opaque
13301 = build_function_type_list (opaque_V4SI_type_node,
13302 opaque_V4SI_type_node,
13307 enum insn_code icode = d->icode;
13308 if (d->name == 0 || icode == CODE_FOR_nothing)
13311 mode0 = insn_data[icode].operand[0].mode;
13312 mode1 = insn_data[icode].operand[1].mode;
13314 if (mode0 == V2SImode && mode1 == QImode)
13316 if (! (type = v2si_ftype_qi))
13317 type = v2si_ftype_qi
13318 = build_function_type_list (opaque_V2SI_type_node,
13324 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
13328 def_builtin (d->mask, d->name, type, d->code);
13333 rs6000_init_libfuncs (void)
13335 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
13336 && !TARGET_POWER2 && !TARGET_POWERPC)
13338 /* AIX library routines for float->int conversion. */
13339 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
13340 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
13341 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
13342 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
13345 if (!TARGET_IEEEQUAD)
13346 /* AIX/Darwin/64-bit Linux quad floating point routines. */
13347 if (!TARGET_XL_COMPAT)
13349 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
13350 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
13351 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
13352 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
13354 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
13356 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
13357 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
13358 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
13359 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
13360 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
13361 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
13362 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
13364 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
13365 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
13366 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
13367 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
13368 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
13369 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
13370 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
13371 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
13374 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
13375 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
13379 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
13380 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
13381 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
13382 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
13386 /* 32-bit SVR4 quad floating point routines. */
13388 set_optab_libfunc (add_optab, TFmode, "_q_add");
13389 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
13390 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
13391 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
13392 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
13393 if (TARGET_PPC_GPOPT || TARGET_POWER2)
13394 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
13396 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
13397 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
13398 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
13399 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
13400 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
13401 set_optab_libfunc (le_optab, TFmode, "_q_fle");
13403 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
13404 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
13405 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
13406 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
13407 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
13408 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
13409 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
13410 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
13415 /* Expand a block clear operation, and return 1 if successful. Return 0
13416 if we should let the compiler generate normal code.
13418 operands[0] is the destination
13419 operands[1] is the length
13420 operands[3] is the alignment */
13423 expand_block_clear (rtx operands[])
13425 rtx orig_dest = operands[0];
13426 rtx bytes_rtx = operands[1];
13427 rtx align_rtx = operands[3];
13428 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
13429 HOST_WIDE_INT align;
13430 HOST_WIDE_INT bytes;
13435 /* If this is not a fixed size move, just call memcpy */
13439 /* This must be a fixed size alignment */
13440 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13441 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13443 /* Anything to clear? */
13444 bytes = INTVAL (bytes_rtx);
13448 /* Use the builtin memset after a point, to avoid huge code bloat.
13449 When optimize_size, avoid any significant code bloat; calling
13450 memset is about 4 instructions, so allow for one instruction to
13451 load zero and three to do clearing. */
13452 if (TARGET_ALTIVEC && align >= 128)
13454 else if (TARGET_POWERPC64 && align >= 32)
13456 else if (TARGET_SPE && align >= 64)
13461 if (optimize_size && bytes > 3 * clear_step)
13463 if (! optimize_size && bytes > 8 * clear_step)
13466 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
13468 enum machine_mode mode = BLKmode;
13471 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
13476 else if (bytes >= 8 && TARGET_SPE && align >= 64)
13481 else if (bytes >= 8 && TARGET_POWERPC64
13482 /* 64-bit loads and stores require word-aligned
13484 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13489 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13490 { /* move 4 bytes */
13494 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13495 { /* move 2 bytes */
13499 else /* move 1 byte at a time */
13505 dest = adjust_address (orig_dest, mode, offset);
13507 emit_move_insn (dest, CONST0_RTX (mode));
13514 /* Expand a block move operation, and return 1 if successful. Return 0
13515 if we should let the compiler generate normal code.
13517 operands[0] is the destination
13518 operands[1] is the source
13519 operands[2] is the length
13520 operands[3] is the alignment */
13522 #define MAX_MOVE_REG 4
13525 expand_block_move (rtx operands[])
13527 rtx orig_dest = operands[0];
13528 rtx orig_src = operands[1];
13529 rtx bytes_rtx = operands[2];
13530 rtx align_rtx = operands[3];
13531 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
13536 rtx stores[MAX_MOVE_REG];
13539 /* If this is not a fixed size move, just call memcpy */
13543 /* This must be a fixed size alignment */
13544 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13545 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13547 /* Anything to move? */
13548 bytes = INTVAL (bytes_rtx);
13552 if (bytes > rs6000_block_move_inline_limit)
13555 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
13558 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
13559 rtx (*mov) (rtx, rtx);
13561 enum machine_mode mode = BLKmode;
13564 /* Altivec first, since it will be faster than a string move
13565 when it applies, and usually not significantly larger. */
13566 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
13570 gen_func.mov = gen_movv4si;
13572 else if (TARGET_SPE && bytes >= 8 && align >= 64)
13576 gen_func.mov = gen_movv2si;
13578 else if (TARGET_STRING
13579 && bytes > 24 /* move up to 32 bytes at a time */
13585 && ! fixed_regs[10]
13586 && ! fixed_regs[11]
13587 && ! fixed_regs[12])
13589 move_bytes = (bytes > 32) ? 32 : bytes;
13590 gen_func.movmemsi = gen_movmemsi_8reg;
13592 else if (TARGET_STRING
13593 && bytes > 16 /* move up to 24 bytes at a time */
13599 && ! fixed_regs[10])
13601 move_bytes = (bytes > 24) ? 24 : bytes;
13602 gen_func.movmemsi = gen_movmemsi_6reg;
13604 else if (TARGET_STRING
13605 && bytes > 8 /* move up to 16 bytes at a time */
13609 && ! fixed_regs[8])
13611 move_bytes = (bytes > 16) ? 16 : bytes;
13612 gen_func.movmemsi = gen_movmemsi_4reg;
13614 else if (bytes >= 8 && TARGET_POWERPC64
13615 /* 64-bit loads and stores require word-aligned
13617 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13621 gen_func.mov = gen_movdi;
13623 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
13624 { /* move up to 8 bytes at a time */
13625 move_bytes = (bytes > 8) ? 8 : bytes;
13626 gen_func.movmemsi = gen_movmemsi_2reg;
13628 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13629 { /* move 4 bytes */
13632 gen_func.mov = gen_movsi;
13634 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13635 { /* move 2 bytes */
13638 gen_func.mov = gen_movhi;
13640 else if (TARGET_STRING && bytes > 1)
13641 { /* move up to 4 bytes at a time */
13642 move_bytes = (bytes > 4) ? 4 : bytes;
13643 gen_func.movmemsi = gen_movmemsi_1reg;
13645 else /* move 1 byte at a time */
13649 gen_func.mov = gen_movqi;
13652 src = adjust_address (orig_src, mode, offset);
13653 dest = adjust_address (orig_dest, mode, offset);
13655 if (mode != BLKmode)
13657 rtx tmp_reg = gen_reg_rtx (mode);
13659 emit_insn ((*gen_func.mov) (tmp_reg, src));
13660 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
13663 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
13666 for (i = 0; i < num_reg; i++)
13667 emit_insn (stores[i]);
13671 if (mode == BLKmode)
13673 /* Move the address into scratch registers. The movmemsi
13674 patterns require zero offset. */
13675 if (!REG_P (XEXP (src, 0)))
13677 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
13678 src = replace_equiv_address (src, src_reg);
13680 set_mem_size (src, move_bytes);
13682 if (!REG_P (XEXP (dest, 0)))
13684 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
13685 dest = replace_equiv_address (dest, dest_reg);
13687 set_mem_size (dest, move_bytes);
13689 emit_insn ((*gen_func.movmemsi) (dest, src,
13690 GEN_INT (move_bytes & 31),
13699 /* Return a string to perform a load_multiple operation.
13700 operands[0] is the vector.
13701 operands[1] is the source address.
13702 operands[2] is the first destination register. */
13705 rs6000_output_load_multiple (rtx operands[3])
13707 /* We have to handle the case where the pseudo used to contain the address
13708 is assigned to one of the output registers. */
13710 int words = XVECLEN (operands[0], 0);
13713 if (XVECLEN (operands[0], 0) == 1)
13714 return "{l|lwz} %2,0(%1)";
13716 for (i = 0; i < words; i++)
13717 if (refers_to_regno_p (REGNO (operands[2]) + i,
13718 REGNO (operands[2]) + i + 1, operands[1], 0))
13722 xop[0] = GEN_INT (4 * (words-1));
13723 xop[1] = operands[1];
13724 xop[2] = operands[2];
13725 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
13730 xop[0] = GEN_INT (4 * (words-1));
13731 xop[1] = operands[1];
13732 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
13733 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);
13738 for (j = 0; j < words; j++)
13741 xop[0] = GEN_INT (j * 4);
13742 xop[1] = operands[1];
13743 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
13744 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
13746 xop[0] = GEN_INT (i * 4);
13747 xop[1] = operands[1];
13748 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
13753 return "{lsi|lswi} %2,%1,%N0";
13757 /* A validation routine: say whether CODE, a condition code, and MODE
13758 match. The other alternatives either don't make sense or should
13759 never be generated. */
13762 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
13764 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
13765 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
13766 && GET_MODE_CLASS (mode) == MODE_CC);
13768 /* These don't make sense. */
13769 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
13770 || mode != CCUNSmode);
13772 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
13773 || mode == CCUNSmode);
13775 gcc_assert (mode == CCFPmode
13776 || (code != ORDERED && code != UNORDERED
13777 && code != UNEQ && code != LTGT
13778 && code != UNGT && code != UNLT
13779 && code != UNGE && code != UNLE));
13781 /* These should never be generated except for
13782 flag_finite_math_only. */
13783 gcc_assert (mode != CCFPmode
13784 || flag_finite_math_only
13785 || (code != LE && code != GE
13786 && code != UNEQ && code != LTGT
13787 && code != UNGT && code != UNLT));
13789 /* These are invalid; the information is not there. */
13790 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
13794 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
13795 mask required to convert the result of a rotate insn into a shift
13796 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
13799 includes_lshift_p (rtx shiftop, rtx andop)
13801 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
13803 shift_mask <<= INTVAL (shiftop);
13805 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
13808 /* Similar, but for right shift. */
13811 includes_rshift_p (rtx shiftop, rtx andop)
13813 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
13815 shift_mask >>= INTVAL (shiftop);
13817 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
13820 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
13821 to perform a left shift. It must have exactly SHIFTOP least
13822 significant 0's, then one or more 1's, then zero or more 0's. */
13825 includes_rldic_lshift_p (rtx shiftop, rtx andop)
13827 if (GET_CODE (andop) == CONST_INT)
13829 HOST_WIDE_INT c, lsb, shift_mask;
13831 c = INTVAL (andop);
13832 if (c == 0 || c == ~0)
13836 shift_mask <<= INTVAL (shiftop);
13838 /* Find the least significant one bit. */
13841 /* It must coincide with the LSB of the shift mask. */
13842 if (-lsb != shift_mask)
13845 /* Invert to look for the next transition (if any). */
13848 /* Remove the low group of ones (originally low group of zeros). */
13851 /* Again find the lsb, and check we have all 1's above. */
13855 else if (GET_CODE (andop) == CONST_DOUBLE
13856 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
13858 HOST_WIDE_INT low, high, lsb;
13859 HOST_WIDE_INT shift_mask_low, shift_mask_high;
13861 low = CONST_DOUBLE_LOW (andop);
13862 if (HOST_BITS_PER_WIDE_INT < 64)
13863 high = CONST_DOUBLE_HIGH (andop);
13865 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
13866 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
13869 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13871 shift_mask_high = ~0;
13872 if (INTVAL (shiftop) > 32)
13873 shift_mask_high <<= INTVAL (shiftop) - 32;
13875 lsb = high & -high;
13877 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
13883 lsb = high & -high;
13884 return high == -lsb;
13887 shift_mask_low = ~0;
13888 shift_mask_low <<= INTVAL (shiftop);
13892 if (-lsb != shift_mask_low)
13895 if (HOST_BITS_PER_WIDE_INT < 64)
13900 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13902 lsb = high & -high;
13903 return high == -lsb;
13907 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
13913 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
13914 to perform a left shift. It must have SHIFTOP or more least
13915 significant 0's, with the remainder of the word 1's. */
13918 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
13920 if (GET_CODE (andop) == CONST_INT)
13922 HOST_WIDE_INT c, lsb, shift_mask;
13925 shift_mask <<= INTVAL (shiftop);
13926 c = INTVAL (andop);
13928 /* Find the least significant one bit. */
13931 /* It must be covered by the shift mask.
13932 This test also rejects c == 0. */
13933 if ((lsb & shift_mask) == 0)
13936 /* Check we have all 1's above the transition, and reject all 1's. */
13937 return c == -lsb && lsb != 1;
13939 else if (GET_CODE (andop) == CONST_DOUBLE
13940 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
13942 HOST_WIDE_INT low, lsb, shift_mask_low;
13944 low = CONST_DOUBLE_LOW (andop);
13946 if (HOST_BITS_PER_WIDE_INT < 64)
13948 HOST_WIDE_INT high, shift_mask_high;
13950 high = CONST_DOUBLE_HIGH (andop);
13954 shift_mask_high = ~0;
13955 if (INTVAL (shiftop) > 32)
13956 shift_mask_high <<= INTVAL (shiftop) - 32;
13958 lsb = high & -high;
13960 if ((lsb & shift_mask_high) == 0)
13963 return high == -lsb;
13969 shift_mask_low = ~0;
13970 shift_mask_low <<= INTVAL (shiftop);
13974 if ((lsb & shift_mask_low) == 0)
13977 return low == -lsb && lsb != 1;
13983 /* Return 1 if operands will generate a valid arguments to rlwimi
13984 instruction for insert with right shift in 64-bit mode. The mask may
13985 not start on the first bit or stop on the last bit because wrap-around
13986 effects of instruction do not correspond to semantics of RTL insn. */
13989 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
13991 if (INTVAL (startop) > 32
13992 && INTVAL (startop) < 64
13993 && INTVAL (sizeop) > 1
13994 && INTVAL (sizeop) + INTVAL (startop) < 64
13995 && INTVAL (shiftop) > 0
13996 && INTVAL (sizeop) + INTVAL (shiftop) < 32
13997 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
14003 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
14004 for lfq and stfq insns iff the registers are hard registers. */
14007 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
14009 /* We might have been passed a SUBREG. */
14010 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
14013 /* We might have been passed non floating point registers. */
14014 if (!FP_REGNO_P (REGNO (reg1))
14015 || !FP_REGNO_P (REGNO (reg2)))
14018 return (REGNO (reg1) == REGNO (reg2) - 1);
14021 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
14022 addr1 and addr2 must be in consecutive memory locations
14023 (addr2 == addr1 + 8). */
14026 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
14029 unsigned int reg1, reg2;
14030 int offset1, offset2;
14032 /* The mems cannot be volatile. */
14033 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
14036 addr1 = XEXP (mem1, 0);
14037 addr2 = XEXP (mem2, 0);
14039 /* Extract an offset (if used) from the first addr. */
14040 if (GET_CODE (addr1) == PLUS)
14042 /* If not a REG, return zero. */
14043 if (GET_CODE (XEXP (addr1, 0)) != REG)
14047 reg1 = REGNO (XEXP (addr1, 0));
14048 /* The offset must be constant! */
14049 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
14051 offset1 = INTVAL (XEXP (addr1, 1));
14054 else if (GET_CODE (addr1) != REG)
14058 reg1 = REGNO (addr1);
14059 /* This was a simple (mem (reg)) expression. Offset is 0. */
14063 /* And now for the second addr. */
14064 if (GET_CODE (addr2) == PLUS)
14066 /* If not a REG, return zero. */
14067 if (GET_CODE (XEXP (addr2, 0)) != REG)
14071 reg2 = REGNO (XEXP (addr2, 0));
14072 /* The offset must be constant. */
14073 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
14075 offset2 = INTVAL (XEXP (addr2, 1));
14078 else if (GET_CODE (addr2) != REG)
14082 reg2 = REGNO (addr2);
14083 /* This was a simple (mem (reg)) expression. Offset is 0. */
14087 /* Both of these must have the same base register. */
14091 /* The offset for the second addr must be 8 more than the first addr. */
14092 if (offset2 != offset1 + 8)
14095 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
14102 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
14104 static bool eliminated = false;
14107 if (mode != SDmode)
14108 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
14111 rtx mem = cfun->machine->sdmode_stack_slot;
14112 gcc_assert (mem != NULL_RTX);
14116 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
14117 cfun->machine->sdmode_stack_slot = mem;
14123 if (TARGET_DEBUG_ADDR)
14125 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
14126 GET_MODE_NAME (mode));
14128 fprintf (stderr, "\tNULL_RTX\n");
14137 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
14139 /* Don't walk into types. */
14140 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
14142 *walk_subtrees = 0;
14146 switch (TREE_CODE (*tp))
14155 case VIEW_CONVERT_EXPR:
14156 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
14166 enum reload_reg_type {
14168 VECTOR_REGISTER_TYPE,
14169 OTHER_REGISTER_TYPE
14172 static enum reload_reg_type
14173 rs6000_reload_register_type (enum reg_class rclass)
14179 return GPR_REGISTER_TYPE;
14184 return VECTOR_REGISTER_TYPE;
14187 return OTHER_REGISTER_TYPE;
14191 /* Inform reload about cases where moving X with a mode MODE to a register in
14192 RCLASS requires an extra scratch or immediate register. Return the class
14193 needed for the immediate register.
14195 For VSX and Altivec, we may need a register to convert sp+offset into
14198 For misaligned 64-bit gpr loads and stores we need a register to
14199 convert an offset address to indirect. */
14202 rs6000_secondary_reload (bool in_p,
14204 reg_class_t rclass_i,
14205 enum machine_mode mode,
14206 secondary_reload_info *sri)
14208 enum reg_class rclass = (enum reg_class) rclass_i;
14209 reg_class_t ret = ALL_REGS;
14210 enum insn_code icode;
14211 bool default_p = false;
14213 sri->icode = CODE_FOR_nothing;
14215 /* Convert vector loads and stores into gprs to use an additional base
14217 icode = rs6000_vector_reload[mode][in_p != false];
14218 if (icode != CODE_FOR_nothing)
14221 sri->icode = CODE_FOR_nothing;
14222 sri->extra_cost = 0;
14224 if (GET_CODE (x) == MEM)
14226 rtx addr = XEXP (x, 0);
14228 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
14229 an extra register in that case, but it would need an extra
14230 register if the addressing is reg+reg or (reg+reg)&(-16). */
14231 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
14233 if (!legitimate_indirect_address_p (addr, false)
14234 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14236 sri->icode = icode;
14237 /* account for splitting the loads, and converting the
14238 address from reg+reg to reg. */
14239 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
14240 + ((GET_CODE (addr) == AND) ? 1 : 0));
14243 /* Loads to and stores from vector registers can only do reg+reg
14244 addressing. Altivec registers can also do (reg+reg)&(-16). */
14245 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
14246 || rclass == FLOAT_REGS || rclass == NO_REGS)
14248 if (!VECTOR_MEM_ALTIVEC_P (mode)
14249 && GET_CODE (addr) == AND
14250 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14251 && INTVAL (XEXP (addr, 1)) == -16
14252 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
14253 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
14255 sri->icode = icode;
14256 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
14259 else if (!legitimate_indirect_address_p (addr, false)
14260 && (rclass == NO_REGS
14261 || !legitimate_indexed_address_p (addr, false)))
14263 sri->icode = icode;
14264 sri->extra_cost = 1;
14267 icode = CODE_FOR_nothing;
14269 /* Any other loads, including to pseudo registers which haven't been
14270 assigned to a register yet, default to require a scratch
14274 sri->icode = icode;
14275 sri->extra_cost = 2;
14278 else if (REG_P (x))
14280 int regno = true_regnum (x);
14282 icode = CODE_FOR_nothing;
14283 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
14287 enum reg_class xclass = REGNO_REG_CLASS (regno);
14288 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
14289 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
14291 /* If memory is needed, use default_secondary_reload to create the
14293 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
14302 else if (TARGET_POWERPC64
14303 && rs6000_reload_register_type (rclass) == GPR_REGISTER_TYPE
14305 && GET_MODE_SIZE (GET_MODE (x)) >= UNITS_PER_WORD)
14307 rtx addr = XEXP (x, 0);
14309 if (GET_CODE (addr) == PRE_MODIFY)
14310 addr = XEXP (addr, 1);
14311 else if (GET_CODE (addr) == LO_SUM
14312 && GET_CODE (XEXP (addr, 0)) == REG
14313 && GET_CODE (XEXP (addr, 1)) == CONST)
14314 addr = XEXP (XEXP (addr, 1), 0);
14316 if (GET_CODE (addr) == PLUS
14317 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14318 && (INTVAL (XEXP (addr, 1)) & 3) != 0)
14321 sri->icode = CODE_FOR_reload_di_load;
14323 sri->icode = CODE_FOR_reload_di_store;
14324 sri->extra_cost = 2;
14334 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
14336 gcc_assert (ret != ALL_REGS);
14338 if (TARGET_DEBUG_ADDR)
14341 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
14343 reg_class_names[ret],
14344 in_p ? "true" : "false",
14345 reg_class_names[rclass],
14346 GET_MODE_NAME (mode));
14349 fprintf (stderr, ", default secondary reload");
14351 if (sri->icode != CODE_FOR_nothing)
14352 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
14353 insn_data[sri->icode].name, sri->extra_cost);
14355 fprintf (stderr, "\n");
14363 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
14364 to SP+reg addressing. */
14367 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
14369 int regno = true_regnum (reg);
14370 enum machine_mode mode = GET_MODE (reg);
14371 enum reg_class rclass;
14373 rtx and_op2 = NULL_RTX;
14376 rtx scratch_or_premodify = scratch;
14380 if (TARGET_DEBUG_ADDR)
14382 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
14383 store_p ? "store" : "load");
14384 fprintf (stderr, "reg:\n");
14386 fprintf (stderr, "mem:\n");
14388 fprintf (stderr, "scratch:\n");
14389 debug_rtx (scratch);
14392 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
14393 gcc_assert (GET_CODE (mem) == MEM);
14394 rclass = REGNO_REG_CLASS (regno);
14395 addr = XEXP (mem, 0);
14399 /* GPRs can handle reg + small constant, all other addresses need to use
14400 the scratch register. */
14403 if (GET_CODE (addr) == AND)
14405 and_op2 = XEXP (addr, 1);
14406 addr = XEXP (addr, 0);
14409 if (GET_CODE (addr) == PRE_MODIFY)
14411 scratch_or_premodify = XEXP (addr, 0);
14412 gcc_assert (REG_P (scratch_or_premodify));
14413 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14414 addr = XEXP (addr, 1);
14417 if (GET_CODE (addr) == PLUS
14418 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
14419 || and_op2 != NULL_RTX))
14421 addr_op1 = XEXP (addr, 0);
14422 addr_op2 = XEXP (addr, 1);
14423 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
14425 if (!REG_P (addr_op2)
14426 && (GET_CODE (addr_op2) != CONST_INT
14427 || !satisfies_constraint_I (addr_op2)))
14429 if (TARGET_DEBUG_ADDR)
14432 "\nMove plus addr to register %s, mode = %s: ",
14433 rs6000_reg_names[REGNO (scratch)],
14434 GET_MODE_NAME (mode));
14435 debug_rtx (addr_op2);
14437 rs6000_emit_move (scratch, addr_op2, Pmode);
14438 addr_op2 = scratch;
14441 emit_insn (gen_rtx_SET (VOIDmode,
14442 scratch_or_premodify,
14443 gen_rtx_PLUS (Pmode,
14447 addr = scratch_or_premodify;
14448 scratch_or_premodify = scratch;
14450 else if (!legitimate_indirect_address_p (addr, false)
14451 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14453 if (TARGET_DEBUG_ADDR)
14455 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14456 rs6000_reg_names[REGNO (scratch_or_premodify)],
14457 GET_MODE_NAME (mode));
14460 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14461 addr = scratch_or_premodify;
14462 scratch_or_premodify = scratch;
14466 /* Float/Altivec registers can only handle reg+reg addressing. Move
14467 other addresses into a scratch register. */
14472 /* With float regs, we need to handle the AND ourselves, since we can't
14473 use the Altivec instruction with an implicit AND -16. Allow scalar
14474 loads to float registers to use reg+offset even if VSX. */
14475 if (GET_CODE (addr) == AND
14476 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
14477 || GET_CODE (XEXP (addr, 1)) != CONST_INT
14478 || INTVAL (XEXP (addr, 1)) != -16
14479 || !VECTOR_MEM_ALTIVEC_P (mode)))
14481 and_op2 = XEXP (addr, 1);
14482 addr = XEXP (addr, 0);
14485 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
14486 as the address later. */
14487 if (GET_CODE (addr) == PRE_MODIFY
14488 && (!VECTOR_MEM_VSX_P (mode)
14489 || and_op2 != NULL_RTX
14490 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
14492 scratch_or_premodify = XEXP (addr, 0);
14493 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
14495 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14496 addr = XEXP (addr, 1);
14499 if (legitimate_indirect_address_p (addr, false) /* reg */
14500 || legitimate_indexed_address_p (addr, false) /* reg+reg */
14501 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
14502 || (GET_CODE (addr) == AND /* Altivec memory */
14503 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14504 && INTVAL (XEXP (addr, 1)) == -16
14505 && VECTOR_MEM_ALTIVEC_P (mode))
14506 || (rclass == FLOAT_REGS /* legacy float mem */
14507 && GET_MODE_SIZE (mode) == 8
14508 && and_op2 == NULL_RTX
14509 && scratch_or_premodify == scratch
14510 && rs6000_legitimate_offset_address_p (mode, addr, false)))
14513 else if (GET_CODE (addr) == PLUS)
14515 addr_op1 = XEXP (addr, 0);
14516 addr_op2 = XEXP (addr, 1);
14517 gcc_assert (REG_P (addr_op1));
14519 if (TARGET_DEBUG_ADDR)
14521 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
14522 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14523 debug_rtx (addr_op2);
14525 rs6000_emit_move (scratch, addr_op2, Pmode);
14526 emit_insn (gen_rtx_SET (VOIDmode,
14527 scratch_or_premodify,
14528 gen_rtx_PLUS (Pmode,
14531 addr = scratch_or_premodify;
14532 scratch_or_premodify = scratch;
14535 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
14536 || GET_CODE (addr) == CONST_INT || REG_P (addr))
14538 if (TARGET_DEBUG_ADDR)
14540 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14541 rs6000_reg_names[REGNO (scratch_or_premodify)],
14542 GET_MODE_NAME (mode));
14546 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14547 addr = scratch_or_premodify;
14548 scratch_or_premodify = scratch;
14552 gcc_unreachable ();
14557 gcc_unreachable ();
14560 /* If the original address involved a pre-modify that we couldn't use the VSX
14561 memory instruction with update, and we haven't taken care of already,
14562 store the address in the pre-modify register and use that as the
14564 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
14566 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
14567 addr = scratch_or_premodify;
14570 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
14571 memory instruction, recreate the AND now, including the clobber which is
14572 generated by the general ANDSI3/ANDDI3 patterns for the
14573 andi. instruction. */
14574 if (and_op2 != NULL_RTX)
14576 if (! legitimate_indirect_address_p (addr, false))
14578 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
14582 if (TARGET_DEBUG_ADDR)
14584 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
14585 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14586 debug_rtx (and_op2);
14589 and_rtx = gen_rtx_SET (VOIDmode,
14591 gen_rtx_AND (Pmode,
14595 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
14596 emit_insn (gen_rtx_PARALLEL (VOIDmode,
14597 gen_rtvec (2, and_rtx, cc_clobber)));
14601 /* Adjust the address if it changed. */
14602 if (addr != XEXP (mem, 0))
14604 mem = change_address (mem, mode, addr);
14605 if (TARGET_DEBUG_ADDR)
14606 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
14609 /* Now create the move. */
14611 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
14613 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
14618 /* Convert reloads involving 64-bit gprs and misaligned offset
14619 addressing to use indirect addressing. */
14622 rs6000_secondary_reload_ppc64 (rtx reg, rtx mem, rtx scratch, bool store_p)
14624 int regno = true_regnum (reg);
14625 enum reg_class rclass;
14627 rtx scratch_or_premodify = scratch;
14629 if (TARGET_DEBUG_ADDR)
14631 fprintf (stderr, "\nrs6000_secondary_reload_ppc64, type = %s\n",
14632 store_p ? "store" : "load");
14633 fprintf (stderr, "reg:\n");
14635 fprintf (stderr, "mem:\n");
14637 fprintf (stderr, "scratch:\n");
14638 debug_rtx (scratch);
14641 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
14642 gcc_assert (GET_CODE (mem) == MEM);
14643 rclass = REGNO_REG_CLASS (regno);
14644 gcc_assert (rclass == GENERAL_REGS || rclass == BASE_REGS);
14645 addr = XEXP (mem, 0);
14647 if (GET_CODE (addr) == PRE_MODIFY)
14649 scratch_or_premodify = XEXP (addr, 0);
14650 gcc_assert (REG_P (scratch_or_premodify));
14651 addr = XEXP (addr, 1);
14653 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
14655 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14657 mem = replace_equiv_address_nv (mem, scratch_or_premodify);
14659 /* Now create the move. */
14661 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
14663 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
14668 /* Allocate a 64-bit stack slot to be used for copying SDmode
14669 values through if this function has any SDmode references. */
14672 rs6000_alloc_sdmode_stack_slot (void)
14676 gimple_stmt_iterator gsi;
14678 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
14681 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
14683 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
14686 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14687 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14693 /* Check for any SDmode parameters of the function. */
14694 for (t = DECL_ARGUMENTS (cfun->decl); t; t = DECL_CHAIN (t))
14696 if (TREE_TYPE (t) == error_mark_node)
14699 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
14700 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
14702 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14703 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14711 rs6000_instantiate_decls (void)
14713 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
14714 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
14717 /* Given an rtx X being reloaded into a reg required to be
14718 in class CLASS, return the class of reg to actually use.
14719 In general this is just CLASS; but on some machines
14720 in some cases it is preferable to use a more restrictive class.
14722 On the RS/6000, we have to return NO_REGS when we want to reload a
14723 floating-point CONST_DOUBLE to force it to be copied to memory.
14725 We also don't want to reload integer values into floating-point
14726 registers if we can at all help it. In fact, this can
14727 cause reload to die, if it tries to generate a reload of CTR
14728 into a FP register and discovers it doesn't have the memory location
14731 ??? Would it be a good idea to have reload do the converse, that is
14732 try to reload floating modes into FP registers if possible?
14735 static enum reg_class
14736 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
14738 enum machine_mode mode = GET_MODE (x);
14740 if (VECTOR_UNIT_VSX_P (mode)
14741 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
14744 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
14745 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
14746 && easy_vector_constant (x, mode))
14747 return ALTIVEC_REGS;
14749 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
14752 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
14753 return GENERAL_REGS;
14755 /* For VSX, prefer the traditional registers for 64-bit values because we can
14756 use the non-VSX loads. Prefer the Altivec registers if Altivec is
14757 handling the vector operations (i.e. V16QI, V8HI, and V4SI), or if we
14758 prefer Altivec loads.. */
14759 if (rclass == VSX_REGS)
14761 if (GET_MODE_SIZE (mode) <= 8)
14764 if (VECTOR_UNIT_ALTIVEC_P (mode) || VECTOR_MEM_ALTIVEC_P (mode))
14765 return ALTIVEC_REGS;
14773 /* Debug version of rs6000_preferred_reload_class. */
14774 static enum reg_class
14775 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
14777 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
14780 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
14782 reg_class_names[ret], reg_class_names[rclass],
14783 GET_MODE_NAME (GET_MODE (x)));
14789 /* If we are copying between FP or AltiVec registers and anything else, we need
14790 a memory location. The exception is when we are targeting ppc64 and the
14791 move to/from fpr to gpr instructions are available. Also, under VSX, you
14792 can copy vector registers from the FP register set to the Altivec register
14793 set and vice versa. */
14796 rs6000_secondary_memory_needed (enum reg_class class1,
14797 enum reg_class class2,
14798 enum machine_mode mode)
14800 if (class1 == class2)
14803 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
14804 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
14805 between these classes. But we need memory for other things that can go in
14806 FLOAT_REGS like SFmode. */
14808 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
14809 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
14810 || class1 == FLOAT_REGS))
14811 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
14812 && class2 != FLOAT_REGS);
14814 if (class1 == VSX_REGS || class2 == VSX_REGS)
14817 if (class1 == FLOAT_REGS
14818 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14819 || ((mode != DFmode)
14820 && (mode != DDmode)
14821 && (mode != DImode))))
14824 if (class2 == FLOAT_REGS
14825 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14826 || ((mode != DFmode)
14827 && (mode != DDmode)
14828 && (mode != DImode))))
14831 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
14837 /* Debug version of rs6000_secondary_memory_needed. */
14839 rs6000_debug_secondary_memory_needed (enum reg_class class1,
14840 enum reg_class class2,
14841 enum machine_mode mode)
14843 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
14846 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
14847 "class2 = %s, mode = %s\n",
14848 ret ? "true" : "false", reg_class_names[class1],
14849 reg_class_names[class2], GET_MODE_NAME (mode));
14854 /* Return the register class of a scratch register needed to copy IN into
14855 or out of a register in RCLASS in MODE. If it can be done directly,
14856 NO_REGS is returned. */
14858 static enum reg_class
14859 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
14864 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
14866 && MACHOPIC_INDIRECT
14870 /* We cannot copy a symbolic operand directly into anything
14871 other than BASE_REGS for TARGET_ELF. So indicate that a
14872 register from BASE_REGS is needed as an intermediate
14875 On Darwin, pic addresses require a load from memory, which
14876 needs a base register. */
14877 if (rclass != BASE_REGS
14878 && (GET_CODE (in) == SYMBOL_REF
14879 || GET_CODE (in) == HIGH
14880 || GET_CODE (in) == LABEL_REF
14881 || GET_CODE (in) == CONST))
14885 if (GET_CODE (in) == REG)
14887 regno = REGNO (in);
14888 if (regno >= FIRST_PSEUDO_REGISTER)
14890 regno = true_regnum (in);
14891 if (regno >= FIRST_PSEUDO_REGISTER)
14895 else if (GET_CODE (in) == SUBREG)
14897 regno = true_regnum (in);
14898 if (regno >= FIRST_PSEUDO_REGISTER)
14904 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
14906 if (rclass == GENERAL_REGS || rclass == BASE_REGS
14907 || (regno >= 0 && INT_REGNO_P (regno)))
14910 /* Constants, memory, and FP registers can go into FP registers. */
14911 if ((regno == -1 || FP_REGNO_P (regno))
14912 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
14913 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
14915 /* Memory, and FP/altivec registers can go into fp/altivec registers under
14918 && (regno == -1 || VSX_REGNO_P (regno))
14919 && VSX_REG_CLASS_P (rclass))
14922 /* Memory, and AltiVec registers can go into AltiVec registers. */
14923 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
14924 && rclass == ALTIVEC_REGS)
14927 /* We can copy among the CR registers. */
14928 if ((rclass == CR_REGS || rclass == CR0_REGS)
14929 && regno >= 0 && CR_REGNO_P (regno))
14932 /* Otherwise, we need GENERAL_REGS. */
14933 return GENERAL_REGS;
14936 /* Debug version of rs6000_secondary_reload_class. */
14937 static enum reg_class
14938 rs6000_debug_secondary_reload_class (enum reg_class rclass,
14939 enum machine_mode mode, rtx in)
14941 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
14943 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
14944 "mode = %s, input rtx:\n",
14945 reg_class_names[ret], reg_class_names[rclass],
14946 GET_MODE_NAME (mode));
14952 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
14955 rs6000_cannot_change_mode_class (enum machine_mode from,
14956 enum machine_mode to,
14957 enum reg_class rclass)
14959 unsigned from_size = GET_MODE_SIZE (from);
14960 unsigned to_size = GET_MODE_SIZE (to);
14962 if (from_size != to_size)
14964 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
14965 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
14966 && reg_classes_intersect_p (xclass, rclass));
14969 if (TARGET_E500_DOUBLE
14970 && ((((to) == DFmode) + ((from) == DFmode)) == 1
14971 || (((to) == TFmode) + ((from) == TFmode)) == 1
14972 || (((to) == DDmode) + ((from) == DDmode)) == 1
14973 || (((to) == TDmode) + ((from) == TDmode)) == 1
14974 || (((to) == DImode) + ((from) == DImode)) == 1))
14977 /* Since the VSX register set includes traditional floating point registers
14978 and altivec registers, just check for the size being different instead of
14979 trying to check whether the modes are vector modes. Otherwise it won't
14980 allow say DF and DI to change classes. */
14981 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
14982 return (from_size != 8 && from_size != 16);
14984 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
14985 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
14988 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
14989 && reg_classes_intersect_p (GENERAL_REGS, rclass))
14995 /* Debug version of rs6000_cannot_change_mode_class. */
14997 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
14998 enum machine_mode to,
14999 enum reg_class rclass)
15001 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
15004 "rs6000_cannot_change_mode_class, return %s, from = %s, "
15005 "to = %s, rclass = %s\n",
15006 ret ? "true" : "false",
15007 GET_MODE_NAME (from), GET_MODE_NAME (to),
15008 reg_class_names[rclass]);
15013 /* Given a comparison operation, return the bit number in CCR to test. We
15014 know this is a valid comparison.
15016 SCC_P is 1 if this is for an scc. That means that %D will have been
15017 used instead of %C, so the bits will be in different places.
15019 Return -1 if OP isn't a valid comparison for some reason. */
15022 ccr_bit (rtx op, int scc_p)
15024 enum rtx_code code = GET_CODE (op);
15025 enum machine_mode cc_mode;
15030 if (!COMPARISON_P (op))
15033 reg = XEXP (op, 0);
15035 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
15037 cc_mode = GET_MODE (reg);
15038 cc_regnum = REGNO (reg);
15039 base_bit = 4 * (cc_regnum - CR0_REGNO);
15041 validate_condition_mode (code, cc_mode);
15043 /* When generating a sCOND operation, only positive conditions are
15046 || code == EQ || code == GT || code == LT || code == UNORDERED
15047 || code == GTU || code == LTU);
15052 return scc_p ? base_bit + 3 : base_bit + 2;
15054 return base_bit + 2;
15055 case GT: case GTU: case UNLE:
15056 return base_bit + 1;
15057 case LT: case LTU: case UNGE:
15059 case ORDERED: case UNORDERED:
15060 return base_bit + 3;
15063 /* If scc, we will have done a cror to put the bit in the
15064 unordered position. So test that bit. For integer, this is ! LT
15065 unless this is an scc insn. */
15066 return scc_p ? base_bit + 3 : base_bit;
15069 return scc_p ? base_bit + 3 : base_bit + 1;
15072 gcc_unreachable ();
15076 /* Return the GOT register. */
15079 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
15081 /* The second flow pass currently (June 1999) can't update
15082 regs_ever_live without disturbing other parts of the compiler, so
15083 update it here to make the prolog/epilogue code happy. */
15084 if (!can_create_pseudo_p ()
15085 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
15086 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
15088 crtl->uses_pic_offset_table = 1;
15090 return pic_offset_table_rtx;
15093 static rs6000_stack_t stack_info;
15095 /* Function to init struct machine_function.
15096 This will be called, via a pointer variable,
15097 from push_function_context. */
15099 static struct machine_function *
15100 rs6000_init_machine_status (void)
15102 stack_info.reload_completed = 0;
15103 return ggc_alloc_cleared_machine_function ();
15106 /* These macros test for integers and extract the low-order bits. */
15108 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
15109 && GET_MODE (X) == VOIDmode)
15111 #define INT_LOWPART(X) \
15112 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
15115 extract_MB (rtx op)
15118 unsigned long val = INT_LOWPART (op);
15120 /* If the high bit is zero, the value is the first 1 bit we find
15122 if ((val & 0x80000000) == 0)
15124 gcc_assert (val & 0xffffffff);
15127 while (((val <<= 1) & 0x80000000) == 0)
15132 /* If the high bit is set and the low bit is not, or the mask is all
15133 1's, the value is zero. */
15134 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
15137 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15140 while (((val >>= 1) & 1) != 0)
15147 extract_ME (rtx op)
15150 unsigned long val = INT_LOWPART (op);
15152 /* If the low bit is zero, the value is the first 1 bit we find from
15154 if ((val & 1) == 0)
15156 gcc_assert (val & 0xffffffff);
15159 while (((val >>= 1) & 1) == 0)
15165 /* If the low bit is set and the high bit is not, or the mask is all
15166 1's, the value is 31. */
15167 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
15170 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15173 while (((val <<= 1) & 0x80000000) != 0)
15179 /* Locate some local-dynamic symbol still in use by this function
15180 so that we can print its name in some tls_ld pattern. */
15182 static const char *
15183 rs6000_get_some_local_dynamic_name (void)
15187 if (cfun->machine->some_ld_name)
15188 return cfun->machine->some_ld_name;
15190 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
15192 && for_each_rtx (&PATTERN (insn),
15193 rs6000_get_some_local_dynamic_name_1, 0))
15194 return cfun->machine->some_ld_name;
15196 gcc_unreachable ();
15199 /* Helper function for rs6000_get_some_local_dynamic_name. */
15202 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
15206 if (GET_CODE (x) == SYMBOL_REF)
15208 const char *str = XSTR (x, 0);
15209 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
15211 cfun->machine->some_ld_name = str;
15219 /* Write out a function code label. */
15222 rs6000_output_function_entry (FILE *file, const char *fname)
15224 if (fname[0] != '.')
15226 switch (DEFAULT_ABI)
15229 gcc_unreachable ();
15235 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
15244 RS6000_OUTPUT_BASENAME (file, fname);
15247 /* Print an operand. Recognize special options, documented below. */
15250 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
15251 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
15253 #define SMALL_DATA_RELOC "sda21"
15254 #define SMALL_DATA_REG 0
15258 print_operand (FILE *file, rtx x, int code)
15262 unsigned HOST_WIDE_INT uval;
15267 /* Write out an instruction after the call which may be replaced
15268 with glue code by the loader. This depends on the AIX version. */
15269 asm_fprintf (file, RS6000_CALL_GLUE);
15272 /* %a is output_address. */
15275 /* If X is a constant integer whose low-order 5 bits are zero,
15276 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
15277 in the AIX assembler where "sri" with a zero shift count
15278 writes a trash instruction. */
15279 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
15286 /* If constant, low-order 16 bits of constant, unsigned.
15287 Otherwise, write normally. */
15289 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
15291 print_operand (file, x, 0);
15295 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
15296 for 64-bit mask direction. */
15297 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
15300 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
15304 /* X is a CR register. Print the number of the GT bit of the CR. */
15305 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15306 output_operand_lossage ("invalid %%c value");
15308 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
15312 /* Like 'J' but get to the GT bit only. */
15313 gcc_assert (GET_CODE (x) == REG);
15315 /* Bit 1 is GT bit. */
15316 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
15318 /* Add one for shift count in rlinm for scc. */
15319 fprintf (file, "%d", i + 1);
15323 /* X is a CR register. Print the number of the EQ bit of the CR */
15324 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15325 output_operand_lossage ("invalid %%E value");
15327 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
15331 /* X is a CR register. Print the shift count needed to move it
15332 to the high-order four bits. */
15333 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15334 output_operand_lossage ("invalid %%f value");
15336 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
15340 /* Similar, but print the count for the rotate in the opposite
15342 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15343 output_operand_lossage ("invalid %%F value");
15345 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
15349 /* X is a constant integer. If it is negative, print "m",
15350 otherwise print "z". This is to make an aze or ame insn. */
15351 if (GET_CODE (x) != CONST_INT)
15352 output_operand_lossage ("invalid %%G value");
15353 else if (INTVAL (x) >= 0)
15360 /* If constant, output low-order five bits. Otherwise, write
15363 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
15365 print_operand (file, x, 0);
15369 /* If constant, output low-order six bits. Otherwise, write
15372 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
15374 print_operand (file, x, 0);
15378 /* Print `i' if this is a constant, else nothing. */
15384 /* Write the bit number in CCR for jump. */
15385 i = ccr_bit (x, 0);
15387 output_operand_lossage ("invalid %%j code");
15389 fprintf (file, "%d", i);
15393 /* Similar, but add one for shift count in rlinm for scc and pass
15394 scc flag to `ccr_bit'. */
15395 i = ccr_bit (x, 1);
15397 output_operand_lossage ("invalid %%J code");
15399 /* If we want bit 31, write a shift count of zero, not 32. */
15400 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15404 /* X must be a constant. Write the 1's complement of the
15407 output_operand_lossage ("invalid %%k value");
15409 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
15413 /* X must be a symbolic constant on ELF. Write an
15414 expression suitable for an 'addi' that adds in the low 16
15415 bits of the MEM. */
15416 if (GET_CODE (x) == CONST)
15418 if (GET_CODE (XEXP (x, 0)) != PLUS
15419 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
15420 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
15421 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
15422 output_operand_lossage ("invalid %%K value");
15424 print_operand_address (file, x);
15425 fputs ("@l", file);
15428 /* %l is output_asm_label. */
15431 /* Write second word of DImode or DFmode reference. Works on register
15432 or non-indexed memory only. */
15433 if (GET_CODE (x) == REG)
15434 fputs (reg_names[REGNO (x) + 1], file);
15435 else if (GET_CODE (x) == MEM)
15437 /* Handle possible auto-increment. Since it is pre-increment and
15438 we have already done it, we can just use an offset of word. */
15439 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15440 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15441 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15443 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15444 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15447 output_address (XEXP (adjust_address_nv (x, SImode,
15451 if (small_data_operand (x, GET_MODE (x)))
15452 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15453 reg_names[SMALL_DATA_REG]);
15458 /* MB value for a mask operand. */
15459 if (! mask_operand (x, SImode))
15460 output_operand_lossage ("invalid %%m value");
15462 fprintf (file, "%d", extract_MB (x));
15466 /* ME value for a mask operand. */
15467 if (! mask_operand (x, SImode))
15468 output_operand_lossage ("invalid %%M value");
15470 fprintf (file, "%d", extract_ME (x));
15473 /* %n outputs the negative of its operand. */
15476 /* Write the number of elements in the vector times 4. */
15477 if (GET_CODE (x) != PARALLEL)
15478 output_operand_lossage ("invalid %%N value");
15480 fprintf (file, "%d", XVECLEN (x, 0) * 4);
15484 /* Similar, but subtract 1 first. */
15485 if (GET_CODE (x) != PARALLEL)
15486 output_operand_lossage ("invalid %%O value");
15488 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
15492 /* X is a CONST_INT that is a power of two. Output the logarithm. */
15494 || INT_LOWPART (x) < 0
15495 || (i = exact_log2 (INT_LOWPART (x))) < 0)
15496 output_operand_lossage ("invalid %%p value");
15498 fprintf (file, "%d", i);
15502 /* The operand must be an indirect memory reference. The result
15503 is the register name. */
15504 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
15505 || REGNO (XEXP (x, 0)) >= 32)
15506 output_operand_lossage ("invalid %%P value");
15508 fputs (reg_names[REGNO (XEXP (x, 0))], file);
15512 /* This outputs the logical code corresponding to a boolean
15513 expression. The expression may have one or both operands
15514 negated (if one, only the first one). For condition register
15515 logical operations, it will also treat the negated
15516 CR codes as NOTs, but not handle NOTs of them. */
15518 const char *const *t = 0;
15520 enum rtx_code code = GET_CODE (x);
15521 static const char * const tbl[3][3] = {
15522 { "and", "andc", "nor" },
15523 { "or", "orc", "nand" },
15524 { "xor", "eqv", "xor" } };
15528 else if (code == IOR)
15530 else if (code == XOR)
15533 output_operand_lossage ("invalid %%q value");
15535 if (GET_CODE (XEXP (x, 0)) != NOT)
15539 if (GET_CODE (XEXP (x, 1)) == NOT)
15557 /* X is a CR register. Print the mask for `mtcrf'. */
15558 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15559 output_operand_lossage ("invalid %%R value");
15561 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
15565 /* Low 5 bits of 32 - value */
15567 output_operand_lossage ("invalid %%s value");
15569 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
15573 /* PowerPC64 mask position. All 0's is excluded.
15574 CONST_INT 32-bit mask is considered sign-extended so any
15575 transition must occur within the CONST_INT, not on the boundary. */
15576 if (! mask64_operand (x, DImode))
15577 output_operand_lossage ("invalid %%S value");
15579 uval = INT_LOWPART (x);
15581 if (uval & 1) /* Clear Left */
15583 #if HOST_BITS_PER_WIDE_INT > 64
15584 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15588 else /* Clear Right */
15591 #if HOST_BITS_PER_WIDE_INT > 64
15592 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15598 gcc_assert (i >= 0);
15599 fprintf (file, "%d", i);
15603 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
15604 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
15606 /* Bit 3 is OV bit. */
15607 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
15609 /* If we want bit 31, write a shift count of zero, not 32. */
15610 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15614 /* Print the symbolic name of a branch target register. */
15615 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
15616 && REGNO (x) != CTR_REGNO))
15617 output_operand_lossage ("invalid %%T value");
15618 else if (REGNO (x) == LR_REGNO)
15619 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
15621 fputs ("ctr", file);
15625 /* High-order 16 bits of constant for use in unsigned operand. */
15627 output_operand_lossage ("invalid %%u value");
15629 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15630 (INT_LOWPART (x) >> 16) & 0xffff);
15634 /* High-order 16 bits of constant for use in signed operand. */
15636 output_operand_lossage ("invalid %%v value");
15638 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15639 (INT_LOWPART (x) >> 16) & 0xffff);
15643 /* Print `u' if this has an auto-increment or auto-decrement. */
15644 if (GET_CODE (x) == MEM
15645 && (GET_CODE (XEXP (x, 0)) == PRE_INC
15646 || GET_CODE (XEXP (x, 0)) == PRE_DEC
15647 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
15652 /* Print the trap code for this operand. */
15653 switch (GET_CODE (x))
15656 fputs ("eq", file); /* 4 */
15659 fputs ("ne", file); /* 24 */
15662 fputs ("lt", file); /* 16 */
15665 fputs ("le", file); /* 20 */
15668 fputs ("gt", file); /* 8 */
15671 fputs ("ge", file); /* 12 */
15674 fputs ("llt", file); /* 2 */
15677 fputs ("lle", file); /* 6 */
15680 fputs ("lgt", file); /* 1 */
15683 fputs ("lge", file); /* 5 */
15686 gcc_unreachable ();
15691 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
15694 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
15695 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
15697 print_operand (file, x, 0);
15701 /* MB value for a PowerPC64 rldic operand. */
15702 val = (GET_CODE (x) == CONST_INT
15703 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
15708 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
15709 if ((val <<= 1) < 0)
15712 #if HOST_BITS_PER_WIDE_INT == 32
15713 if (GET_CODE (x) == CONST_INT && i >= 0)
15714 i += 32; /* zero-extend high-part was all 0's */
15715 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
15717 val = CONST_DOUBLE_LOW (x);
15723 for ( ; i < 64; i++)
15724 if ((val <<= 1) < 0)
15729 fprintf (file, "%d", i + 1);
15733 /* X is a FPR or Altivec register used in a VSX context. */
15734 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
15735 output_operand_lossage ("invalid %%x value");
15738 int reg = REGNO (x);
15739 int vsx_reg = (FP_REGNO_P (reg)
15741 : reg - FIRST_ALTIVEC_REGNO + 32);
15743 #ifdef TARGET_REGNAMES
15744 if (TARGET_REGNAMES)
15745 fprintf (file, "%%vs%d", vsx_reg);
15748 fprintf (file, "%d", vsx_reg);
15753 if (GET_CODE (x) == MEM
15754 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
15755 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
15756 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
15761 /* Like 'L', for third word of TImode */
15762 if (GET_CODE (x) == REG)
15763 fputs (reg_names[REGNO (x) + 2], file);
15764 else if (GET_CODE (x) == MEM)
15766 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15767 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15768 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15769 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15770 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15772 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
15773 if (small_data_operand (x, GET_MODE (x)))
15774 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15775 reg_names[SMALL_DATA_REG]);
15780 /* X is a SYMBOL_REF. Write out the name preceded by a
15781 period and without any trailing data in brackets. Used for function
15782 names. If we are configured for System V (or the embedded ABI) on
15783 the PowerPC, do not emit the period, since those systems do not use
15784 TOCs and the like. */
15785 gcc_assert (GET_CODE (x) == SYMBOL_REF);
15787 /* Mark the decl as referenced so that cgraph will output the
15789 if (SYMBOL_REF_DECL (x))
15790 mark_decl_referenced (SYMBOL_REF_DECL (x));
15792 /* For macho, check to see if we need a stub. */
15795 const char *name = XSTR (x, 0);
15797 if (darwin_emit_branch_islands
15798 && MACHOPIC_INDIRECT
15799 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
15800 name = machopic_indirection_name (x, /*stub_p=*/true);
15802 assemble_name (file, name);
15804 else if (!DOT_SYMBOLS)
15805 assemble_name (file, XSTR (x, 0));
15807 rs6000_output_function_entry (file, XSTR (x, 0));
15811 /* Like 'L', for last word of TImode. */
15812 if (GET_CODE (x) == REG)
15813 fputs (reg_names[REGNO (x) + 3], file);
15814 else if (GET_CODE (x) == MEM)
15816 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15817 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15818 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15819 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15820 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15822 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
15823 if (small_data_operand (x, GET_MODE (x)))
15824 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15825 reg_names[SMALL_DATA_REG]);
15829 /* Print AltiVec or SPE memory operand. */
15834 gcc_assert (GET_CODE (x) == MEM);
15838 /* Ugly hack because %y is overloaded. */
15839 if ((TARGET_SPE || TARGET_E500_DOUBLE)
15840 && (GET_MODE_SIZE (GET_MODE (x)) == 8
15841 || GET_MODE (x) == TFmode
15842 || GET_MODE (x) == TImode))
15844 /* Handle [reg]. */
15845 if (GET_CODE (tmp) == REG)
15847 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
15850 /* Handle [reg+UIMM]. */
15851 else if (GET_CODE (tmp) == PLUS &&
15852 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
15856 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
15858 x = INTVAL (XEXP (tmp, 1));
15859 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
15863 /* Fall through. Must be [reg+reg]. */
15865 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
15866 && GET_CODE (tmp) == AND
15867 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
15868 && INTVAL (XEXP (tmp, 1)) == -16)
15869 tmp = XEXP (tmp, 0);
15870 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
15871 && GET_CODE (tmp) == PRE_MODIFY)
15872 tmp = XEXP (tmp, 1);
15873 if (GET_CODE (tmp) == REG)
15874 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
15877 if (!GET_CODE (tmp) == PLUS
15878 || !REG_P (XEXP (tmp, 0))
15879 || !REG_P (XEXP (tmp, 1)))
15881 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
15885 if (REGNO (XEXP (tmp, 0)) == 0)
15886 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
15887 reg_names[ REGNO (XEXP (tmp, 0)) ]);
15889 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
15890 reg_names[ REGNO (XEXP (tmp, 1)) ]);
15896 if (GET_CODE (x) == REG)
15897 fprintf (file, "%s", reg_names[REGNO (x)]);
15898 else if (GET_CODE (x) == MEM)
15900 /* We need to handle PRE_INC and PRE_DEC here, since we need to
15901 know the width from the mode. */
15902 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
15903 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
15904 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
15905 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
15906 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
15907 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
15908 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15909 output_address (XEXP (XEXP (x, 0), 1));
15911 output_address (XEXP (x, 0));
15915 if (toc_relative_expr_p (x))
15916 /* This hack along with a corresponding hack in
15917 rs6000_output_addr_const_extra arranges to output addends
15918 where the assembler expects to find them. eg.
15919 (const (plus (unspec [symbol_ref ("x") tocrel]) 4))
15920 without this hack would be output as "x@toc+4". We
15922 output_addr_const (file, tocrel_base);
15924 output_addr_const (file, x);
15929 assemble_name (file, rs6000_get_some_local_dynamic_name ());
15933 output_operand_lossage ("invalid %%xn code");
15937 /* Print the address of an operand. */
15940 print_operand_address (FILE *file, rtx x)
15942 if (GET_CODE (x) == REG)
15943 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
15944 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
15945 || GET_CODE (x) == LABEL_REF)
15947 output_addr_const (file, x);
15948 if (small_data_operand (x, GET_MODE (x)))
15949 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15950 reg_names[SMALL_DATA_REG]);
15952 gcc_assert (!TARGET_TOC);
15954 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
15956 gcc_assert (REG_P (XEXP (x, 0)));
15957 if (REGNO (XEXP (x, 0)) == 0)
15958 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
15959 reg_names[ REGNO (XEXP (x, 0)) ]);
15961 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
15962 reg_names[ REGNO (XEXP (x, 1)) ]);
15964 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
15965 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
15966 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
15968 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15969 && CONSTANT_P (XEXP (x, 1)))
15971 fprintf (file, "lo16(");
15972 output_addr_const (file, XEXP (x, 1));
15973 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15976 else if (legitimate_constant_pool_address_p (x, QImode, true))
15978 /* This hack along with a corresponding hack in
15979 rs6000_output_addr_const_extra arranges to output addends
15980 where the assembler expects to find them. eg.
15982 . (const (plus (unspec [symbol_ref ("x") tocrel]) 8)))
15983 without this hack would be output as "x@toc+8@l(9)". We
15984 want "x+8@toc@l(9)". */
15985 output_addr_const (file, tocrel_base);
15986 if (GET_CODE (x) == LO_SUM)
15987 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15989 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
15992 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15993 && CONSTANT_P (XEXP (x, 1)))
15995 output_addr_const (file, XEXP (x, 1));
15996 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16000 gcc_unreachable ();
16003 /* Implement TARGET_OUTPUT_ADDR_CONST_EXTRA. */
16006 rs6000_output_addr_const_extra (FILE *file, rtx x)
16008 if (GET_CODE (x) == UNSPEC)
16009 switch (XINT (x, 1))
16011 case UNSPEC_TOCREL:
16012 gcc_assert (GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF);
16013 output_addr_const (file, XVECEXP (x, 0, 0));
16014 if (x == tocrel_base && tocrel_offset != const0_rtx)
16016 if (INTVAL (tocrel_offset) >= 0)
16017 fprintf (file, "+");
16018 output_addr_const (file, tocrel_offset);
16020 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
16023 assemble_name (file, toc_label_name);
16025 else if (TARGET_ELF)
16026 fputs ("@toc", file);
16030 case UNSPEC_MACHOPIC_OFFSET:
16031 output_addr_const (file, XVECEXP (x, 0, 0));
16033 machopic_output_function_base_name (file);
16040 /* Target hook for assembling integer objects. The PowerPC version has
16041 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
16042 is defined. It also needs to handle DI-mode objects on 64-bit
16046 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
16048 #ifdef RELOCATABLE_NEEDS_FIXUP
16049 /* Special handling for SI values. */
16050 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
16052 static int recurse = 0;
16054 /* For -mrelocatable, we mark all addresses that need to be fixed up
16055 in the .fixup section. */
16056 if (TARGET_RELOCATABLE
16057 && in_section != toc_section
16058 && in_section != text_section
16059 && !unlikely_text_section_p (in_section)
16061 && GET_CODE (x) != CONST_INT
16062 && GET_CODE (x) != CONST_DOUBLE
16068 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
16070 ASM_OUTPUT_LABEL (asm_out_file, buf);
16071 fprintf (asm_out_file, "\t.long\t(");
16072 output_addr_const (asm_out_file, x);
16073 fprintf (asm_out_file, ")@fixup\n");
16074 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
16075 ASM_OUTPUT_ALIGN (asm_out_file, 2);
16076 fprintf (asm_out_file, "\t.long\t");
16077 assemble_name (asm_out_file, buf);
16078 fprintf (asm_out_file, "\n\t.previous\n");
16082 /* Remove initial .'s to turn a -mcall-aixdesc function
16083 address into the address of the descriptor, not the function
16085 else if (GET_CODE (x) == SYMBOL_REF
16086 && XSTR (x, 0)[0] == '.'
16087 && DEFAULT_ABI == ABI_AIX)
16089 const char *name = XSTR (x, 0);
16090 while (*name == '.')
16093 fprintf (asm_out_file, "\t.long\t%s\n", name);
16097 #endif /* RELOCATABLE_NEEDS_FIXUP */
16098 return default_assemble_integer (x, size, aligned_p);
16101 #if defined (HAVE_GAS_HIDDEN) && !defined (TARGET_MACHO)
16102 /* Emit an assembler directive to set symbol visibility for DECL to
16103 VISIBILITY_TYPE. */
16106 rs6000_assemble_visibility (tree decl, int vis)
16108 /* Functions need to have their entry point symbol visibility set as
16109 well as their descriptor symbol visibility. */
16110 if (DEFAULT_ABI == ABI_AIX
16112 && TREE_CODE (decl) == FUNCTION_DECL)
16114 static const char * const visibility_types[] = {
16115 NULL, "internal", "hidden", "protected"
16118 const char *name, *type;
16120 name = ((* targetm.strip_name_encoding)
16121 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
16122 type = visibility_types[vis];
16124 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
16125 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
16128 default_assemble_visibility (decl, vis);
16133 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
16135 /* Reversal of FP compares takes care -- an ordered compare
16136 becomes an unordered compare and vice versa. */
16137 if (mode == CCFPmode
16138 && (!flag_finite_math_only
16139 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
16140 || code == UNEQ || code == LTGT))
16141 return reverse_condition_maybe_unordered (code);
16143 return reverse_condition (code);
16146 /* Generate a compare for CODE. Return a brand-new rtx that
16147 represents the result of the compare. */
16150 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
16152 enum machine_mode comp_mode;
16153 rtx compare_result;
16154 enum rtx_code code = GET_CODE (cmp);
16155 rtx op0 = XEXP (cmp, 0);
16156 rtx op1 = XEXP (cmp, 1);
16158 if (FLOAT_MODE_P (mode))
16159 comp_mode = CCFPmode;
16160 else if (code == GTU || code == LTU
16161 || code == GEU || code == LEU)
16162 comp_mode = CCUNSmode;
16163 else if ((code == EQ || code == NE)
16164 && GET_CODE (op0) == SUBREG
16165 && GET_CODE (op1) == SUBREG
16166 && SUBREG_PROMOTED_UNSIGNED_P (op0)
16167 && SUBREG_PROMOTED_UNSIGNED_P (op1))
16168 /* These are unsigned values, perhaps there will be a later
16169 ordering compare that can be shared with this one.
16170 Unfortunately we cannot detect the signedness of the operands
16171 for non-subregs. */
16172 comp_mode = CCUNSmode;
16174 comp_mode = CCmode;
16176 /* First, the compare. */
16177 compare_result = gen_reg_rtx (comp_mode);
16179 /* E500 FP compare instructions on the GPRs. Yuck! */
16180 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
16181 && FLOAT_MODE_P (mode))
16183 rtx cmp, or_result, compare_result2;
16184 enum machine_mode op_mode = GET_MODE (op0);
16186 if (op_mode == VOIDmode)
16187 op_mode = GET_MODE (op1);
16189 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
16190 This explains the following mess. */
16194 case EQ: case UNEQ: case NE: case LTGT:
16198 cmp = (flag_finite_math_only && !flag_trapping_math)
16199 ? gen_tstsfeq_gpr (compare_result, op0, op1)
16200 : gen_cmpsfeq_gpr (compare_result, op0, op1);
16204 cmp = (flag_finite_math_only && !flag_trapping_math)
16205 ? gen_tstdfeq_gpr (compare_result, op0, op1)
16206 : gen_cmpdfeq_gpr (compare_result, op0, op1);
16210 cmp = (flag_finite_math_only && !flag_trapping_math)
16211 ? gen_tsttfeq_gpr (compare_result, op0, op1)
16212 : gen_cmptfeq_gpr (compare_result, op0, op1);
16216 gcc_unreachable ();
16220 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
16224 cmp = (flag_finite_math_only && !flag_trapping_math)
16225 ? gen_tstsfgt_gpr (compare_result, op0, op1)
16226 : gen_cmpsfgt_gpr (compare_result, op0, op1);
16230 cmp = (flag_finite_math_only && !flag_trapping_math)
16231 ? gen_tstdfgt_gpr (compare_result, op0, op1)
16232 : gen_cmpdfgt_gpr (compare_result, op0, op1);
16236 cmp = (flag_finite_math_only && !flag_trapping_math)
16237 ? gen_tsttfgt_gpr (compare_result, op0, op1)
16238 : gen_cmptfgt_gpr (compare_result, op0, op1);
16242 gcc_unreachable ();
16246 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
16250 cmp = (flag_finite_math_only && !flag_trapping_math)
16251 ? gen_tstsflt_gpr (compare_result, op0, op1)
16252 : gen_cmpsflt_gpr (compare_result, op0, op1);
16256 cmp = (flag_finite_math_only && !flag_trapping_math)
16257 ? gen_tstdflt_gpr (compare_result, op0, op1)
16258 : gen_cmpdflt_gpr (compare_result, op0, op1);
16262 cmp = (flag_finite_math_only && !flag_trapping_math)
16263 ? gen_tsttflt_gpr (compare_result, op0, op1)
16264 : gen_cmptflt_gpr (compare_result, op0, op1);
16268 gcc_unreachable ();
16272 gcc_unreachable ();
16275 /* Synthesize LE and GE from LT/GT || EQ. */
16276 if (code == LE || code == GE || code == LEU || code == GEU)
16282 case LE: code = LT; break;
16283 case GE: code = GT; break;
16284 case LEU: code = LT; break;
16285 case GEU: code = GT; break;
16286 default: gcc_unreachable ();
16289 compare_result2 = gen_reg_rtx (CCFPmode);
16295 cmp = (flag_finite_math_only && !flag_trapping_math)
16296 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
16297 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
16301 cmp = (flag_finite_math_only && !flag_trapping_math)
16302 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
16303 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
16307 cmp = (flag_finite_math_only && !flag_trapping_math)
16308 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
16309 : gen_cmptfeq_gpr (compare_result2, op0, op1);
16313 gcc_unreachable ();
16317 /* OR them together. */
16318 or_result = gen_reg_rtx (CCFPmode);
16319 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
16321 compare_result = or_result;
16326 if (code == NE || code == LTGT)
16336 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
16337 CLOBBERs to match cmptf_internal2 pattern. */
16338 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
16339 && GET_MODE (op0) == TFmode
16340 && !TARGET_IEEEQUAD
16341 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
16342 emit_insn (gen_rtx_PARALLEL (VOIDmode,
16344 gen_rtx_SET (VOIDmode,
16346 gen_rtx_COMPARE (comp_mode, op0, op1)),
16347 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16348 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16349 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16350 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16351 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16352 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16353 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16354 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16355 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (Pmode)))));
16356 else if (GET_CODE (op1) == UNSPEC
16357 && XINT (op1, 1) == UNSPEC_SP_TEST)
16359 rtx op1b = XVECEXP (op1, 0, 0);
16360 comp_mode = CCEQmode;
16361 compare_result = gen_reg_rtx (CCEQmode);
16363 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
16365 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
16368 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
16369 gen_rtx_COMPARE (comp_mode, op0, op1)));
16372 /* Some kinds of FP comparisons need an OR operation;
16373 under flag_finite_math_only we don't bother. */
16374 if (FLOAT_MODE_P (mode)
16375 && !flag_finite_math_only
16376 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
16377 && (code == LE || code == GE
16378 || code == UNEQ || code == LTGT
16379 || code == UNGT || code == UNLT))
16381 enum rtx_code or1, or2;
16382 rtx or1_rtx, or2_rtx, compare2_rtx;
16383 rtx or_result = gen_reg_rtx (CCEQmode);
16387 case LE: or1 = LT; or2 = EQ; break;
16388 case GE: or1 = GT; or2 = EQ; break;
16389 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
16390 case LTGT: or1 = LT; or2 = GT; break;
16391 case UNGT: or1 = UNORDERED; or2 = GT; break;
16392 case UNLT: or1 = UNORDERED; or2 = LT; break;
16393 default: gcc_unreachable ();
16395 validate_condition_mode (or1, comp_mode);
16396 validate_condition_mode (or2, comp_mode);
16397 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
16398 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
16399 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
16400 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
16402 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
16404 compare_result = or_result;
16408 validate_condition_mode (code, GET_MODE (compare_result));
16410 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
16414 /* Emit the RTL for an sISEL pattern. */
16417 rs6000_emit_sISEL (enum machine_mode mode ATTRIBUTE_UNUSED, rtx operands[])
16419 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
16423 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
16426 enum machine_mode op_mode;
16427 enum rtx_code cond_code;
16428 rtx result = operands[0];
16430 if (TARGET_ISEL && (mode == SImode || mode == DImode))
16432 rs6000_emit_sISEL (mode, operands);
16436 condition_rtx = rs6000_generate_compare (operands[1], mode);
16437 cond_code = GET_CODE (condition_rtx);
16439 if (FLOAT_MODE_P (mode)
16440 && !TARGET_FPRS && TARGET_HARD_FLOAT)
16444 PUT_MODE (condition_rtx, SImode);
16445 t = XEXP (condition_rtx, 0);
16447 gcc_assert (cond_code == NE || cond_code == EQ);
16449 if (cond_code == NE)
16450 emit_insn (gen_e500_flip_gt_bit (t, t));
16452 emit_insn (gen_move_from_CR_gt_bit (result, t));
16456 if (cond_code == NE
16457 || cond_code == GE || cond_code == LE
16458 || cond_code == GEU || cond_code == LEU
16459 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
16461 rtx not_result = gen_reg_rtx (CCEQmode);
16462 rtx not_op, rev_cond_rtx;
16463 enum machine_mode cc_mode;
16465 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
16467 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
16468 SImode, XEXP (condition_rtx, 0), const0_rtx);
16469 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
16470 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
16471 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
16474 op_mode = GET_MODE (XEXP (operands[1], 0));
16475 if (op_mode == VOIDmode)
16476 op_mode = GET_MODE (XEXP (operands[1], 1));
16478 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
16480 PUT_MODE (condition_rtx, DImode);
16481 convert_move (result, condition_rtx, 0);
16485 PUT_MODE (condition_rtx, SImode);
16486 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
16490 /* Emit a branch of kind CODE to location LOC. */
16493 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
16495 rtx condition_rtx, loc_ref;
16497 condition_rtx = rs6000_generate_compare (operands[0], mode);
16498 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
16499 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
16500 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
16501 loc_ref, pc_rtx)));
16504 /* Return the string to output a conditional branch to LABEL, which is
16505 the operand number of the label, or -1 if the branch is really a
16506 conditional return.
16508 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
16509 condition code register and its mode specifies what kind of
16510 comparison we made.
16512 REVERSED is nonzero if we should reverse the sense of the comparison.
16514 INSN is the insn. */
16517 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
16519 static char string[64];
16520 enum rtx_code code = GET_CODE (op);
16521 rtx cc_reg = XEXP (op, 0);
16522 enum machine_mode mode = GET_MODE (cc_reg);
16523 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
16524 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
16525 int really_reversed = reversed ^ need_longbranch;
16531 validate_condition_mode (code, mode);
16533 /* Work out which way this really branches. We could use
16534 reverse_condition_maybe_unordered here always but this
16535 makes the resulting assembler clearer. */
16536 if (really_reversed)
16538 /* Reversal of FP compares takes care -- an ordered compare
16539 becomes an unordered compare and vice versa. */
16540 if (mode == CCFPmode)
16541 code = reverse_condition_maybe_unordered (code);
16543 code = reverse_condition (code);
16546 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
16548 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
16553 /* Opposite of GT. */
16562 gcc_unreachable ();
16568 /* Not all of these are actually distinct opcodes, but
16569 we distinguish them for clarity of the resulting assembler. */
16570 case NE: case LTGT:
16571 ccode = "ne"; break;
16572 case EQ: case UNEQ:
16573 ccode = "eq"; break;
16575 ccode = "ge"; break;
16576 case GT: case GTU: case UNGT:
16577 ccode = "gt"; break;
16579 ccode = "le"; break;
16580 case LT: case LTU: case UNLT:
16581 ccode = "lt"; break;
16582 case UNORDERED: ccode = "un"; break;
16583 case ORDERED: ccode = "nu"; break;
16584 case UNGE: ccode = "nl"; break;
16585 case UNLE: ccode = "ng"; break;
16587 gcc_unreachable ();
16590 /* Maybe we have a guess as to how likely the branch is.
16591 The old mnemonics don't have a way to specify this information. */
16593 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
16594 if (note != NULL_RTX)
16596 /* PROB is the difference from 50%. */
16597 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
16599 /* Only hint for highly probable/improbable branches on newer
16600 cpus as static prediction overrides processor dynamic
16601 prediction. For older cpus we may as well always hint, but
16602 assume not taken for branches that are very close to 50% as a
16603 mispredicted taken branch is more expensive than a
16604 mispredicted not-taken branch. */
16605 if (rs6000_always_hint
16606 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
16607 && br_prob_note_reliable_p (note)))
16609 if (abs (prob) > REG_BR_PROB_BASE / 20
16610 && ((prob > 0) ^ need_longbranch))
16618 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
16620 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
16622 /* We need to escape any '%' characters in the reg_names string.
16623 Assume they'd only be the first character.... */
16624 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
16626 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
16630 /* If the branch distance was too far, we may have to use an
16631 unconditional branch to go the distance. */
16632 if (need_longbranch)
16633 s += sprintf (s, ",$+8\n\tb %s", label);
16635 s += sprintf (s, ",%s", label);
16641 /* Return the string to flip the GT bit on a CR. */
16643 output_e500_flip_gt_bit (rtx dst, rtx src)
16645 static char string[64];
16648 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
16649 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
16652 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
16653 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
16655 sprintf (string, "crnot %d,%d", a, b);
16659 /* Return insn for VSX or Altivec comparisons. */
16662 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
16665 enum machine_mode mode = GET_MODE (op0);
16673 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
16679 mask = gen_reg_rtx (mode);
16680 emit_insn (gen_rtx_SET (VOIDmode,
16682 gen_rtx_fmt_ee (code, mode, op0, op1)));
16689 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
16690 DMODE is expected destination mode. This is a recursive function. */
16693 rs6000_emit_vector_compare (enum rtx_code rcode,
16695 enum machine_mode dmode)
16698 bool swap_operands = false;
16699 bool try_again = false;
16701 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
16702 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
16704 /* See if the comparison works as is. */
16705 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16713 swap_operands = true;
16718 swap_operands = true;
16726 /* Invert condition and try again.
16727 e.g., A != B becomes ~(A==B). */
16729 enum rtx_code rev_code;
16730 enum insn_code nor_code;
16733 rev_code = reverse_condition_maybe_unordered (rcode);
16734 if (rev_code == UNKNOWN)
16737 nor_code = optab_handler (one_cmpl_optab, dmode);
16738 if (nor_code == CODE_FOR_nothing)
16741 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
16745 mask = gen_reg_rtx (dmode);
16746 emit_insn (GEN_FCN (nor_code) (mask, mask2));
16754 /* Try GT/GTU/LT/LTU OR EQ */
16757 enum insn_code ior_code;
16758 enum rtx_code new_code;
16779 gcc_unreachable ();
16782 ior_code = optab_handler (ior_optab, dmode);
16783 if (ior_code == CODE_FOR_nothing)
16786 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
16790 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
16794 mask = gen_reg_rtx (dmode);
16795 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
16813 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16818 /* You only get two chances. */
16822 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
16823 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
16824 operands for the relation operation COND. */
16827 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
16828 rtx cond, rtx cc_op0, rtx cc_op1)
16830 enum machine_mode dest_mode = GET_MODE (dest);
16831 enum rtx_code rcode = GET_CODE (cond);
16832 enum machine_mode cc_mode = CCmode;
16836 bool invert_move = false;
16838 if (VECTOR_UNIT_NONE_P (dest_mode))
16843 /* Swap operands if we can, and fall back to doing the operation as
16844 specified, and doing a NOR to invert the test. */
16850 /* Invert condition and try again.
16851 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
16852 invert_move = true;
16853 rcode = reverse_condition_maybe_unordered (rcode);
16854 if (rcode == UNKNOWN)
16858 /* Mark unsigned tests with CCUNSmode. */
16863 cc_mode = CCUNSmode;
16870 /* Get the vector mask for the given relational operations. */
16871 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
16879 op_true = op_false;
16883 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, CONST0_RTX (dest_mode));
16884 emit_insn (gen_rtx_SET (VOIDmode,
16886 gen_rtx_IF_THEN_ELSE (dest_mode,
16893 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
16894 operands of the last comparison is nonzero/true, FALSE_COND if it
16895 is zero/false. Return 0 if the hardware has no such operation. */
16898 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
16900 enum rtx_code code = GET_CODE (op);
16901 rtx op0 = XEXP (op, 0);
16902 rtx op1 = XEXP (op, 1);
16903 REAL_VALUE_TYPE c1;
16904 enum machine_mode compare_mode = GET_MODE (op0);
16905 enum machine_mode result_mode = GET_MODE (dest);
16907 bool is_against_zero;
16909 /* These modes should always match. */
16910 if (GET_MODE (op1) != compare_mode
16911 /* In the isel case however, we can use a compare immediate, so
16912 op1 may be a small constant. */
16913 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
16915 if (GET_MODE (true_cond) != result_mode)
16917 if (GET_MODE (false_cond) != result_mode)
16920 /* First, work out if the hardware can do this at all, or
16921 if it's too slow.... */
16922 if (!FLOAT_MODE_P (compare_mode))
16925 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
16928 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
16929 && SCALAR_FLOAT_MODE_P (compare_mode))
16932 is_against_zero = op1 == CONST0_RTX (compare_mode);
16934 /* A floating-point subtract might overflow, underflow, or produce
16935 an inexact result, thus changing the floating-point flags, so it
16936 can't be generated if we care about that. It's safe if one side
16937 of the construct is zero, since then no subtract will be
16939 if (SCALAR_FLOAT_MODE_P (compare_mode)
16940 && flag_trapping_math && ! is_against_zero)
16943 /* Eliminate half of the comparisons by switching operands, this
16944 makes the remaining code simpler. */
16945 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
16946 || code == LTGT || code == LT || code == UNLE)
16948 code = reverse_condition_maybe_unordered (code);
16950 true_cond = false_cond;
16954 /* UNEQ and LTGT take four instructions for a comparison with zero,
16955 it'll probably be faster to use a branch here too. */
16956 if (code == UNEQ && HONOR_NANS (compare_mode))
16959 if (GET_CODE (op1) == CONST_DOUBLE)
16960 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
16962 /* We're going to try to implement comparisons by performing
16963 a subtract, then comparing against zero. Unfortunately,
16964 Inf - Inf is NaN which is not zero, and so if we don't
16965 know that the operand is finite and the comparison
16966 would treat EQ different to UNORDERED, we can't do it. */
16967 if (HONOR_INFINITIES (compare_mode)
16968 && code != GT && code != UNGE
16969 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
16970 /* Constructs of the form (a OP b ? a : b) are safe. */
16971 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
16972 || (! rtx_equal_p (op0, true_cond)
16973 && ! rtx_equal_p (op1, true_cond))))
16976 /* At this point we know we can use fsel. */
16978 /* Reduce the comparison to a comparison against zero. */
16979 if (! is_against_zero)
16981 temp = gen_reg_rtx (compare_mode);
16982 emit_insn (gen_rtx_SET (VOIDmode, temp,
16983 gen_rtx_MINUS (compare_mode, op0, op1)));
16985 op1 = CONST0_RTX (compare_mode);
16988 /* If we don't care about NaNs we can reduce some of the comparisons
16989 down to faster ones. */
16990 if (! HONOR_NANS (compare_mode))
16996 true_cond = false_cond;
17009 /* Now, reduce everything down to a GE. */
17016 temp = gen_reg_rtx (compare_mode);
17017 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17022 temp = gen_reg_rtx (compare_mode);
17023 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
17028 temp = gen_reg_rtx (compare_mode);
17029 emit_insn (gen_rtx_SET (VOIDmode, temp,
17030 gen_rtx_NEG (compare_mode,
17031 gen_rtx_ABS (compare_mode, op0))));
17036 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
17037 temp = gen_reg_rtx (result_mode);
17038 emit_insn (gen_rtx_SET (VOIDmode, temp,
17039 gen_rtx_IF_THEN_ELSE (result_mode,
17040 gen_rtx_GE (VOIDmode,
17042 true_cond, false_cond)));
17043 false_cond = true_cond;
17046 temp = gen_reg_rtx (compare_mode);
17047 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17052 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
17053 temp = gen_reg_rtx (result_mode);
17054 emit_insn (gen_rtx_SET (VOIDmode, temp,
17055 gen_rtx_IF_THEN_ELSE (result_mode,
17056 gen_rtx_GE (VOIDmode,
17058 true_cond, false_cond)));
17059 true_cond = false_cond;
17062 temp = gen_reg_rtx (compare_mode);
17063 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17068 gcc_unreachable ();
17071 emit_insn (gen_rtx_SET (VOIDmode, dest,
17072 gen_rtx_IF_THEN_ELSE (result_mode,
17073 gen_rtx_GE (VOIDmode,
17075 true_cond, false_cond)));
17079 /* Same as above, but for ints (isel). */
17082 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
17084 rtx condition_rtx, cr;
17085 enum machine_mode mode = GET_MODE (dest);
17086 enum rtx_code cond_code;
17087 rtx (*isel_func) (rtx, rtx, rtx, rtx, rtx);
17090 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
17093 /* We still have to do the compare, because isel doesn't do a
17094 compare, it just looks at the CRx bits set by a previous compare
17096 condition_rtx = rs6000_generate_compare (op, mode);
17097 cond_code = GET_CODE (condition_rtx);
17098 cr = XEXP (condition_rtx, 0);
17099 signedp = GET_MODE (cr) == CCmode;
17101 isel_func = (mode == SImode
17102 ? (signedp ? gen_isel_signed_si : gen_isel_unsigned_si)
17103 : (signedp ? gen_isel_signed_di : gen_isel_unsigned_di));
17107 case LT: case GT: case LTU: case GTU: case EQ:
17108 /* isel handles these directly. */
17112 /* We need to swap the sense of the comparison. */
17115 true_cond = false_cond;
17117 PUT_CODE (condition_rtx, reverse_condition (cond_code));
17122 false_cond = force_reg (mode, false_cond);
17123 if (true_cond != const0_rtx)
17124 true_cond = force_reg (mode, true_cond);
17126 emit_insn (isel_func (dest, condition_rtx, true_cond, false_cond, cr));
17132 output_isel (rtx *operands)
17134 enum rtx_code code;
17136 code = GET_CODE (operands[1]);
17138 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
17140 gcc_assert (GET_CODE (operands[2]) == REG
17141 && GET_CODE (operands[3]) == REG);
17142 PUT_CODE (operands[1], reverse_condition (code));
17143 return "isel %0,%3,%2,%j1";
17146 return "isel %0,%2,%3,%j1";
17150 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
17152 enum machine_mode mode = GET_MODE (op0);
17156 /* VSX/altivec have direct min/max insns. */
17157 if ((code == SMAX || code == SMIN)
17158 && (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
17159 || (mode == SFmode && VECTOR_UNIT_VSX_P (DFmode))))
17161 emit_insn (gen_rtx_SET (VOIDmode,
17163 gen_rtx_fmt_ee (code, mode, op0, op1)));
17167 if (code == SMAX || code == SMIN)
17172 if (code == SMAX || code == UMAX)
17173 target = emit_conditional_move (dest, c, op0, op1, mode,
17174 op0, op1, mode, 0);
17176 target = emit_conditional_move (dest, c, op0, op1, mode,
17177 op1, op0, mode, 0);
17178 gcc_assert (target);
17179 if (target != dest)
17180 emit_move_insn (dest, target);
17183 /* Emit instructions to perform a load-reserved/store-conditional operation.
17184 The operation performed is an atomic
17185 (set M (CODE:MODE M OP))
17186 If not NULL, BEFORE is atomically set to M before the operation, and
17187 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
17188 If SYNC_P then a memory barrier is emitted before the operation.
17189 Either OP or M may be wrapped in a NOT operation. */
17192 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
17193 rtx m, rtx op, rtx before_param, rtx after_param,
17196 enum machine_mode used_mode;
17197 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
17200 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17201 rtx shift = NULL_RTX;
17204 emit_insn (gen_lwsync ());
17208 /* If this is smaller than SImode, we'll have to use SImode with
17210 if (mode == QImode || mode == HImode)
17214 if (MEM_ALIGN (used_m) >= 32)
17217 if (BYTES_BIG_ENDIAN)
17218 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
17220 shift = GEN_INT (ishift);
17221 used_m = change_address (used_m, SImode, 0);
17225 rtx addrSI, aligned_addr;
17226 int shift_mask = mode == QImode ? 0x18 : 0x10;
17228 addrSI = gen_lowpart_common (SImode,
17229 force_reg (Pmode, XEXP (used_m, 0)));
17230 addrSI = force_reg (SImode, addrSI);
17231 shift = gen_reg_rtx (SImode);
17233 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17234 GEN_INT (shift_mask)));
17235 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17237 aligned_addr = expand_binop (Pmode, and_optab,
17239 GEN_INT (-4), NULL_RTX,
17240 1, OPTAB_LIB_WIDEN);
17241 used_m = change_address (used_m, SImode, aligned_addr);
17242 set_mem_align (used_m, 32);
17244 /* It's safe to keep the old alias set of USED_M, because
17245 the operation is atomic and only affects the original
17249 if (GET_CODE (op) == NOT)
17251 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
17252 oldop = gen_rtx_NOT (SImode, oldop);
17255 oldop = lowpart_subreg (SImode, op, mode);
17261 newop = expand_binop (SImode, and_optab,
17262 oldop, GEN_INT (imask), NULL_RTX,
17263 1, OPTAB_LIB_WIDEN);
17264 emit_insn (gen_ashlsi3 (newop, newop, shift));
17267 case NOT: /* NAND */
17268 newop = expand_binop (SImode, ior_optab,
17269 oldop, GEN_INT (~imask), NULL_RTX,
17270 1, OPTAB_LIB_WIDEN);
17271 emit_insn (gen_rotlsi3 (newop, newop, shift));
17275 newop = expand_binop (SImode, ior_optab,
17276 oldop, GEN_INT (~imask), NULL_RTX,
17277 1, OPTAB_LIB_WIDEN);
17278 emit_insn (gen_rotlsi3 (newop, newop, shift));
17286 newop = expand_binop (SImode, and_optab,
17287 oldop, GEN_INT (imask), NULL_RTX,
17288 1, OPTAB_LIB_WIDEN);
17289 emit_insn (gen_ashlsi3 (newop, newop, shift));
17291 mask = gen_reg_rtx (SImode);
17292 emit_move_insn (mask, GEN_INT (imask));
17293 emit_insn (gen_ashlsi3 (mask, mask, shift));
17296 newop = gen_rtx_PLUS (SImode, m, newop);
17298 newop = gen_rtx_MINUS (SImode, m, newop);
17299 newop = gen_rtx_AND (SImode, newop, mask);
17300 newop = gen_rtx_IOR (SImode, newop,
17301 gen_rtx_AND (SImode,
17302 gen_rtx_NOT (SImode, mask),
17308 gcc_unreachable ();
17312 used_mode = SImode;
17313 before = gen_reg_rtx (used_mode);
17314 after = gen_reg_rtx (used_mode);
17319 before = before_param;
17320 after = after_param;
17322 if (before == NULL_RTX)
17323 before = gen_reg_rtx (used_mode);
17324 if (after == NULL_RTX)
17325 after = gen_reg_rtx (used_mode);
17328 if ((code == PLUS || code == MINUS)
17329 && used_mode != mode)
17330 the_op = op; /* Computed above. */
17331 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
17332 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
17333 else if (code == NOT)
17334 the_op = gen_rtx_fmt_ee (IOR, used_mode,
17335 gen_rtx_NOT (used_mode, m),
17336 gen_rtx_NOT (used_mode, op));
17338 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
17340 set_after = gen_rtx_SET (VOIDmode, after, the_op);
17341 set_before = gen_rtx_SET (VOIDmode, before, used_m);
17342 set_atomic = gen_rtx_SET (VOIDmode, used_m,
17343 gen_rtx_UNSPEC (used_mode,
17344 gen_rtvec (1, the_op),
17346 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
17348 if ((code == PLUS || code == MINUS) && used_mode != mode)
17349 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
17350 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
17352 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
17353 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
17355 /* Shift and mask the return values properly. */
17356 if (used_mode != mode && before_param)
17358 emit_insn (gen_lshrsi3 (before, before, shift));
17359 convert_move (before_param, before, 1);
17362 if (used_mode != mode && after_param)
17364 emit_insn (gen_lshrsi3 (after, after, shift));
17365 convert_move (after_param, after, 1);
17368 /* The previous sequence will end with a branch that's dependent on
17369 the conditional store, so placing an isync will ensure that no
17370 other instructions (especially, no load or store instructions)
17371 can start before the atomic operation completes. */
17373 emit_insn (gen_isync ());
17376 /* A subroutine of the atomic operation splitters. Jump to LABEL if
17377 COND is true. Mark the jump as unlikely to be taken. */
17380 emit_unlikely_jump (rtx cond, rtx label)
17382 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
17385 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
17386 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
17387 add_reg_note (x, REG_BR_PROB, very_unlikely);
17390 /* A subroutine of the atomic operation splitters. Emit a load-locked
17391 instruction in MODE. */
17394 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
17396 rtx (*fn) (rtx, rtx) = NULL;
17397 if (mode == SImode)
17398 fn = gen_load_locked_si;
17399 else if (mode == DImode)
17400 fn = gen_load_locked_di;
17401 emit_insn (fn (reg, mem));
17404 /* A subroutine of the atomic operation splitters. Emit a store-conditional
17405 instruction in MODE. */
17408 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
17410 rtx (*fn) (rtx, rtx, rtx) = NULL;
17411 if (mode == SImode)
17412 fn = gen_store_conditional_si;
17413 else if (mode == DImode)
17414 fn = gen_store_conditional_di;
17416 /* Emit sync before stwcx. to address PPC405 Erratum. */
17417 if (PPC405_ERRATUM77)
17418 emit_insn (gen_memory_barrier ());
17420 emit_insn (fn (res, mem, val));
17423 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
17424 to perform. MEM is the memory on which to operate. VAL is the second
17425 operand of the binary operator. BEFORE and AFTER are optional locations to
17426 return the value of MEM either before of after the operation. SCRATCH is
17427 a scratch register. */
17430 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
17431 rtx before, rtx after, rtx scratch)
17433 enum machine_mode mode = GET_MODE (mem);
17434 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17436 emit_insn (gen_lwsync ());
17438 label = gen_label_rtx ();
17439 emit_label (label);
17440 label = gen_rtx_LABEL_REF (VOIDmode, label);
17442 if (before == NULL_RTX)
17444 emit_load_locked (mode, before, mem);
17447 x = gen_rtx_IOR (mode,
17448 gen_rtx_NOT (mode, before),
17449 gen_rtx_NOT (mode, val));
17450 else if (code == AND)
17451 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
17453 x = gen_rtx_fmt_ee (code, mode, before, val);
17455 if (after != NULL_RTX)
17456 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
17457 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
17459 emit_store_conditional (mode, cond, mem, scratch);
17461 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17462 emit_unlikely_jump (x, label);
17464 emit_insn (gen_isync ());
17467 /* Expand an atomic compare and swap operation. MEM is the memory on which
17468 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
17469 value to be stored. SCRATCH is a scratch GPR. */
17472 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
17475 enum machine_mode mode = GET_MODE (mem);
17476 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17478 emit_insn (gen_lwsync ());
17480 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17481 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17482 emit_label (XEXP (label1, 0));
17484 emit_load_locked (mode, retval, mem);
17486 x = gen_rtx_COMPARE (CCmode, retval, oldval);
17487 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
17489 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17490 emit_unlikely_jump (x, label2);
17492 emit_move_insn (scratch, newval);
17493 emit_store_conditional (mode, cond, mem, scratch);
17495 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17496 emit_unlikely_jump (x, label1);
17498 emit_insn (gen_isync ());
17499 emit_label (XEXP (label2, 0));
17502 /* Expand an atomic test and set operation. MEM is the memory on which
17503 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
17506 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
17508 enum machine_mode mode = GET_MODE (mem);
17509 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17511 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17512 emit_label (XEXP (label, 0));
17514 emit_load_locked (mode, retval, mem);
17515 emit_move_insn (scratch, val);
17516 emit_store_conditional (mode, cond, mem, scratch);
17518 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17519 emit_unlikely_jump (x, label);
17521 emit_insn (gen_isync ());
17525 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
17527 enum machine_mode mode = GET_MODE (mem);
17528 rtx addrSI, align, wdst, shift, mask;
17529 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
17530 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17532 /* Shift amount for subword relative to aligned word. */
17533 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
17534 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
17535 shift = gen_reg_rtx (SImode);
17536 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17537 GEN_INT (shift_mask)));
17538 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17540 /* Shift and mask old value into position within word. */
17541 oldval = convert_modes (SImode, mode, oldval, 1);
17542 oldval = expand_binop (SImode, and_optab,
17543 oldval, GEN_INT (imask), NULL_RTX,
17544 1, OPTAB_LIB_WIDEN);
17545 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
17547 /* Shift and mask new value into position within word. */
17548 newval = convert_modes (SImode, mode, newval, 1);
17549 newval = expand_binop (SImode, and_optab,
17550 newval, GEN_INT (imask), NULL_RTX,
17551 1, OPTAB_LIB_WIDEN);
17552 emit_insn (gen_ashlsi3 (newval, newval, shift));
17554 /* Mask for insertion. */
17555 mask = gen_reg_rtx (SImode);
17556 emit_move_insn (mask, GEN_INT (imask));
17557 emit_insn (gen_ashlsi3 (mask, mask, shift));
17559 /* Address of aligned word containing subword. */
17560 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
17561 NULL_RTX, 1, OPTAB_LIB_WIDEN);
17562 mem = change_address (mem, SImode, align);
17563 set_mem_align (mem, 32);
17564 MEM_VOLATILE_P (mem) = 1;
17566 wdst = gen_reg_rtx (SImode);
17567 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
17568 oldval, newval, mem));
17570 /* Shift the result back. */
17571 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
17573 emit_move_insn (dst, gen_lowpart (mode, wdst));
17577 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
17578 rtx oldval, rtx newval, rtx mem,
17581 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17583 emit_insn (gen_lwsync ());
17584 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17585 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17586 emit_label (XEXP (label1, 0));
17588 emit_load_locked (SImode, scratch, mem);
17590 /* Mask subword within loaded value for comparison with oldval.
17591 Use UNSPEC_AND to avoid clobber.*/
17592 emit_insn (gen_rtx_SET (SImode, dest,
17593 gen_rtx_UNSPEC (SImode,
17594 gen_rtvec (2, scratch, mask),
17597 x = gen_rtx_COMPARE (CCmode, dest, oldval);
17598 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
17600 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17601 emit_unlikely_jump (x, label2);
17603 /* Clear subword within loaded value for insertion of new value. */
17604 emit_insn (gen_rtx_SET (SImode, scratch,
17605 gen_rtx_AND (SImode,
17606 gen_rtx_NOT (SImode, mask), scratch)));
17607 emit_insn (gen_iorsi3 (scratch, scratch, newval));
17608 emit_store_conditional (SImode, cond, mem, scratch);
17610 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17611 emit_unlikely_jump (x, label1);
17613 emit_insn (gen_isync ());
17614 emit_label (XEXP (label2, 0));
17618 /* Emit instructions to move SRC to DST. Called by splitters for
17619 multi-register moves. It will emit at most one instruction for
17620 each register that is accessed; that is, it won't emit li/lis pairs
17621 (or equivalent for 64-bit code). One of SRC or DST must be a hard
17625 rs6000_split_multireg_move (rtx dst, rtx src)
17627 /* The register number of the first register being moved. */
17629 /* The mode that is to be moved. */
17630 enum machine_mode mode;
17631 /* The mode that the move is being done in, and its size. */
17632 enum machine_mode reg_mode;
17634 /* The number of registers that will be moved. */
17637 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
17638 mode = GET_MODE (dst);
17639 nregs = hard_regno_nregs[reg][mode];
17640 if (FP_REGNO_P (reg))
17641 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
17642 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
17643 else if (ALTIVEC_REGNO_P (reg))
17644 reg_mode = V16QImode;
17645 else if (TARGET_E500_DOUBLE && mode == TFmode)
17648 reg_mode = word_mode;
17649 reg_mode_size = GET_MODE_SIZE (reg_mode);
17651 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
17653 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
17655 /* Move register range backwards, if we might have destructive
17658 for (i = nregs - 1; i >= 0; i--)
17659 emit_insn (gen_rtx_SET (VOIDmode,
17660 simplify_gen_subreg (reg_mode, dst, mode,
17661 i * reg_mode_size),
17662 simplify_gen_subreg (reg_mode, src, mode,
17663 i * reg_mode_size)));
17669 bool used_update = false;
17670 rtx restore_basereg = NULL_RTX;
17672 if (MEM_P (src) && INT_REGNO_P (reg))
17676 if (GET_CODE (XEXP (src, 0)) == PRE_INC
17677 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
17680 breg = XEXP (XEXP (src, 0), 0);
17681 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
17682 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
17683 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
17684 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17685 src = replace_equiv_address (src, breg);
17687 else if (! rs6000_offsettable_memref_p (src))
17689 if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)
17691 rtx basereg = XEXP (XEXP (src, 0), 0);
17694 rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0);
17695 emit_insn (gen_rtx_SET (VOIDmode, ndst,
17696 gen_rtx_MEM (reg_mode, XEXP (src, 0))));
17697 used_update = true;
17700 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17701 XEXP (XEXP (src, 0), 1)));
17702 src = replace_equiv_address (src, basereg);
17706 rtx basereg = gen_rtx_REG (Pmode, reg);
17707 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
17708 src = replace_equiv_address (src, basereg);
17712 breg = XEXP (src, 0);
17713 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
17714 breg = XEXP (breg, 0);
17716 /* If the base register we are using to address memory is
17717 also a destination reg, then change that register last. */
17719 && REGNO (breg) >= REGNO (dst)
17720 && REGNO (breg) < REGNO (dst) + nregs)
17721 j = REGNO (breg) - REGNO (dst);
17723 else if (MEM_P (dst) && INT_REGNO_P (reg))
17727 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
17728 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
17731 breg = XEXP (XEXP (dst, 0), 0);
17732 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
17733 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
17734 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
17736 /* We have to update the breg before doing the store.
17737 Use store with update, if available. */
17741 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17742 emit_insn (TARGET_32BIT
17743 ? (TARGET_POWERPC64
17744 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
17745 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
17746 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
17747 used_update = true;
17750 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17751 dst = replace_equiv_address (dst, breg);
17753 else if (!rs6000_offsettable_memref_p (dst)
17754 && GET_CODE (XEXP (dst, 0)) != LO_SUM)
17756 if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY)
17758 rtx basereg = XEXP (XEXP (dst, 0), 0);
17761 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17762 emit_insn (gen_rtx_SET (VOIDmode,
17763 gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc));
17764 used_update = true;
17767 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17768 XEXP (XEXP (dst, 0), 1)));
17769 dst = replace_equiv_address (dst, basereg);
17773 rtx basereg = XEXP (XEXP (dst, 0), 0);
17774 rtx offsetreg = XEXP (XEXP (dst, 0), 1);
17775 gcc_assert (GET_CODE (XEXP (dst, 0)) == PLUS
17777 && REG_P (offsetreg)
17778 && REGNO (basereg) != REGNO (offsetreg));
17779 if (REGNO (basereg) == 0)
17781 rtx tmp = offsetreg;
17782 offsetreg = basereg;
17785 emit_insn (gen_add3_insn (basereg, basereg, offsetreg));
17786 restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg);
17787 dst = replace_equiv_address (dst, basereg);
17790 else if (GET_CODE (XEXP (dst, 0)) != LO_SUM)
17791 gcc_assert (rs6000_offsettable_memref_p (dst));
17794 for (i = 0; i < nregs; i++)
17796 /* Calculate index to next subword. */
17801 /* If compiler already emitted move of first word by
17802 store with update, no need to do anything. */
17803 if (j == 0 && used_update)
17806 emit_insn (gen_rtx_SET (VOIDmode,
17807 simplify_gen_subreg (reg_mode, dst, mode,
17808 j * reg_mode_size),
17809 simplify_gen_subreg (reg_mode, src, mode,
17810 j * reg_mode_size)));
17812 if (restore_basereg != NULL_RTX)
17813 emit_insn (restore_basereg);
17818 /* This page contains routines that are used to determine what the
17819 function prologue and epilogue code will do and write them out. */
17821 /* Return the first fixed-point register that is required to be
17822 saved. 32 if none. */
17825 first_reg_to_save (void)
17829 /* Find lowest numbered live register. */
17830 for (first_reg = 13; first_reg <= 31; first_reg++)
17831 if (df_regs_ever_live_p (first_reg)
17832 && (! call_used_regs[first_reg]
17833 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
17834 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
17835 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
17836 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
17841 && crtl->uses_pic_offset_table
17842 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
17843 return RS6000_PIC_OFFSET_TABLE_REGNUM;
17849 /* Similar, for FP regs. */
17852 first_fp_reg_to_save (void)
17856 /* Find lowest numbered live register. */
17857 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
17858 if (df_regs_ever_live_p (first_reg))
17864 /* Similar, for AltiVec regs. */
17867 first_altivec_reg_to_save (void)
17871 /* Stack frame remains as is unless we are in AltiVec ABI. */
17872 if (! TARGET_ALTIVEC_ABI)
17873 return LAST_ALTIVEC_REGNO + 1;
17875 /* On Darwin, the unwind routines are compiled without
17876 TARGET_ALTIVEC, and use save_world to save/restore the
17877 altivec registers when necessary. */
17878 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17879 && ! TARGET_ALTIVEC)
17880 return FIRST_ALTIVEC_REGNO + 20;
17882 /* Find lowest numbered live register. */
17883 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
17884 if (df_regs_ever_live_p (i))
17890 /* Return a 32-bit mask of the AltiVec registers we need to set in
17891 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
17892 the 32-bit word is 0. */
17894 static unsigned int
17895 compute_vrsave_mask (void)
17897 unsigned int i, mask = 0;
17899 /* On Darwin, the unwind routines are compiled without
17900 TARGET_ALTIVEC, and use save_world to save/restore the
17901 call-saved altivec registers when necessary. */
17902 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17903 && ! TARGET_ALTIVEC)
17906 /* First, find out if we use _any_ altivec registers. */
17907 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
17908 if (df_regs_ever_live_p (i))
17909 mask |= ALTIVEC_REG_BIT (i);
17914 /* Next, remove the argument registers from the set. These must
17915 be in the VRSAVE mask set by the caller, so we don't need to add
17916 them in again. More importantly, the mask we compute here is
17917 used to generate CLOBBERs in the set_vrsave insn, and we do not
17918 wish the argument registers to die. */
17919 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
17920 mask &= ~ALTIVEC_REG_BIT (i);
17922 /* Similarly, remove the return value from the set. */
17925 diddle_return_value (is_altivec_return_reg, &yes);
17927 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
17933 /* For a very restricted set of circumstances, we can cut down the
17934 size of prologues/epilogues by calling our own save/restore-the-world
17938 compute_save_world_info (rs6000_stack_t *info_ptr)
17940 info_ptr->world_save_p = 1;
17941 info_ptr->world_save_p
17942 = (WORLD_SAVE_P (info_ptr)
17943 && DEFAULT_ABI == ABI_DARWIN
17944 && ! (cfun->calls_setjmp && flag_exceptions)
17945 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
17946 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
17947 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
17948 && info_ptr->cr_save_p);
17950 /* This will not work in conjunction with sibcalls. Make sure there
17951 are none. (This check is expensive, but seldom executed.) */
17952 if (WORLD_SAVE_P (info_ptr))
17955 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
17956 if ( GET_CODE (insn) == CALL_INSN
17957 && SIBLING_CALL_P (insn))
17959 info_ptr->world_save_p = 0;
17964 if (WORLD_SAVE_P (info_ptr))
17966 /* Even if we're not touching VRsave, make sure there's room on the
17967 stack for it, if it looks like we're calling SAVE_WORLD, which
17968 will attempt to save it. */
17969 info_ptr->vrsave_size = 4;
17971 /* If we are going to save the world, we need to save the link register too. */
17972 info_ptr->lr_save_p = 1;
17974 /* "Save" the VRsave register too if we're saving the world. */
17975 if (info_ptr->vrsave_mask == 0)
17976 info_ptr->vrsave_mask = compute_vrsave_mask ();
17978 /* Because the Darwin register save/restore routines only handle
17979 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
17981 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
17982 && (info_ptr->first_altivec_reg_save
17983 >= FIRST_SAVED_ALTIVEC_REGNO));
17990 is_altivec_return_reg (rtx reg, void *xyes)
17992 bool *yes = (bool *) xyes;
17993 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
17998 /* Determine the strategy for savings/restoring registers. */
18001 SAVRES_MULTIPLE = 0x1,
18002 SAVE_INLINE_FPRS = 0x2,
18003 SAVE_INLINE_GPRS = 0x4,
18004 REST_INLINE_FPRS = 0x8,
18005 REST_INLINE_GPRS = 0x10,
18006 SAVE_NOINLINE_GPRS_SAVES_LR = 0x20,
18007 SAVE_NOINLINE_FPRS_SAVES_LR = 0x40,
18008 REST_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x80
18012 rs6000_savres_strategy (rs6000_stack_t *info,
18013 bool using_static_chain_p)
18017 if (TARGET_MULTIPLE
18018 && !TARGET_POWERPC64
18019 && !(TARGET_SPE_ABI && info->spe_64bit_regs_used)
18020 && info->first_gp_reg_save < 31
18021 && no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true))
18022 strategy |= SAVRES_MULTIPLE;
18024 if (crtl->calls_eh_return
18025 || cfun->machine->ra_need_lr
18026 || info->total_size > 32767)
18027 strategy |= (SAVE_INLINE_FPRS | REST_INLINE_FPRS
18028 | SAVE_INLINE_GPRS | REST_INLINE_GPRS);
18030 if (info->first_fp_reg_save == 64
18031 || FP_SAVE_INLINE (info->first_fp_reg_save)
18032 /* The out-of-line FP routines use double-precision stores;
18033 we can't use those routines if we don't have such stores. */
18034 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
18035 || !no_global_regs_above (info->first_fp_reg_save, /*gpr=*/false))
18036 strategy |= SAVE_INLINE_FPRS | REST_INLINE_FPRS;
18038 if (info->first_gp_reg_save == 32
18039 || GP_SAVE_INLINE (info->first_gp_reg_save)
18040 || !((strategy & SAVRES_MULTIPLE)
18041 || no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true)))
18042 strategy |= SAVE_INLINE_GPRS | REST_INLINE_GPRS;
18044 /* Don't bother to try to save things out-of-line if r11 is occupied
18045 by the static chain. It would require too much fiddling and the
18046 static chain is rarely used anyway. */
18047 if (using_static_chain_p)
18048 strategy |= SAVE_INLINE_FPRS | SAVE_INLINE_GPRS;
18050 /* If we are going to use store multiple, then don't even bother
18051 with the out-of-line routines, since the store-multiple
18052 instruction will always be smaller. */
18053 if ((strategy & SAVRES_MULTIPLE))
18054 strategy |= SAVE_INLINE_GPRS;
18056 /* The situation is more complicated with load multiple. We'd
18057 prefer to use the out-of-line routines for restores, since the
18058 "exit" out-of-line routines can handle the restore of LR and the
18059 frame teardown. However if doesn't make sense to use the
18060 out-of-line routine if that is the only reason we'd need to save
18061 LR, and we can't use the "exit" out-of-line gpr restore if we
18062 have saved some fprs; In those cases it is advantageous to use
18063 load multiple when available. */
18064 if ((strategy & SAVRES_MULTIPLE)
18065 && (!info->lr_save_p
18066 || info->first_fp_reg_save != 64))
18067 strategy |= REST_INLINE_GPRS;
18069 /* We can only use load multiple or the out-of-line routines to
18070 restore if we've used store multiple or out-of-line routines
18071 in the prologue, i.e. if we've saved all the registers from
18072 first_gp_reg_save. Otherwise, we risk loading garbage. */
18073 if ((strategy & (SAVE_INLINE_GPRS | SAVRES_MULTIPLE)) == SAVE_INLINE_GPRS)
18074 strategy |= REST_INLINE_GPRS;
18076 /* Saving CR interferes with the exit routines used on the SPE, so
18079 && info->spe_64bit_regs_used
18080 && info->cr_save_p)
18081 strategy |= REST_INLINE_GPRS;
18083 #ifdef POWERPC_LINUX
18086 if (!(strategy & SAVE_INLINE_FPRS))
18087 strategy |= SAVE_NOINLINE_FPRS_SAVES_LR;
18088 else if (!(strategy & SAVE_INLINE_GPRS)
18089 && info->first_fp_reg_save == 64)
18090 strategy |= SAVE_NOINLINE_GPRS_SAVES_LR;
18093 if (TARGET_AIX && !(strategy & REST_INLINE_FPRS))
18094 strategy |= REST_NOINLINE_FPRS_DOESNT_RESTORE_LR;
18099 /* Calculate the stack information for the current function. This is
18100 complicated by having two separate calling sequences, the AIX calling
18101 sequence and the V.4 calling sequence.
18103 AIX (and Darwin/Mac OS X) stack frames look like:
18105 SP----> +---------------------------------------+
18106 | back chain to caller | 0 0
18107 +---------------------------------------+
18108 | saved CR | 4 8 (8-11)
18109 +---------------------------------------+
18111 +---------------------------------------+
18112 | reserved for compilers | 12 24
18113 +---------------------------------------+
18114 | reserved for binders | 16 32
18115 +---------------------------------------+
18116 | saved TOC pointer | 20 40
18117 +---------------------------------------+
18118 | Parameter save area (P) | 24 48
18119 +---------------------------------------+
18120 | Alloca space (A) | 24+P etc.
18121 +---------------------------------------+
18122 | Local variable space (L) | 24+P+A
18123 +---------------------------------------+
18124 | Float/int conversion temporary (X) | 24+P+A+L
18125 +---------------------------------------+
18126 | Save area for AltiVec registers (W) | 24+P+A+L+X
18127 +---------------------------------------+
18128 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
18129 +---------------------------------------+
18130 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
18131 +---------------------------------------+
18132 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
18133 +---------------------------------------+
18134 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
18135 +---------------------------------------+
18136 old SP->| back chain to caller's caller |
18137 +---------------------------------------+
18139 The required alignment for AIX configurations is two words (i.e., 8
18143 V.4 stack frames look like:
18145 SP----> +---------------------------------------+
18146 | back chain to caller | 0
18147 +---------------------------------------+
18148 | caller's saved LR | 4
18149 +---------------------------------------+
18150 | Parameter save area (P) | 8
18151 +---------------------------------------+
18152 | Alloca space (A) | 8+P
18153 +---------------------------------------+
18154 | Varargs save area (V) | 8+P+A
18155 +---------------------------------------+
18156 | Local variable space (L) | 8+P+A+V
18157 +---------------------------------------+
18158 | Float/int conversion temporary (X) | 8+P+A+V+L
18159 +---------------------------------------+
18160 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
18161 +---------------------------------------+
18162 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
18163 +---------------------------------------+
18164 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
18165 +---------------------------------------+
18166 | SPE: area for 64-bit GP registers |
18167 +---------------------------------------+
18168 | SPE alignment padding |
18169 +---------------------------------------+
18170 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
18171 +---------------------------------------+
18172 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
18173 +---------------------------------------+
18174 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
18175 +---------------------------------------+
18176 old SP->| back chain to caller's caller |
18177 +---------------------------------------+
18179 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
18180 given. (But note below and in sysv4.h that we require only 8 and
18181 may round up the size of our stack frame anyways. The historical
18182 reason is early versions of powerpc-linux which didn't properly
18183 align the stack at program startup. A happy side-effect is that
18184 -mno-eabi libraries can be used with -meabi programs.)
18186 The EABI configuration defaults to the V.4 layout. However,
18187 the stack alignment requirements may differ. If -mno-eabi is not
18188 given, the required stack alignment is 8 bytes; if -mno-eabi is
18189 given, the required alignment is 16 bytes. (But see V.4 comment
18192 #ifndef ABI_STACK_BOUNDARY
18193 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
18196 static rs6000_stack_t *
18197 rs6000_stack_info (void)
18199 rs6000_stack_t *info_ptr = &stack_info;
18200 int reg_size = TARGET_32BIT ? 4 : 8;
18204 HOST_WIDE_INT non_fixed_size;
18205 bool using_static_chain_p;
18207 if (reload_completed && info_ptr->reload_completed)
18210 memset (info_ptr, 0, sizeof (*info_ptr));
18211 info_ptr->reload_completed = reload_completed;
18215 /* Cache value so we don't rescan instruction chain over and over. */
18216 if (cfun->machine->insn_chain_scanned_p == 0)
18217 cfun->machine->insn_chain_scanned_p
18218 = spe_func_has_64bit_regs_p () + 1;
18219 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
18222 /* Select which calling sequence. */
18223 info_ptr->abi = DEFAULT_ABI;
18225 /* Calculate which registers need to be saved & save area size. */
18226 info_ptr->first_gp_reg_save = first_reg_to_save ();
18227 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
18228 even if it currently looks like we won't. Reload may need it to
18229 get at a constant; if so, it will have already created a constant
18230 pool entry for it. */
18231 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
18232 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
18233 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
18234 && crtl->uses_const_pool
18235 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
18236 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
18238 first_gp = info_ptr->first_gp_reg_save;
18240 info_ptr->gp_size = reg_size * (32 - first_gp);
18242 /* For the SPE, we have an additional upper 32-bits on each GPR.
18243 Ideally we should save the entire 64-bits only when the upper
18244 half is used in SIMD instructions. Since we only record
18245 registers live (not the size they are used in), this proves
18246 difficult because we'd have to traverse the instruction chain at
18247 the right time, taking reload into account. This is a real pain,
18248 so we opt to save the GPRs in 64-bits always if but one register
18249 gets used in 64-bits. Otherwise, all the registers in the frame
18250 get saved in 32-bits.
18252 So... since when we save all GPRs (except the SP) in 64-bits, the
18253 traditional GP save area will be empty. */
18254 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18255 info_ptr->gp_size = 0;
18257 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
18258 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
18260 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
18261 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
18262 - info_ptr->first_altivec_reg_save);
18264 /* Does this function call anything? */
18265 info_ptr->calls_p = (! current_function_is_leaf
18266 || cfun->machine->ra_needs_full_frame);
18268 /* Determine if we need to save the condition code registers. */
18269 if (df_regs_ever_live_p (CR2_REGNO)
18270 || df_regs_ever_live_p (CR3_REGNO)
18271 || df_regs_ever_live_p (CR4_REGNO))
18273 info_ptr->cr_save_p = 1;
18274 if (DEFAULT_ABI == ABI_V4)
18275 info_ptr->cr_size = reg_size;
18278 /* If the current function calls __builtin_eh_return, then we need
18279 to allocate stack space for registers that will hold data for
18280 the exception handler. */
18281 if (crtl->calls_eh_return)
18284 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
18287 /* SPE saves EH registers in 64-bits. */
18288 ehrd_size = i * (TARGET_SPE_ABI
18289 && info_ptr->spe_64bit_regs_used != 0
18290 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
18295 /* Determine various sizes. */
18296 info_ptr->reg_size = reg_size;
18297 info_ptr->fixed_size = RS6000_SAVE_AREA;
18298 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
18299 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
18300 TARGET_ALTIVEC ? 16 : 8);
18301 if (FRAME_GROWS_DOWNWARD)
18302 info_ptr->vars_size
18303 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
18304 + info_ptr->parm_size,
18305 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
18306 - (info_ptr->fixed_size + info_ptr->vars_size
18307 + info_ptr->parm_size);
18309 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18310 info_ptr->spe_gp_size = 8 * (32 - first_gp);
18312 info_ptr->spe_gp_size = 0;
18314 if (TARGET_ALTIVEC_ABI)
18315 info_ptr->vrsave_mask = compute_vrsave_mask ();
18317 info_ptr->vrsave_mask = 0;
18319 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
18320 info_ptr->vrsave_size = 4;
18322 info_ptr->vrsave_size = 0;
18324 compute_save_world_info (info_ptr);
18326 /* Calculate the offsets. */
18327 switch (DEFAULT_ABI)
18331 gcc_unreachable ();
18335 info_ptr->fp_save_offset = - info_ptr->fp_size;
18336 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18338 if (TARGET_ALTIVEC_ABI)
18340 info_ptr->vrsave_save_offset
18341 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
18343 /* Align stack so vector save area is on a quadword boundary.
18344 The padding goes above the vectors. */
18345 if (info_ptr->altivec_size != 0)
18346 info_ptr->altivec_padding_size
18347 = info_ptr->vrsave_save_offset & 0xF;
18349 info_ptr->altivec_padding_size = 0;
18351 info_ptr->altivec_save_offset
18352 = info_ptr->vrsave_save_offset
18353 - info_ptr->altivec_padding_size
18354 - info_ptr->altivec_size;
18355 gcc_assert (info_ptr->altivec_size == 0
18356 || info_ptr->altivec_save_offset % 16 == 0);
18358 /* Adjust for AltiVec case. */
18359 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
18362 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
18363 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
18364 info_ptr->lr_save_offset = 2*reg_size;
18368 info_ptr->fp_save_offset = - info_ptr->fp_size;
18369 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18370 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
18372 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18374 /* Align stack so SPE GPR save area is aligned on a
18375 double-word boundary. */
18376 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
18377 info_ptr->spe_padding_size
18378 = 8 - (-info_ptr->cr_save_offset % 8);
18380 info_ptr->spe_padding_size = 0;
18382 info_ptr->spe_gp_save_offset
18383 = info_ptr->cr_save_offset
18384 - info_ptr->spe_padding_size
18385 - info_ptr->spe_gp_size;
18387 /* Adjust for SPE case. */
18388 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
18390 else if (TARGET_ALTIVEC_ABI)
18392 info_ptr->vrsave_save_offset
18393 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
18395 /* Align stack so vector save area is on a quadword boundary. */
18396 if (info_ptr->altivec_size != 0)
18397 info_ptr->altivec_padding_size
18398 = 16 - (-info_ptr->vrsave_save_offset % 16);
18400 info_ptr->altivec_padding_size = 0;
18402 info_ptr->altivec_save_offset
18403 = info_ptr->vrsave_save_offset
18404 - info_ptr->altivec_padding_size
18405 - info_ptr->altivec_size;
18407 /* Adjust for AltiVec case. */
18408 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
18411 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
18412 info_ptr->ehrd_offset -= ehrd_size;
18413 info_ptr->lr_save_offset = reg_size;
18417 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
18418 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
18419 + info_ptr->gp_size
18420 + info_ptr->altivec_size
18421 + info_ptr->altivec_padding_size
18422 + info_ptr->spe_gp_size
18423 + info_ptr->spe_padding_size
18425 + info_ptr->cr_size
18426 + info_ptr->vrsave_size,
18429 non_fixed_size = (info_ptr->vars_size
18430 + info_ptr->parm_size
18431 + info_ptr->save_size);
18433 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
18434 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
18436 /* Determine if we need to save the link register. */
18437 if (info_ptr->calls_p
18438 || (DEFAULT_ABI == ABI_AIX
18440 && !TARGET_PROFILE_KERNEL)
18441 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
18442 #ifdef TARGET_RELOCATABLE
18443 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
18445 || rs6000_ra_ever_killed ())
18446 info_ptr->lr_save_p = 1;
18448 using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
18449 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
18450 && call_used_regs[STATIC_CHAIN_REGNUM]);
18451 info_ptr->savres_strategy = rs6000_savres_strategy (info_ptr,
18452 using_static_chain_p);
18454 if (!(info_ptr->savres_strategy & SAVE_INLINE_GPRS)
18455 || !(info_ptr->savres_strategy & SAVE_INLINE_FPRS)
18456 || !(info_ptr->savres_strategy & REST_INLINE_GPRS)
18457 || !(info_ptr->savres_strategy & REST_INLINE_FPRS))
18458 info_ptr->lr_save_p = 1;
18460 if (info_ptr->lr_save_p)
18461 df_set_regs_ever_live (LR_REGNO, true);
18463 /* Determine if we need to allocate any stack frame:
18465 For AIX we need to push the stack if a frame pointer is needed
18466 (because the stack might be dynamically adjusted), if we are
18467 debugging, if we make calls, or if the sum of fp_save, gp_save,
18468 and local variables are more than the space needed to save all
18469 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
18470 + 18*8 = 288 (GPR13 reserved).
18472 For V.4 we don't have the stack cushion that AIX uses, but assume
18473 that the debugger can handle stackless frames. */
18475 if (info_ptr->calls_p)
18476 info_ptr->push_p = 1;
18478 else if (DEFAULT_ABI == ABI_V4)
18479 info_ptr->push_p = non_fixed_size != 0;
18481 else if (frame_pointer_needed)
18482 info_ptr->push_p = 1;
18484 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
18485 info_ptr->push_p = 1;
18488 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
18490 /* Zero offsets if we're not saving those registers. */
18491 if (info_ptr->fp_size == 0)
18492 info_ptr->fp_save_offset = 0;
18494 if (info_ptr->gp_size == 0)
18495 info_ptr->gp_save_offset = 0;
18497 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
18498 info_ptr->altivec_save_offset = 0;
18500 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
18501 info_ptr->vrsave_save_offset = 0;
18503 if (! TARGET_SPE_ABI
18504 || info_ptr->spe_64bit_regs_used == 0
18505 || info_ptr->spe_gp_size == 0)
18506 info_ptr->spe_gp_save_offset = 0;
18508 if (! info_ptr->lr_save_p)
18509 info_ptr->lr_save_offset = 0;
18511 if (! info_ptr->cr_save_p)
18512 info_ptr->cr_save_offset = 0;
18517 /* Return true if the current function uses any GPRs in 64-bit SIMD
18521 spe_func_has_64bit_regs_p (void)
18525 /* Functions that save and restore all the call-saved registers will
18526 need to save/restore the registers in 64-bits. */
18527 if (crtl->calls_eh_return
18528 || cfun->calls_setjmp
18529 || crtl->has_nonlocal_goto)
18532 insns = get_insns ();
18534 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
18540 /* FIXME: This should be implemented with attributes...
18542 (set_attr "spe64" "true")....then,
18543 if (get_spe64(insn)) return true;
18545 It's the only reliable way to do the stuff below. */
18547 i = PATTERN (insn);
18548 if (GET_CODE (i) == SET)
18550 enum machine_mode mode = GET_MODE (SET_SRC (i));
18552 if (SPE_VECTOR_MODE (mode))
18554 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
18564 debug_stack_info (rs6000_stack_t *info)
18566 const char *abi_string;
18569 info = rs6000_stack_info ();
18571 fprintf (stderr, "\nStack information for function %s:\n",
18572 ((current_function_decl && DECL_NAME (current_function_decl))
18573 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
18578 default: abi_string = "Unknown"; break;
18579 case ABI_NONE: abi_string = "NONE"; break;
18580 case ABI_AIX: abi_string = "AIX"; break;
18581 case ABI_DARWIN: abi_string = "Darwin"; break;
18582 case ABI_V4: abi_string = "V.4"; break;
18585 fprintf (stderr, "\tABI = %5s\n", abi_string);
18587 if (TARGET_ALTIVEC_ABI)
18588 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
18590 if (TARGET_SPE_ABI)
18591 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
18593 if (info->first_gp_reg_save != 32)
18594 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
18596 if (info->first_fp_reg_save != 64)
18597 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
18599 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
18600 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
18601 info->first_altivec_reg_save);
18603 if (info->lr_save_p)
18604 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
18606 if (info->cr_save_p)
18607 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
18609 if (info->vrsave_mask)
18610 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
18613 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
18616 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
18618 if (info->gp_save_offset)
18619 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
18621 if (info->fp_save_offset)
18622 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
18624 if (info->altivec_save_offset)
18625 fprintf (stderr, "\taltivec_save_offset = %5d\n",
18626 info->altivec_save_offset);
18628 if (info->spe_gp_save_offset)
18629 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
18630 info->spe_gp_save_offset);
18632 if (info->vrsave_save_offset)
18633 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
18634 info->vrsave_save_offset);
18636 if (info->lr_save_offset)
18637 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
18639 if (info->cr_save_offset)
18640 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
18642 if (info->varargs_save_offset)
18643 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
18645 if (info->total_size)
18646 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18649 if (info->vars_size)
18650 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18653 if (info->parm_size)
18654 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
18656 if (info->fixed_size)
18657 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
18660 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
18662 if (info->spe_gp_size)
18663 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
18666 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
18668 if (info->altivec_size)
18669 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
18671 if (info->vrsave_size)
18672 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
18674 if (info->altivec_padding_size)
18675 fprintf (stderr, "\taltivec_padding_size= %5d\n",
18676 info->altivec_padding_size);
18678 if (info->spe_padding_size)
18679 fprintf (stderr, "\tspe_padding_size = %5d\n",
18680 info->spe_padding_size);
18683 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
18685 if (info->save_size)
18686 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
18688 if (info->reg_size != 4)
18689 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
18691 fprintf (stderr, "\n");
18695 rs6000_return_addr (int count, rtx frame)
18697 /* Currently we don't optimize very well between prolog and body
18698 code and for PIC code the code can be actually quite bad, so
18699 don't try to be too clever here. */
18700 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
18702 cfun->machine->ra_needs_full_frame = 1;
18709 plus_constant (copy_to_reg
18710 (gen_rtx_MEM (Pmode,
18711 memory_address (Pmode, frame))),
18712 RETURN_ADDRESS_OFFSET)));
18715 cfun->machine->ra_need_lr = 1;
18716 return get_hard_reg_initial_val (Pmode, LR_REGNO);
18719 /* Say whether a function is a candidate for sibcall handling or not. */
18722 rs6000_function_ok_for_sibcall (tree decl, tree exp)
18727 fntype = TREE_TYPE (decl);
18729 fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (exp)));
18731 /* We can't do it if the called function has more vector parameters
18732 than the current function; there's nowhere to put the VRsave code. */
18733 if (TARGET_ALTIVEC_ABI
18734 && TARGET_ALTIVEC_VRSAVE
18735 && !(decl && decl == current_function_decl))
18737 function_args_iterator args_iter;
18741 /* Functions with vector parameters are required to have a
18742 prototype, so the argument type info must be available
18744 FOREACH_FUNCTION_ARGS(fntype, type, args_iter)
18745 if (TREE_CODE (type) == VECTOR_TYPE
18746 && ALTIVEC_OR_VSX_VECTOR_MODE (TYPE_MODE (type)))
18749 FOREACH_FUNCTION_ARGS(TREE_TYPE (current_function_decl), type, args_iter)
18750 if (TREE_CODE (type) == VECTOR_TYPE
18751 && ALTIVEC_OR_VSX_VECTOR_MODE (TYPE_MODE (type)))
18758 /* Under the AIX ABI we can't allow calls to non-local functions,
18759 because the callee may have a different TOC pointer to the
18760 caller and there's no way to ensure we restore the TOC when we
18761 return. With the secure-plt SYSV ABI we can't make non-local
18762 calls when -fpic/PIC because the plt call stubs use r30. */
18763 if (DEFAULT_ABI == ABI_DARWIN
18764 || (DEFAULT_ABI == ABI_AIX
18766 && !DECL_EXTERNAL (decl)
18767 && (*targetm.binds_local_p) (decl))
18768 || (DEFAULT_ABI == ABI_V4
18769 && (!TARGET_SECURE_PLT
18772 && (*targetm.binds_local_p) (decl)))))
18774 tree attr_list = TYPE_ATTRIBUTES (fntype);
18776 if (!lookup_attribute ("longcall", attr_list)
18777 || lookup_attribute ("shortcall", attr_list))
18784 /* NULL if INSN insn is valid within a low-overhead loop.
18785 Otherwise return why doloop cannot be applied.
18786 PowerPC uses the COUNT register for branch on table instructions. */
18788 static const char *
18789 rs6000_invalid_within_doloop (const_rtx insn)
18792 return "Function call in the loop.";
18795 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
18796 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
18797 return "Computed branch in the loop.";
18803 rs6000_ra_ever_killed (void)
18809 if (cfun->is_thunk)
18812 if (cfun->machine->lr_save_state)
18813 return cfun->machine->lr_save_state - 1;
18815 /* regs_ever_live has LR marked as used if any sibcalls are present,
18816 but this should not force saving and restoring in the
18817 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
18818 clobbers LR, so that is inappropriate. */
18820 /* Also, the prologue can generate a store into LR that
18821 doesn't really count, like this:
18824 bcl to set PIC register
18828 When we're called from the epilogue, we need to avoid counting
18829 this as a store. */
18831 push_topmost_sequence ();
18832 top = get_insns ();
18833 pop_topmost_sequence ();
18834 reg = gen_rtx_REG (Pmode, LR_REGNO);
18836 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
18842 if (!SIBLING_CALL_P (insn))
18845 else if (find_regno_note (insn, REG_INC, LR_REGNO))
18847 else if (set_of (reg, insn) != NULL_RTX
18848 && !prologue_epilogue_contains (insn))
18855 /* Emit instructions needed to load the TOC register.
18856 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
18857 a constant pool; or for SVR4 -fpic. */
18860 rs6000_emit_load_toc_table (int fromprolog)
18863 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
18865 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
18868 rtx lab, tmp1, tmp2, got;
18870 lab = gen_label_rtx ();
18871 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (lab));
18872 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18874 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18876 got = rs6000_got_sym ();
18877 tmp1 = tmp2 = dest;
18880 tmp1 = gen_reg_rtx (Pmode);
18881 tmp2 = gen_reg_rtx (Pmode);
18883 emit_insn (gen_load_toc_v4_PIC_1 (lab));
18884 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
18885 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
18886 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
18888 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
18890 emit_insn (gen_load_toc_v4_pic_si ());
18891 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18893 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
18896 rtx temp0 = (fromprolog
18897 ? gen_rtx_REG (Pmode, 0)
18898 : gen_reg_rtx (Pmode));
18904 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
18905 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18907 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
18908 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18910 emit_insn (gen_load_toc_v4_PIC_1 (symF));
18911 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18912 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
18918 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18919 lab = gen_label_rtx ();
18920 emit_insn (gen_load_toc_v4_PIC_1b (tocsym, lab));
18921 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18922 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
18924 emit_insn (gen_addsi3 (dest, temp0, dest));
18926 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
18928 /* This is for AIX code running in non-PIC ELF32. */
18931 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
18932 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18934 emit_insn (gen_elf_high (dest, realsym));
18935 emit_insn (gen_elf_low (dest, dest, realsym));
18939 gcc_assert (DEFAULT_ABI == ABI_AIX);
18942 emit_insn (gen_load_toc_aix_si (dest));
18944 emit_insn (gen_load_toc_aix_di (dest));
18948 /* Emit instructions to restore the link register after determining where
18949 its value has been stored. */
18952 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
18954 rs6000_stack_t *info = rs6000_stack_info ();
18957 operands[0] = source;
18958 operands[1] = scratch;
18960 if (info->lr_save_p)
18962 rtx frame_rtx = stack_pointer_rtx;
18963 HOST_WIDE_INT sp_offset = 0;
18966 if (frame_pointer_needed
18967 || cfun->calls_alloca
18968 || info->total_size > 32767)
18970 tmp = gen_frame_mem (Pmode, frame_rtx);
18971 emit_move_insn (operands[1], tmp);
18972 frame_rtx = operands[1];
18974 else if (info->push_p)
18975 sp_offset = info->total_size;
18977 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
18978 tmp = gen_frame_mem (Pmode, tmp);
18979 emit_move_insn (tmp, operands[0]);
18982 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
18984 /* Freeze lr_save_p. We've just emitted rtl that depends on the
18985 state of lr_save_p so any change from here on would be a bug. In
18986 particular, stop rs6000_ra_ever_killed from considering the SET
18987 of lr we may have added just above. */
18988 cfun->machine->lr_save_state = info->lr_save_p + 1;
18991 static GTY(()) alias_set_type set = -1;
18994 get_TOC_alias_set (void)
18997 set = new_alias_set ();
19001 /* This returns nonzero if the current function uses the TOC. This is
19002 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
19003 is generated by the ABI_V4 load_toc_* patterns. */
19010 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
19013 rtx pat = PATTERN (insn);
19016 if (GET_CODE (pat) == PARALLEL)
19017 for (i = 0; i < XVECLEN (pat, 0); i++)
19019 rtx sub = XVECEXP (pat, 0, i);
19020 if (GET_CODE (sub) == USE)
19022 sub = XEXP (sub, 0);
19023 if (GET_CODE (sub) == UNSPEC
19024 && XINT (sub, 1) == UNSPEC_TOC)
19034 create_TOC_reference (rtx symbol, rtx largetoc_reg)
19036 rtx tocrel, tocreg;
19038 if (TARGET_DEBUG_ADDR)
19040 if (GET_CODE (symbol) == SYMBOL_REF)
19041 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
19045 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
19046 GET_RTX_NAME (GET_CODE (symbol)));
19047 debug_rtx (symbol);
19051 if (!can_create_pseudo_p ())
19052 df_set_regs_ever_live (TOC_REGISTER, true);
19054 tocrel = gen_rtx_CONST (Pmode,
19055 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol),
19057 tocreg = gen_rtx_REG (Pmode, TOC_REGISTER);
19058 if (TARGET_CMODEL != CMODEL_SMALL)
19060 rtx hi = gen_rtx_CONST (Pmode,
19061 gen_rtx_PLUS (Pmode, tocreg,
19062 gen_rtx_HIGH (Pmode, tocrel)));
19063 if (largetoc_reg != NULL)
19065 emit_move_insn (largetoc_reg, hi);
19068 return gen_rtx_LO_SUM (Pmode, hi, copy_rtx (tocrel));
19071 return gen_rtx_PLUS (Pmode, tocreg, tocrel);
19074 /* Issue assembly directives that create a reference to the given DWARF
19075 FRAME_TABLE_LABEL from the current function section. */
19077 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
19079 fprintf (asm_out_file, "\t.ref %s\n",
19080 TARGET_STRIP_NAME_ENCODING (frame_table_label));
19083 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
19084 and the change to the stack pointer. */
19087 rs6000_emit_stack_tie (void)
19089 rtx mem = gen_frame_mem (BLKmode,
19090 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
19092 emit_insn (gen_stack_tie (mem));
19095 /* Emit the correct code for allocating stack space, as insns.
19096 If COPY_REG, make sure a copy of the old frame is left there.
19097 The generated code may use hard register 0 as a temporary. */
19100 rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg)
19103 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19104 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
19105 rtx todec = gen_int_mode (-size, Pmode);
19108 if (INTVAL (todec) != -size)
19110 warning (0, "stack frame too large");
19111 emit_insn (gen_trap ());
19115 if (crtl->limit_stack)
19117 if (REG_P (stack_limit_rtx)
19118 && REGNO (stack_limit_rtx) > 1
19119 && REGNO (stack_limit_rtx) <= 31)
19121 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
19122 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19125 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
19127 && DEFAULT_ABI == ABI_V4)
19129 rtx toload = gen_rtx_CONST (VOIDmode,
19130 gen_rtx_PLUS (Pmode,
19134 emit_insn (gen_elf_high (tmp_reg, toload));
19135 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
19136 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19140 warning (0, "stack limit expression is not supported");
19144 emit_move_insn (copy_reg, stack_reg);
19148 /* Need a note here so that try_split doesn't get confused. */
19149 if (get_last_insn () == NULL_RTX)
19150 emit_note (NOTE_INSN_DELETED);
19151 insn = emit_move_insn (tmp_reg, todec);
19152 try_split (PATTERN (insn), insn, 0);
19156 insn = emit_insn (TARGET_32BIT
19157 ? gen_movsi_update_stack (stack_reg, stack_reg,
19159 : gen_movdi_di_update_stack (stack_reg, stack_reg,
19160 todec, stack_reg));
19161 /* Since we didn't use gen_frame_mem to generate the MEM, grab
19162 it now and set the alias set/attributes. The above gen_*_update
19163 calls will generate a PARALLEL with the MEM set being the first
19165 par = PATTERN (insn);
19166 gcc_assert (GET_CODE (par) == PARALLEL);
19167 set = XVECEXP (par, 0, 0);
19168 gcc_assert (GET_CODE (set) == SET);
19169 mem = SET_DEST (set);
19170 gcc_assert (MEM_P (mem));
19171 MEM_NOTRAP_P (mem) = 1;
19172 set_mem_alias_set (mem, get_frame_alias_set ());
19174 RTX_FRAME_RELATED_P (insn) = 1;
19175 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
19176 gen_rtx_SET (VOIDmode, stack_reg,
19177 gen_rtx_PLUS (Pmode, stack_reg,
19178 GEN_INT (-size))));
19181 #define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
19183 #if PROBE_INTERVAL > 32768
19184 #error Cannot use indexed addressing mode for stack probing
19187 /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
19188 inclusive. These are offsets from the current stack pointer. */
19191 rs6000_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size)
19193 /* See if we have a constant small number of probes to generate. If so,
19194 that's the easy case. */
19195 if (first + size <= 32768)
19199 /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
19200 it exceeds SIZE. If only one probe is needed, this will not
19201 generate any code. Then probe at FIRST + SIZE. */
19202 for (i = PROBE_INTERVAL; i < size; i += PROBE_INTERVAL)
19203 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + i)));
19205 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + size)));
19208 /* Otherwise, do the same as above, but in a loop. Note that we must be
19209 extra careful with variables wrapping around because we might be at
19210 the very top (or the very bottom) of the address space and we have
19211 to be able to handle this case properly; in particular, we use an
19212 equality test for the loop condition. */
19215 HOST_WIDE_INT rounded_size;
19216 rtx r12 = gen_rtx_REG (Pmode, 12);
19217 rtx r0 = gen_rtx_REG (Pmode, 0);
19219 /* Sanity check for the addressing mode we're going to use. */
19220 gcc_assert (first <= 32768);
19222 /* Step 1: round SIZE to the previous multiple of the interval. */
19224 rounded_size = size & -PROBE_INTERVAL;
19227 /* Step 2: compute initial and final value of the loop counter. */
19229 /* TEST_ADDR = SP + FIRST. */
19230 emit_insn (gen_rtx_SET (VOIDmode, r12,
19231 plus_constant (stack_pointer_rtx, -first)));
19233 /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE. */
19234 if (rounded_size > 32768)
19236 emit_move_insn (r0, GEN_INT (-rounded_size));
19237 emit_insn (gen_rtx_SET (VOIDmode, r0,
19238 gen_rtx_PLUS (Pmode, r12, r0)));
19241 emit_insn (gen_rtx_SET (VOIDmode, r0,
19242 plus_constant (r12, -rounded_size)));
19245 /* Step 3: the loop
19247 while (TEST_ADDR != LAST_ADDR)
19249 TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
19253 probes at FIRST + N * PROBE_INTERVAL for values of N from 1
19254 until it is equal to ROUNDED_SIZE. */
19257 emit_insn (gen_probe_stack_rangedi (r12, r12, r0));
19259 emit_insn (gen_probe_stack_rangesi (r12, r12, r0));
19262 /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
19263 that SIZE is equal to ROUNDED_SIZE. */
19265 if (size != rounded_size)
19266 emit_stack_probe (plus_constant (r12, rounded_size - size));
19270 /* Probe a range of stack addresses from REG1 to REG2 inclusive. These are
19271 absolute addresses. */
19274 output_probe_stack_range (rtx reg1, rtx reg2)
19276 static int labelno = 0;
19277 char loop_lab[32], end_lab[32];
19280 ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno);
19281 ASM_GENERATE_INTERNAL_LABEL (end_lab, "LPSRE", labelno++);
19283 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
19285 /* Jump to END_LAB if TEST_ADDR == LAST_ADDR. */
19289 output_asm_insn ("{cmp|cmpd} 0,%0,%1", xops);
19291 output_asm_insn ("{cmp|cmpw} 0,%0,%1", xops);
19293 fputs ("\tbeq 0,", asm_out_file);
19294 assemble_name_raw (asm_out_file, end_lab);
19295 fputc ('\n', asm_out_file);
19297 /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */
19298 xops[1] = GEN_INT (-PROBE_INTERVAL);
19299 output_asm_insn ("{cal %0,%1(%0)|addi %0,%0,%1}", xops);
19301 /* Probe at TEST_ADDR and branch. */
19302 output_asm_insn ("{st|stw} 0,0(%0)", xops);
19303 fprintf (asm_out_file, "\tb ");
19304 assemble_name_raw (asm_out_file, loop_lab);
19305 fputc ('\n', asm_out_file);
19307 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, end_lab);
19312 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
19313 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
19314 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
19315 deduce these equivalences by itself so it wasn't necessary to hold
19316 its hand so much. */
19319 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
19320 rtx reg2, rtx rreg)
19324 /* copy_rtx will not make unique copies of registers, so we need to
19325 ensure we don't have unwanted sharing here. */
19327 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19330 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19332 real = copy_rtx (PATTERN (insn));
19334 if (reg2 != NULL_RTX)
19335 real = replace_rtx (real, reg2, rreg);
19337 real = replace_rtx (real, reg,
19338 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
19339 STACK_POINTER_REGNUM),
19342 /* We expect that 'real' is either a SET or a PARALLEL containing
19343 SETs (and possibly other stuff). In a PARALLEL, all the SETs
19344 are important so they all have to be marked RTX_FRAME_RELATED_P. */
19346 if (GET_CODE (real) == SET)
19350 temp = simplify_rtx (SET_SRC (set));
19352 SET_SRC (set) = temp;
19353 temp = simplify_rtx (SET_DEST (set));
19355 SET_DEST (set) = temp;
19356 if (GET_CODE (SET_DEST (set)) == MEM)
19358 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19360 XEXP (SET_DEST (set), 0) = temp;
19367 gcc_assert (GET_CODE (real) == PARALLEL);
19368 for (i = 0; i < XVECLEN (real, 0); i++)
19369 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
19371 rtx set = XVECEXP (real, 0, i);
19373 temp = simplify_rtx (SET_SRC (set));
19375 SET_SRC (set) = temp;
19376 temp = simplify_rtx (SET_DEST (set));
19378 SET_DEST (set) = temp;
19379 if (GET_CODE (SET_DEST (set)) == MEM)
19381 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19383 XEXP (SET_DEST (set), 0) = temp;
19385 RTX_FRAME_RELATED_P (set) = 1;
19389 RTX_FRAME_RELATED_P (insn) = 1;
19390 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
19395 /* Returns an insn that has a vrsave set operation with the
19396 appropriate CLOBBERs. */
19399 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
19402 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
19403 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19406 = gen_rtx_SET (VOIDmode,
19408 gen_rtx_UNSPEC_VOLATILE (SImode,
19409 gen_rtvec (2, reg, vrsave),
19410 UNSPECV_SET_VRSAVE));
19414 /* We need to clobber the registers in the mask so the scheduler
19415 does not move sets to VRSAVE before sets of AltiVec registers.
19417 However, if the function receives nonlocal gotos, reload will set
19418 all call saved registers live. We will end up with:
19420 (set (reg 999) (mem))
19421 (parallel [ (set (reg vrsave) (unspec blah))
19422 (clobber (reg 999))])
19424 The clobber will cause the store into reg 999 to be dead, and
19425 flow will attempt to delete an epilogue insn. In this case, we
19426 need an unspec use/set of the register. */
19428 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
19429 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19431 if (!epiloguep || call_used_regs [i])
19432 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
19433 gen_rtx_REG (V4SImode, i));
19436 rtx reg = gen_rtx_REG (V4SImode, i);
19439 = gen_rtx_SET (VOIDmode,
19441 gen_rtx_UNSPEC (V4SImode,
19442 gen_rtvec (1, reg), 27));
19446 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
19448 for (i = 0; i < nclobs; ++i)
19449 XVECEXP (insn, 0, i) = clobs[i];
19454 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
19455 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
19458 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
19459 unsigned int regno, int offset, HOST_WIDE_INT total_size)
19461 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
19462 rtx replacea, replaceb;
19464 int_rtx = GEN_INT (offset);
19466 /* Some cases that need register indexed addressing. */
19467 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
19468 || (TARGET_VSX && ALTIVEC_OR_VSX_VECTOR_MODE (mode))
19469 || (TARGET_E500_DOUBLE && mode == DFmode)
19471 && SPE_VECTOR_MODE (mode)
19472 && !SPE_CONST_OFFSET_OK (offset)))
19474 /* Whomever calls us must make sure r11 is available in the
19475 flow path of instructions in the prologue. */
19476 offset_rtx = gen_rtx_REG (Pmode, 11);
19477 emit_move_insn (offset_rtx, int_rtx);
19479 replacea = offset_rtx;
19480 replaceb = int_rtx;
19484 offset_rtx = int_rtx;
19485 replacea = NULL_RTX;
19486 replaceb = NULL_RTX;
19489 reg = gen_rtx_REG (mode, regno);
19490 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
19491 mem = gen_frame_mem (mode, addr);
19493 insn = emit_move_insn (mem, reg);
19495 return rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
19498 /* Emit an offset memory reference suitable for a frame store, while
19499 converting to a valid addressing mode. */
19502 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
19504 rtx int_rtx, offset_rtx;
19506 int_rtx = GEN_INT (offset);
19508 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
19509 || (TARGET_E500_DOUBLE && mode == DFmode))
19511 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
19512 emit_move_insn (offset_rtx, int_rtx);
19515 offset_rtx = int_rtx;
19517 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
19520 /* Look for user-defined global regs. We should not save and restore these,
19521 and cannot use stmw/lmw if there are any in its range. */
19524 no_global_regs_above (int first, bool gpr)
19527 int last = gpr ? 32 : 64;
19528 for (i = first; i < last; i++)
19529 if (global_regs[i])
19534 #ifndef TARGET_FIX_AND_CONTINUE
19535 #define TARGET_FIX_AND_CONTINUE 0
19538 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
19539 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
19540 #define LAST_SAVRES_REGISTER 31
19541 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
19543 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
19545 /* Temporary holding space for an out-of-line register save/restore
19547 static char savres_routine_name[30];
19549 /* Return the name for an out-of-line register save/restore routine.
19550 We are saving/restoring GPRs if GPR is true. */
19553 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
19554 bool savep, bool gpr, bool lr)
19556 const char *prefix = "";
19557 const char *suffix = "";
19559 /* Different targets are supposed to define
19560 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
19561 routine name could be defined with:
19563 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
19565 This is a nice idea in practice, but in reality, things are
19566 complicated in several ways:
19568 - ELF targets have save/restore routines for GPRs.
19570 - SPE targets use different prefixes for 32/64-bit registers, and
19571 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
19573 - PPC64 ELF targets have routines for save/restore of GPRs that
19574 differ in what they do with the link register, so having a set
19575 prefix doesn't work. (We only use one of the save routines at
19576 the moment, though.)
19578 - PPC32 elf targets have "exit" versions of the restore routines
19579 that restore the link register and can save some extra space.
19580 These require an extra suffix. (There are also "tail" versions
19581 of the restore routines and "GOT" versions of the save routines,
19582 but we don't generate those at present. Same problems apply,
19585 We deal with all this by synthesizing our own prefix/suffix and
19586 using that for the simple sprintf call shown above. */
19589 /* No floating point saves on the SPE. */
19593 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
19595 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
19600 else if (DEFAULT_ABI == ABI_V4)
19606 prefix = savep ? "_savegpr_" : "_restgpr_";
19608 prefix = savep ? "_savefpr_" : "_restfpr_";
19613 else if (DEFAULT_ABI == ABI_AIX)
19615 #ifndef POWERPC_LINUX
19616 /* No out-of-line save/restore routines for GPRs on AIX. */
19617 gcc_assert (!TARGET_AIX || !gpr);
19623 ? (lr ? "_savegpr0_" : "_savegpr1_")
19624 : (lr ? "_restgpr0_" : "_restgpr1_"));
19625 #ifdef POWERPC_LINUX
19627 prefix = (savep ? "_savefpr_" : "_restfpr_");
19631 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
19632 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
19635 else if (DEFAULT_ABI == ABI_DARWIN)
19636 sorry ("out-of-line save/restore routines not supported on Darwin");
19638 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
19640 return savres_routine_name;
19643 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
19644 We are saving/restoring GPRs if GPR is true. */
19647 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
19650 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
19652 int select = ((savep ? 1 : 0) << 2
19654 /* On the SPE, we never have any FPRs, but we do have
19655 32/64-bit versions of the routines. */
19656 ? (info->spe_64bit_regs_used ? 1 : 0)
19657 : (gpr ? 1 : 0)) << 1)
19660 /* Don't generate bogus routine names. */
19661 gcc_assert (FIRST_SAVRES_REGISTER <= regno
19662 && regno <= LAST_SAVRES_REGISTER);
19664 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
19670 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
19672 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
19673 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
19674 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
19680 /* Emit a sequence of insns, including a stack tie if needed, for
19681 resetting the stack pointer. If SAVRES is true, then don't reset the
19682 stack pointer, but move the base of the frame into r11 for use by
19683 out-of-line register restore routines. */
19686 rs6000_emit_stack_reset (rs6000_stack_t *info,
19687 rtx sp_reg_rtx, rtx frame_reg_rtx,
19688 int sp_offset, bool savres)
19690 /* This blockage is needed so that sched doesn't decide to move
19691 the sp change before the register restores. */
19692 if (frame_reg_rtx != sp_reg_rtx
19694 && info->spe_64bit_regs_used != 0
19695 && info->first_gp_reg_save != 32))
19696 rs6000_emit_stack_tie ();
19698 if (frame_reg_rtx != sp_reg_rtx)
19700 if (sp_offset != 0)
19702 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
19703 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
19704 GEN_INT (sp_offset)));
19707 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
19709 else if (sp_offset != 0)
19711 /* If we are restoring registers out-of-line, we will be using the
19712 "exit" variants of the restore routines, which will reset the
19713 stack for us. But we do need to point r11 into the right place
19714 for those routines. */
19715 rtx dest_reg = (savres
19716 ? gen_rtx_REG (Pmode, 11)
19719 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
19720 GEN_INT (sp_offset)));
19727 /* Construct a parallel rtx describing the effect of a call to an
19728 out-of-line register save/restore routine. */
19731 rs6000_make_savres_rtx (rs6000_stack_t *info,
19732 rtx frame_reg_rtx, int save_area_offset,
19733 enum machine_mode reg_mode,
19734 bool savep, bool gpr, bool lr)
19737 int offset, start_reg, end_reg, n_regs;
19738 int reg_size = GET_MODE_SIZE (reg_mode);
19744 ? info->first_gp_reg_save
19745 : info->first_fp_reg_save);
19746 end_reg = gpr ? 32 : 64;
19747 n_regs = end_reg - start_reg;
19748 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
19751 RTVEC_ELT (p, offset++) = ret_rtx;
19753 RTVEC_ELT (p, offset++)
19754 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
19756 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
19757 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
19758 RTVEC_ELT (p, offset++)
19759 = gen_rtx_USE (VOIDmode,
19760 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
19764 for (i = 0; i < end_reg - start_reg; i++)
19766 rtx addr, reg, mem;
19767 reg = gen_rtx_REG (reg_mode, start_reg + i);
19768 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19769 GEN_INT (save_area_offset + reg_size*i));
19770 mem = gen_frame_mem (reg_mode, addr);
19772 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
19774 savep ? reg : mem);
19779 rtx addr, reg, mem;
19780 reg = gen_rtx_REG (Pmode, 0);
19781 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19782 GEN_INT (info->lr_save_offset));
19783 mem = gen_frame_mem (Pmode, addr);
19784 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
19787 return gen_rtx_PARALLEL (VOIDmode, p);
19790 /* Determine whether the gp REG is really used. */
19793 rs6000_reg_live_or_pic_offset_p (int reg)
19795 /* If the function calls eh_return, claim used all the registers that would
19796 be checked for liveness otherwise. This is required for the PIC offset
19797 register with -mminimal-toc on AIX, as it is advertised as "fixed" for
19798 register allocation purposes in this case. */
19800 return (((crtl->calls_eh_return || df_regs_ever_live_p (reg))
19801 && (!call_used_regs[reg]
19802 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
19803 && !TARGET_SINGLE_PIC_BASE
19804 && TARGET_TOC && TARGET_MINIMAL_TOC)))
19805 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
19806 && !TARGET_SINGLE_PIC_BASE
19807 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
19808 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
19811 /* Emit function prologue as insns. */
19814 rs6000_emit_prologue (void)
19816 rs6000_stack_t *info = rs6000_stack_info ();
19817 enum machine_mode reg_mode = Pmode;
19818 int reg_size = TARGET_32BIT ? 4 : 8;
19819 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19820 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
19821 rtx frame_reg_rtx = sp_reg_rtx;
19822 rtx cr_save_rtx = NULL_RTX;
19825 int saving_FPRs_inline;
19826 int saving_GPRs_inline;
19827 int using_store_multiple;
19828 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
19829 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
19830 && call_used_regs[STATIC_CHAIN_REGNUM]);
19831 HOST_WIDE_INT sp_offset = 0;
19833 if (flag_stack_usage_info)
19834 current_function_static_stack_size = info->total_size;
19836 if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK && info->total_size)
19837 rs6000_emit_probe_stack_range (STACK_CHECK_PROTECT, info->total_size);
19839 if (TARGET_FIX_AND_CONTINUE)
19841 /* gdb on darwin arranges to forward a function from the old
19842 address by modifying the first 5 instructions of the function
19843 to branch to the overriding function. This is necessary to
19844 permit function pointers that point to the old function to
19845 actually forward to the new function. */
19846 emit_insn (gen_nop ());
19847 emit_insn (gen_nop ());
19848 emit_insn (gen_nop ());
19849 emit_insn (gen_nop ());
19850 emit_insn (gen_nop ());
19853 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19855 reg_mode = V2SImode;
19859 strategy = info->savres_strategy;
19860 using_store_multiple = strategy & SAVRES_MULTIPLE;
19861 saving_FPRs_inline = strategy & SAVE_INLINE_FPRS;
19862 saving_GPRs_inline = strategy & SAVE_INLINE_GPRS;
19864 /* For V.4, update stack before we do any saving and set back pointer. */
19865 if (! WORLD_SAVE_P (info)
19867 && (DEFAULT_ABI == ABI_V4
19868 || crtl->calls_eh_return))
19870 bool need_r11 = (TARGET_SPE
19871 ? (!saving_GPRs_inline
19872 && info->spe_64bit_regs_used == 0)
19873 : (!saving_FPRs_inline || !saving_GPRs_inline));
19874 rtx copy_reg = need_r11 ? gen_rtx_REG (Pmode, 11) : NULL;
19876 if (info->total_size < 32767)
19877 sp_offset = info->total_size;
19879 frame_reg_rtx = copy_reg;
19880 else if (info->cr_save_p
19882 || info->first_fp_reg_save < 64
19883 || info->first_gp_reg_save < 32
19884 || info->altivec_size != 0
19885 || info->vrsave_mask != 0
19886 || crtl->calls_eh_return)
19888 copy_reg = frame_ptr_rtx;
19889 frame_reg_rtx = copy_reg;
19893 /* The prologue won't be saving any regs so there is no need
19894 to set up a frame register to access any frame save area.
19895 We also won't be using sp_offset anywhere below, but set
19896 the correct value anyway to protect against future
19897 changes to this function. */
19898 sp_offset = info->total_size;
19900 rs6000_emit_allocate_stack (info->total_size, copy_reg);
19901 if (frame_reg_rtx != sp_reg_rtx)
19902 rs6000_emit_stack_tie ();
19905 /* Handle world saves specially here. */
19906 if (WORLD_SAVE_P (info))
19913 /* save_world expects lr in r0. */
19914 reg0 = gen_rtx_REG (Pmode, 0);
19915 if (info->lr_save_p)
19917 insn = emit_move_insn (reg0,
19918 gen_rtx_REG (Pmode, LR_REGNO));
19919 RTX_FRAME_RELATED_P (insn) = 1;
19922 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
19923 assumptions about the offsets of various bits of the stack
19925 gcc_assert (info->gp_save_offset == -220
19926 && info->fp_save_offset == -144
19927 && info->lr_save_offset == 8
19928 && info->cr_save_offset == 4
19931 && (!crtl->calls_eh_return
19932 || info->ehrd_offset == -432)
19933 && info->vrsave_save_offset == -224
19934 && info->altivec_save_offset == -416);
19936 treg = gen_rtx_REG (SImode, 11);
19937 emit_move_insn (treg, GEN_INT (-info->total_size));
19939 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
19940 in R11. It also clobbers R12, so beware! */
19942 /* Preserve CR2 for save_world prologues */
19944 sz += 32 - info->first_gp_reg_save;
19945 sz += 64 - info->first_fp_reg_save;
19946 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
19947 p = rtvec_alloc (sz);
19949 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
19950 gen_rtx_REG (SImode,
19952 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
19953 gen_rtx_SYMBOL_REF (Pmode,
19955 /* We do floats first so that the instruction pattern matches
19957 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
19959 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19960 ? DFmode : SFmode),
19961 info->first_fp_reg_save + i);
19962 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19963 GEN_INT (info->fp_save_offset
19964 + sp_offset + 8 * i));
19965 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19966 ? DFmode : SFmode), addr);
19968 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19970 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
19972 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
19973 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19974 GEN_INT (info->altivec_save_offset
19975 + sp_offset + 16 * i));
19976 rtx mem = gen_frame_mem (V4SImode, addr);
19978 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19980 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19982 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19983 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19984 GEN_INT (info->gp_save_offset
19985 + sp_offset + reg_size * i));
19986 rtx mem = gen_frame_mem (reg_mode, addr);
19988 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19992 /* CR register traditionally saved as CR2. */
19993 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
19994 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19995 GEN_INT (info->cr_save_offset
19997 rtx mem = gen_frame_mem (reg_mode, addr);
19999 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20001 /* Explain about use of R0. */
20002 if (info->lr_save_p)
20004 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20005 GEN_INT (info->lr_save_offset
20007 rtx mem = gen_frame_mem (reg_mode, addr);
20009 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
20011 /* Explain what happens to the stack pointer. */
20013 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
20014 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
20017 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20018 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20019 treg, GEN_INT (-info->total_size));
20020 sp_offset = info->total_size;
20023 /* If we use the link register, get it into r0. */
20024 if (!WORLD_SAVE_P (info) && info->lr_save_p)
20026 rtx addr, reg, mem;
20028 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
20029 gen_rtx_REG (Pmode, LR_REGNO));
20030 RTX_FRAME_RELATED_P (insn) = 1;
20032 if (!(strategy & (SAVE_NOINLINE_GPRS_SAVES_LR
20033 | SAVE_NOINLINE_FPRS_SAVES_LR)))
20035 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20036 GEN_INT (info->lr_save_offset + sp_offset));
20037 reg = gen_rtx_REG (Pmode, 0);
20038 mem = gen_rtx_MEM (Pmode, addr);
20039 /* This should not be of rs6000_sr_alias_set, because of
20040 __builtin_return_address. */
20042 insn = emit_move_insn (mem, reg);
20043 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20044 NULL_RTX, NULL_RTX);
20048 /* If we need to save CR, put it into r12 or r11. */
20049 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
20054 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
20056 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20057 RTX_FRAME_RELATED_P (insn) = 1;
20058 /* Now, there's no way that dwarf2out_frame_debug_expr is going
20059 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
20060 But that's OK. All we have to do is specify that _one_ condition
20061 code register is saved in this stack slot. The thrower's epilogue
20062 will then restore all the call-saved registers.
20063 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
20064 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
20065 gen_rtx_REG (SImode, CR2_REGNO));
20066 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20069 /* Do any required saving of fpr's. If only one or two to save, do
20070 it ourselves. Otherwise, call function. */
20071 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
20074 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20075 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
20076 && ! call_used_regs[info->first_fp_reg_save+i]))
20077 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
20078 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20080 info->first_fp_reg_save + i,
20081 info->fp_save_offset + sp_offset + 8 * i,
20084 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
20088 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20089 info->fp_save_offset + sp_offset,
20091 /*savep=*/true, /*gpr=*/false,
20093 & SAVE_NOINLINE_FPRS_SAVES_LR)
20095 insn = emit_insn (par);
20096 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20097 NULL_RTX, NULL_RTX);
20100 /* Save GPRs. This is done as a PARALLEL if we are using
20101 the store-multiple instructions. */
20102 if (!WORLD_SAVE_P (info)
20104 && info->spe_64bit_regs_used != 0
20105 && info->first_gp_reg_save != 32)
20108 rtx spe_save_area_ptr;
20110 /* Determine whether we can address all of the registers that need
20111 to be saved with an offset from the stack pointer that fits in
20112 the small const field for SPE memory instructions. */
20113 int spe_regs_addressable_via_sp
20114 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
20115 + (32 - info->first_gp_reg_save - 1) * reg_size)
20116 && saving_GPRs_inline);
20119 if (spe_regs_addressable_via_sp)
20121 spe_save_area_ptr = frame_reg_rtx;
20122 spe_offset = info->spe_gp_save_offset + sp_offset;
20126 /* Make r11 point to the start of the SPE save area. We need
20127 to be careful here if r11 is holding the static chain. If
20128 it is, then temporarily save it in r0. We would use r0 as
20129 our base register here, but using r0 as a base register in
20130 loads and stores means something different from what we
20132 int ool_adjust = (saving_GPRs_inline
20134 : (info->first_gp_reg_save
20135 - (FIRST_SAVRES_REGISTER+1))*8);
20136 HOST_WIDE_INT offset = (info->spe_gp_save_offset
20137 + sp_offset - ool_adjust);
20139 if (using_static_chain_p)
20141 rtx r0 = gen_rtx_REG (Pmode, 0);
20142 gcc_assert (info->first_gp_reg_save > 11);
20144 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
20147 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
20148 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
20150 GEN_INT (offset)));
20151 /* We need to make sure the move to r11 gets noted for
20152 properly outputting unwind information. */
20153 if (!saving_GPRs_inline)
20154 rs6000_frame_related (insn, frame_reg_rtx, offset,
20155 NULL_RTX, NULL_RTX);
20159 if (saving_GPRs_inline)
20161 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20162 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20164 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20165 rtx offset, addr, mem;
20167 /* We're doing all this to ensure that the offset fits into
20168 the immediate offset of 'evstdd'. */
20169 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
20171 offset = GEN_INT (reg_size * i + spe_offset);
20172 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
20173 mem = gen_rtx_MEM (V2SImode, addr);
20175 insn = emit_move_insn (mem, reg);
20177 rs6000_frame_related (insn, spe_save_area_ptr,
20178 info->spe_gp_save_offset
20179 + sp_offset + reg_size * i,
20180 offset, const0_rtx);
20187 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
20189 /*savep=*/true, /*gpr=*/true,
20191 insn = emit_insn (par);
20192 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20193 NULL_RTX, NULL_RTX);
20197 /* Move the static chain pointer back. */
20198 if (using_static_chain_p && !spe_regs_addressable_via_sp)
20199 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
20201 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
20205 /* Need to adjust r11 (r12) if we saved any FPRs. */
20206 if (info->first_fp_reg_save != 64)
20208 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
20210 rtx offset = GEN_INT (sp_offset
20211 + (-8 * (64-info->first_fp_reg_save)));
20212 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
20215 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20216 info->gp_save_offset + sp_offset,
20218 /*savep=*/true, /*gpr=*/true,
20220 & SAVE_NOINLINE_GPRS_SAVES_LR)
20222 insn = emit_insn (par);
20223 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20224 NULL_RTX, NULL_RTX);
20226 else if (!WORLD_SAVE_P (info) && using_store_multiple)
20230 p = rtvec_alloc (32 - info->first_gp_reg_save);
20231 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20233 rtx addr, reg, mem;
20234 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20235 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20236 GEN_INT (info->gp_save_offset
20239 mem = gen_frame_mem (reg_mode, addr);
20241 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
20243 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20244 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20245 NULL_RTX, NULL_RTX);
20247 else if (!WORLD_SAVE_P (info))
20250 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20251 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20253 rtx addr, reg, mem;
20254 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20256 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20257 GEN_INT (info->gp_save_offset
20260 mem = gen_frame_mem (reg_mode, addr);
20262 insn = emit_move_insn (mem, reg);
20263 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20264 NULL_RTX, NULL_RTX);
20268 /* ??? There's no need to emit actual instructions here, but it's the
20269 easiest way to get the frame unwind information emitted. */
20270 if (crtl->calls_eh_return)
20272 unsigned int i, regno;
20276 regno = EH_RETURN_DATA_REGNO (i);
20277 if (regno == INVALID_REGNUM)
20280 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
20281 info->ehrd_offset + sp_offset
20282 + reg_size * (int) i,
20287 /* In AIX ABI we need to make sure r2 is really saved. */
20288 if (TARGET_AIX && crtl->calls_eh_return)
20290 rtx tmp_reg, tmp_reg_si, hi, lo, compare_result, toc_save_done, jump;
20291 rtx save_insn, join_insn, note;
20292 long toc_restore_insn;
20294 gcc_assert (frame_reg_rtx == frame_ptr_rtx
20295 || frame_reg_rtx == sp_reg_rtx);
20296 tmp_reg = gen_rtx_REG (Pmode, 11);
20297 tmp_reg_si = gen_rtx_REG (SImode, 11);
20298 if (using_static_chain_p)
20299 emit_move_insn (gen_rtx_REG (Pmode, 0), tmp_reg);
20300 gcc_assert (saving_GPRs_inline && saving_FPRs_inline);
20301 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, LR_REGNO));
20302 /* Peek at instruction to which this function returns. If it's
20303 restoring r2, then we know we've already saved r2. We can't
20304 unconditionally save r2 because the value we have will already
20305 be updated if we arrived at this function via a plt call or
20306 toc adjusting stub. */
20307 emit_move_insn (tmp_reg_si, gen_rtx_MEM (SImode, tmp_reg));
20308 toc_restore_insn = TARGET_32BIT ? 0x80410014 : 0xE8410028;
20309 hi = gen_int_mode (toc_restore_insn & ~0xffff, SImode);
20310 emit_insn (gen_xorsi3 (tmp_reg_si, tmp_reg_si, hi));
20311 compare_result = gen_rtx_REG (CCUNSmode, CR0_REGNO);
20312 validate_condition_mode (EQ, CCUNSmode);
20313 lo = gen_int_mode (toc_restore_insn & 0xffff, SImode);
20314 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
20315 gen_rtx_COMPARE (CCUNSmode, tmp_reg_si, lo)));
20316 toc_save_done = gen_label_rtx ();
20317 jump = gen_rtx_IF_THEN_ELSE (VOIDmode,
20318 gen_rtx_EQ (VOIDmode, compare_result,
20320 gen_rtx_LABEL_REF (VOIDmode, toc_save_done),
20322 jump = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, jump));
20323 JUMP_LABEL (jump) = toc_save_done;
20324 LABEL_NUSES (toc_save_done) += 1;
20326 save_insn = emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode,
20327 TOC_REGNUM, sp_offset + 5 * reg_size,
20330 emit_label (toc_save_done);
20332 /* ??? If we leave SAVE_INSN as marked as saving R2, then we'll
20333 have a CFG that has different saves along different paths.
20334 Move the note to a dummy blockage insn, which describes that
20335 R2 is unconditionally saved after the label. */
20336 /* ??? An alternate representation might be a special insn pattern
20337 containing both the branch and the store. That might let the
20338 code that minimizes the number of DW_CFA_advance opcodes better
20339 freedom in placing the annotations. */
20340 note = find_reg_note (save_insn, REG_FRAME_RELATED_EXPR, NULL);
20342 remove_note (save_insn, note);
20343 RTX_FRAME_RELATED_P (save_insn) = 0;
20345 join_insn = emit_insn (gen_blockage ());
20346 REG_NOTES (join_insn) = note;
20347 RTX_FRAME_RELATED_P (join_insn) = 1;
20349 if (using_static_chain_p)
20350 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, 0));
20353 /* Save CR if we use any that must be preserved. */
20354 if (!WORLD_SAVE_P (info) && info->cr_save_p)
20356 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20357 GEN_INT (info->cr_save_offset + sp_offset));
20358 rtx mem = gen_frame_mem (SImode, addr);
20359 /* See the large comment above about why CR2_REGNO is used. */
20360 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
20362 /* If r12 was used to hold the original sp, copy cr into r0 now
20364 if (REGNO (frame_reg_rtx) == 12)
20368 cr_save_rtx = gen_rtx_REG (SImode, 0);
20369 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20370 RTX_FRAME_RELATED_P (insn) = 1;
20371 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
20372 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20374 insn = emit_move_insn (mem, cr_save_rtx);
20376 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20377 NULL_RTX, NULL_RTX);
20380 /* Update stack and set back pointer unless this is V.4,
20381 for which it was done previously. */
20382 if (!WORLD_SAVE_P (info) && info->push_p
20383 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
20385 rtx copy_reg = NULL;
20387 if (info->total_size < 32767)
20388 sp_offset = info->total_size;
20389 else if (info->altivec_size != 0
20390 || info->vrsave_mask != 0)
20392 copy_reg = frame_ptr_rtx;
20393 frame_reg_rtx = copy_reg;
20396 sp_offset = info->total_size;
20397 rs6000_emit_allocate_stack (info->total_size, copy_reg);
20398 if (frame_reg_rtx != sp_reg_rtx)
20399 rs6000_emit_stack_tie ();
20402 /* Set frame pointer, if needed. */
20403 if (frame_pointer_needed)
20405 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
20407 RTX_FRAME_RELATED_P (insn) = 1;
20410 /* Save AltiVec registers if needed. Save here because the red zone does
20411 not include AltiVec registers. */
20412 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
20416 /* There should be a non inline version of this, for when we
20417 are saving lots of vector registers. */
20418 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20419 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20421 rtx areg, savereg, mem;
20424 offset = info->altivec_save_offset + sp_offset
20425 + 16 * (i - info->first_altivec_reg_save);
20427 savereg = gen_rtx_REG (V4SImode, i);
20429 areg = gen_rtx_REG (Pmode, 0);
20430 emit_move_insn (areg, GEN_INT (offset));
20432 /* AltiVec addressing mode is [reg+reg]. */
20433 mem = gen_frame_mem (V4SImode,
20434 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
20436 insn = emit_move_insn (mem, savereg);
20438 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20439 areg, GEN_INT (offset));
20443 /* VRSAVE is a bit vector representing which AltiVec registers
20444 are used. The OS uses this to determine which vector
20445 registers to save on a context switch. We need to save
20446 VRSAVE on the stack frame, add whatever AltiVec registers we
20447 used in this function, and do the corresponding magic in the
20450 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
20451 && info->vrsave_mask != 0)
20453 rtx reg, mem, vrsave;
20456 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
20457 as frame_reg_rtx and r11 as the static chain pointer for
20458 nested functions. */
20459 reg = gen_rtx_REG (SImode, 0);
20460 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
20462 emit_insn (gen_get_vrsave_internal (reg));
20464 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
20466 if (!WORLD_SAVE_P (info))
20469 offset = info->vrsave_save_offset + sp_offset;
20470 mem = gen_frame_mem (SImode,
20471 gen_rtx_PLUS (Pmode, frame_reg_rtx,
20472 GEN_INT (offset)));
20473 insn = emit_move_insn (mem, reg);
20476 /* Include the registers in the mask. */
20477 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
20479 insn = emit_insn (generate_set_vrsave (reg, info, 0));
20482 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
20483 if (!TARGET_SINGLE_PIC_BASE
20484 && ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
20485 || (DEFAULT_ABI == ABI_V4
20486 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
20487 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))))
20489 /* If emit_load_toc_table will use the link register, we need to save
20490 it. We use R12 for this purpose because emit_load_toc_table
20491 can use register 0. This allows us to use a plain 'blr' to return
20492 from the procedure more often. */
20493 int save_LR_around_toc_setup = (TARGET_ELF
20494 && DEFAULT_ABI != ABI_AIX
20496 && ! info->lr_save_p
20497 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
20498 if (save_LR_around_toc_setup)
20500 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
20502 insn = emit_move_insn (frame_ptr_rtx, lr);
20503 RTX_FRAME_RELATED_P (insn) = 1;
20505 rs6000_emit_load_toc_table (TRUE);
20507 insn = emit_move_insn (lr, frame_ptr_rtx);
20508 RTX_FRAME_RELATED_P (insn) = 1;
20511 rs6000_emit_load_toc_table (TRUE);
20515 if (!TARGET_SINGLE_PIC_BASE
20516 && DEFAULT_ABI == ABI_DARWIN
20517 && flag_pic && crtl->uses_pic_offset_table)
20519 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
20520 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
20522 /* Save and restore LR locally around this call (in R0). */
20523 if (!info->lr_save_p)
20524 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
20526 emit_insn (gen_load_macho_picbase (src));
20528 emit_move_insn (gen_rtx_REG (Pmode,
20529 RS6000_PIC_OFFSET_TABLE_REGNUM),
20532 if (!info->lr_save_p)
20533 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
20537 /* If we need to, save the TOC register after doing the stack setup.
20538 Do not emit eh frame info for this save. The unwinder wants info,
20539 conceptually attached to instructions in this function, about
20540 register values in the caller of this function. This R2 may have
20541 already been changed from the value in the caller.
20542 We don't attempt to write accurate DWARF EH frame info for R2
20543 because code emitted by gcc for a (non-pointer) function call
20544 doesn't save and restore R2. Instead, R2 is managed out-of-line
20545 by a linker generated plt call stub when the function resides in
20546 a shared library. This behaviour is costly to describe in DWARF,
20547 both in terms of the size of DWARF info and the time taken in the
20548 unwinder to interpret it. R2 changes, apart from the
20549 calls_eh_return case earlier in this function, are handled by
20550 linux-unwind.h frob_update_context. */
20551 if (rs6000_save_toc_in_prologue_p ())
20553 rtx addr = gen_rtx_PLUS (Pmode, sp_reg_rtx, GEN_INT (5 * reg_size));
20554 rtx mem = gen_frame_mem (reg_mode, addr);
20555 emit_move_insn (mem, gen_rtx_REG (reg_mode, TOC_REGNUM));
20559 /* Write function prologue. */
20562 rs6000_output_function_prologue (FILE *file,
20563 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
20565 rs6000_stack_t *info = rs6000_stack_info ();
20567 if (TARGET_DEBUG_STACK)
20568 debug_stack_info (info);
20570 /* Write .extern for any function we will call to save and restore
20572 if (info->first_fp_reg_save < 64)
20575 int regno = info->first_fp_reg_save - 32;
20577 if ((info->savres_strategy & SAVE_INLINE_FPRS) == 0)
20579 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
20580 /*gpr=*/false, /*lr=*/false);
20581 fprintf (file, "\t.extern %s\n", name);
20583 if ((info->savres_strategy & REST_INLINE_FPRS) == 0)
20585 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
20586 /*gpr=*/false, /*lr=*/true);
20587 fprintf (file, "\t.extern %s\n", name);
20591 /* Write .extern for AIX common mode routines, if needed. */
20592 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
20594 fputs ("\t.extern __mulh\n", file);
20595 fputs ("\t.extern __mull\n", file);
20596 fputs ("\t.extern __divss\n", file);
20597 fputs ("\t.extern __divus\n", file);
20598 fputs ("\t.extern __quoss\n", file);
20599 fputs ("\t.extern __quous\n", file);
20600 common_mode_defined = 1;
20603 rs6000_pic_labelno++;
20606 /* Non-zero if vmx regs are restored before the frame pop, zero if
20607 we restore after the pop when possible. */
20608 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
20610 /* Reload CR from REG. */
20613 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
20618 if (using_mfcr_multiple)
20620 for (i = 0; i < 8; i++)
20621 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20623 gcc_assert (count);
20626 if (using_mfcr_multiple && count > 1)
20631 p = rtvec_alloc (count);
20634 for (i = 0; i < 8; i++)
20635 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20637 rtvec r = rtvec_alloc (2);
20638 RTVEC_ELT (r, 0) = reg;
20639 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
20640 RTVEC_ELT (p, ndx) =
20641 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
20642 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
20645 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20646 gcc_assert (ndx == count);
20649 for (i = 0; i < 8; i++)
20650 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20652 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
20658 /* Return true if OFFSET from stack pointer can be clobbered by signals.
20659 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
20660 below stack pointer not cloberred by signals. */
20663 offset_below_red_zone_p (HOST_WIDE_INT offset)
20665 return offset < (DEFAULT_ABI == ABI_V4
20667 : TARGET_32BIT ? -220 : -288);
20670 /* Emit function epilogue as insns. */
20673 rs6000_emit_epilogue (int sibcall)
20675 rs6000_stack_t *info;
20676 int restoring_GPRs_inline;
20677 int restoring_FPRs_inline;
20678 int using_load_multiple;
20679 int using_mtcr_multiple;
20680 int use_backchain_to_restore_sp;
20684 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
20685 rtx frame_reg_rtx = sp_reg_rtx;
20686 rtx cfa_restores = NULL_RTX;
20688 rtx cr_save_reg = NULL_RTX;
20689 enum machine_mode reg_mode = Pmode;
20690 int reg_size = TARGET_32BIT ? 4 : 8;
20693 info = rs6000_stack_info ();
20695 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
20697 reg_mode = V2SImode;
20701 strategy = info->savres_strategy;
20702 using_load_multiple = strategy & SAVRES_MULTIPLE;
20703 restoring_FPRs_inline = sibcall || (strategy & REST_INLINE_FPRS);
20704 restoring_GPRs_inline = sibcall || (strategy & REST_INLINE_GPRS);
20705 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
20706 || rs6000_cpu == PROCESSOR_PPC603
20707 || rs6000_cpu == PROCESSOR_PPC750
20709 /* Restore via the backchain when we have a large frame, since this
20710 is more efficient than an addis, addi pair. The second condition
20711 here will not trigger at the moment; We don't actually need a
20712 frame pointer for alloca, but the generic parts of the compiler
20713 give us one anyway. */
20714 use_backchain_to_restore_sp = (info->total_size > 32767
20715 || info->total_size
20716 + (info->lr_save_p ? info->lr_save_offset : 0)
20718 || (cfun->calls_alloca
20719 && !frame_pointer_needed));
20720 restore_lr = (info->lr_save_p
20721 && (restoring_FPRs_inline
20722 || (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR))
20723 && (restoring_GPRs_inline
20724 || info->first_fp_reg_save < 64));
20726 if (WORLD_SAVE_P (info))
20730 const char *alloc_rname;
20733 /* eh_rest_world_r10 will return to the location saved in the LR
20734 stack slot (which is not likely to be our caller.)
20735 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
20736 rest_world is similar, except any R10 parameter is ignored.
20737 The exception-handling stuff that was here in 2.95 is no
20738 longer necessary. */
20742 + 32 - info->first_gp_reg_save
20743 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
20744 + 63 + 1 - info->first_fp_reg_save);
20746 strcpy (rname, ((crtl->calls_eh_return) ?
20747 "*eh_rest_world_r10" : "*rest_world"));
20748 alloc_rname = ggc_strdup (rname);
20751 RTVEC_ELT (p, j++) = ret_rtx;
20752 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
20753 gen_rtx_REG (Pmode,
20756 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
20757 /* The instruction pattern requires a clobber here;
20758 it is shared with the restVEC helper. */
20760 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
20763 /* CR register traditionally saved as CR2. */
20764 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
20765 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20766 GEN_INT (info->cr_save_offset));
20767 rtx mem = gen_frame_mem (reg_mode, addr);
20769 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20772 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20774 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20775 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20776 GEN_INT (info->gp_save_offset
20778 rtx mem = gen_frame_mem (reg_mode, addr);
20780 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20782 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
20784 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
20785 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20786 GEN_INT (info->altivec_save_offset
20788 rtx mem = gen_frame_mem (V4SImode, addr);
20790 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20792 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
20794 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20795 ? DFmode : SFmode),
20796 info->first_fp_reg_save + i);
20797 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20798 GEN_INT (info->fp_save_offset
20800 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20801 ? DFmode : SFmode), addr);
20803 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20806 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
20808 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
20810 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
20812 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
20814 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
20815 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
20820 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
20822 sp_offset = info->total_size;
20824 /* Restore AltiVec registers if we must do so before adjusting the
20826 if (TARGET_ALTIVEC_ABI
20827 && info->altivec_size != 0
20828 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20829 || (DEFAULT_ABI != ABI_V4
20830 && offset_below_red_zone_p (info->altivec_save_offset))))
20834 if (use_backchain_to_restore_sp)
20836 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20837 emit_move_insn (frame_reg_rtx,
20838 gen_rtx_MEM (Pmode, sp_reg_rtx));
20841 else if (frame_pointer_needed)
20842 frame_reg_rtx = hard_frame_pointer_rtx;
20844 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20845 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20847 rtx addr, areg, mem, reg;
20849 areg = gen_rtx_REG (Pmode, 0);
20851 (areg, GEN_INT (info->altivec_save_offset
20853 + 16 * (i - info->first_altivec_reg_save)));
20855 /* AltiVec addressing mode is [reg+reg]. */
20856 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
20857 mem = gen_frame_mem (V4SImode, addr);
20859 reg = gen_rtx_REG (V4SImode, i);
20860 emit_move_insn (reg, mem);
20861 if (offset_below_red_zone_p (info->altivec_save_offset
20862 + (i - info->first_altivec_reg_save)
20864 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20869 /* Restore VRSAVE if we must do so before adjusting the stack. */
20871 && TARGET_ALTIVEC_VRSAVE
20872 && info->vrsave_mask != 0
20873 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20874 || (DEFAULT_ABI != ABI_V4
20875 && offset_below_red_zone_p (info->vrsave_save_offset))))
20877 rtx addr, mem, reg;
20879 if (frame_reg_rtx == sp_reg_rtx)
20881 if (use_backchain_to_restore_sp)
20883 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20884 emit_move_insn (frame_reg_rtx,
20885 gen_rtx_MEM (Pmode, sp_reg_rtx));
20888 else if (frame_pointer_needed)
20889 frame_reg_rtx = hard_frame_pointer_rtx;
20892 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20893 GEN_INT (info->vrsave_save_offset + sp_offset));
20894 mem = gen_frame_mem (SImode, addr);
20895 reg = gen_rtx_REG (SImode, 12);
20896 emit_move_insn (reg, mem);
20898 emit_insn (generate_set_vrsave (reg, info, 1));
20902 /* If we have a large stack frame, restore the old stack pointer
20903 using the backchain. */
20904 if (use_backchain_to_restore_sp)
20906 if (frame_reg_rtx == sp_reg_rtx)
20908 /* Under V.4, don't reset the stack pointer until after we're done
20909 loading the saved registers. */
20910 if (DEFAULT_ABI == ABI_V4)
20911 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20913 insn = emit_move_insn (frame_reg_rtx,
20914 gen_rtx_MEM (Pmode, sp_reg_rtx));
20917 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20918 && DEFAULT_ABI == ABI_V4)
20919 /* frame_reg_rtx has been set up by the altivec restore. */
20923 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
20924 frame_reg_rtx = sp_reg_rtx;
20927 /* If we have a frame pointer, we can restore the old stack pointer
20929 else if (frame_pointer_needed)
20931 frame_reg_rtx = sp_reg_rtx;
20932 if (DEFAULT_ABI == ABI_V4)
20933 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20934 /* Prevent reordering memory accesses against stack pointer restore. */
20935 else if (cfun->calls_alloca
20936 || offset_below_red_zone_p (-info->total_size))
20938 rtx mem1 = gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx);
20939 rtx mem2 = gen_rtx_MEM (BLKmode, sp_reg_rtx);
20940 MEM_NOTRAP_P (mem1) = 1;
20941 MEM_NOTRAP_P (mem2) = 1;
20942 emit_insn (gen_frame_tie (mem1, mem2));
20945 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
20946 GEN_INT (info->total_size)));
20949 else if (info->push_p
20950 && DEFAULT_ABI != ABI_V4
20951 && !crtl->calls_eh_return)
20953 /* Prevent reordering memory accesses against stack pointer restore. */
20954 if (cfun->calls_alloca
20955 || offset_below_red_zone_p (-info->total_size))
20957 rtx mem = gen_rtx_MEM (BLKmode, sp_reg_rtx);
20958 MEM_NOTRAP_P (mem) = 1;
20959 emit_insn (gen_stack_tie (mem));
20961 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
20962 GEN_INT (info->total_size)));
20965 if (insn && frame_reg_rtx == sp_reg_rtx)
20969 REG_NOTES (insn) = cfa_restores;
20970 cfa_restores = NULL_RTX;
20972 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
20973 RTX_FRAME_RELATED_P (insn) = 1;
20976 /* Restore AltiVec registers if we have not done so already. */
20977 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20978 && TARGET_ALTIVEC_ABI
20979 && info->altivec_size != 0
20980 && (DEFAULT_ABI == ABI_V4
20981 || !offset_below_red_zone_p (info->altivec_save_offset)))
20985 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20986 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20988 rtx addr, areg, mem, reg;
20990 areg = gen_rtx_REG (Pmode, 0);
20992 (areg, GEN_INT (info->altivec_save_offset
20994 + 16 * (i - info->first_altivec_reg_save)));
20996 /* AltiVec addressing mode is [reg+reg]. */
20997 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
20998 mem = gen_frame_mem (V4SImode, addr);
21000 reg = gen_rtx_REG (V4SImode, i);
21001 emit_move_insn (reg, mem);
21002 if (DEFAULT_ABI == ABI_V4)
21003 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21008 /* Restore VRSAVE if we have not done so already. */
21009 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21011 && TARGET_ALTIVEC_VRSAVE
21012 && info->vrsave_mask != 0
21013 && (DEFAULT_ABI == ABI_V4
21014 || !offset_below_red_zone_p (info->vrsave_save_offset)))
21016 rtx addr, mem, reg;
21018 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21019 GEN_INT (info->vrsave_save_offset + sp_offset));
21020 mem = gen_frame_mem (SImode, addr);
21021 reg = gen_rtx_REG (SImode, 12);
21022 emit_move_insn (reg, mem);
21024 emit_insn (generate_set_vrsave (reg, info, 1));
21027 /* Get the old lr if we saved it. If we are restoring registers
21028 out-of-line, then the out-of-line routines can do this for us. */
21029 if (restore_lr && restoring_GPRs_inline)
21031 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21032 info->lr_save_offset + sp_offset);
21034 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21037 /* Get the old cr if we saved it. */
21038 if (info->cr_save_p)
21040 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21041 GEN_INT (info->cr_save_offset + sp_offset));
21042 rtx mem = gen_frame_mem (SImode, addr);
21044 cr_save_reg = gen_rtx_REG (SImode,
21045 DEFAULT_ABI == ABI_AIX
21046 && !restoring_GPRs_inline
21047 && info->first_fp_reg_save < 64
21049 emit_move_insn (cr_save_reg, mem);
21052 /* Set LR here to try to overlap restores below. LR is always saved
21053 above incoming stack, so it never needs REG_CFA_RESTORE. */
21054 if (restore_lr && restoring_GPRs_inline)
21055 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21056 gen_rtx_REG (Pmode, 0));
21058 /* Load exception handler data registers, if needed. */
21059 if (crtl->calls_eh_return)
21061 unsigned int i, regno;
21065 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21066 GEN_INT (sp_offset + 5 * reg_size));
21067 rtx mem = gen_frame_mem (reg_mode, addr);
21069 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
21076 regno = EH_RETURN_DATA_REGNO (i);
21077 if (regno == INVALID_REGNUM)
21080 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
21081 info->ehrd_offset + sp_offset
21082 + reg_size * (int) i);
21084 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
21088 /* Restore GPRs. This is done as a PARALLEL if we are using
21089 the load-multiple instructions. */
21091 && info->spe_64bit_regs_used != 0
21092 && info->first_gp_reg_save != 32)
21094 /* Determine whether we can address all of the registers that need
21095 to be saved with an offset from the stack pointer that fits in
21096 the small const field for SPE memory instructions. */
21097 int spe_regs_addressable_via_sp
21098 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
21099 + (32 - info->first_gp_reg_save - 1) * reg_size)
21100 && restoring_GPRs_inline);
21103 if (spe_regs_addressable_via_sp)
21104 spe_offset = info->spe_gp_save_offset + sp_offset;
21107 rtx old_frame_reg_rtx = frame_reg_rtx;
21108 /* Make r11 point to the start of the SPE save area. We worried about
21109 not clobbering it when we were saving registers in the prologue.
21110 There's no need to worry here because the static chain is passed
21111 anew to every function. */
21112 int ool_adjust = (restoring_GPRs_inline
21114 : (info->first_gp_reg_save
21115 - (FIRST_SAVRES_REGISTER+1))*8);
21117 if (frame_reg_rtx == sp_reg_rtx)
21118 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21119 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
21120 GEN_INT (info->spe_gp_save_offset
21123 /* Keep the invariant that frame_reg_rtx + sp_offset points
21124 at the top of the stack frame. */
21125 sp_offset = -info->spe_gp_save_offset;
21130 if (restoring_GPRs_inline)
21132 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21133 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21135 rtx offset, addr, mem, reg;
21137 /* We're doing all this to ensure that the immediate offset
21138 fits into the immediate field of 'evldd'. */
21139 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
21141 offset = GEN_INT (spe_offset + reg_size * i);
21142 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
21143 mem = gen_rtx_MEM (V2SImode, addr);
21144 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21146 insn = emit_move_insn (reg, mem);
21147 if (DEFAULT_ABI == ABI_V4)
21149 if (frame_pointer_needed
21150 && info->first_gp_reg_save + i
21151 == HARD_FRAME_POINTER_REGNUM)
21153 add_reg_note (insn, REG_CFA_DEF_CFA,
21154 plus_constant (frame_reg_rtx,
21156 RTX_FRAME_RELATED_P (insn) = 1;
21159 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21168 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
21170 /*savep=*/false, /*gpr=*/true,
21172 emit_jump_insn (par);
21173 /* We don't want anybody else emitting things after we jumped
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;
21184 /* 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);
21190 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
21193 GEN_INT (sp_offset - info->fp_size)));
21194 if (REGNO (frame_reg_rtx) == 11)
21195 sp_offset += info->fp_size;
21198 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
21199 info->gp_save_offset, reg_mode,
21200 /*savep=*/false, /*gpr=*/true,
21201 /*lr=*/can_use_exit);
21205 if (info->cr_save_p)
21207 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21208 if (DEFAULT_ABI == ABI_V4)
21210 = alloc_reg_note (REG_CFA_RESTORE,
21211 gen_rtx_REG (SImode, CR2_REGNO),
21215 emit_jump_insn (par);
21217 /* We don't want anybody else emitting things after we jumped
21222 insn = emit_insn (par);
21223 if (DEFAULT_ABI == ABI_V4)
21225 if (frame_pointer_needed)
21227 add_reg_note (insn, REG_CFA_DEF_CFA,
21228 plus_constant (frame_reg_rtx, sp_offset));
21229 RTX_FRAME_RELATED_P (insn) = 1;
21232 for (i = info->first_gp_reg_save; i < 32; i++)
21234 = alloc_reg_note (REG_CFA_RESTORE,
21235 gen_rtx_REG (reg_mode, i), cfa_restores);
21238 else if (using_load_multiple)
21241 p = rtvec_alloc (32 - info->first_gp_reg_save);
21242 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21244 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21245 GEN_INT (info->gp_save_offset
21248 rtx mem = gen_frame_mem (reg_mode, addr);
21249 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21251 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
21252 if (DEFAULT_ABI == ABI_V4)
21253 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21256 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
21257 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
21259 add_reg_note (insn, REG_CFA_DEF_CFA,
21260 plus_constant (frame_reg_rtx, sp_offset));
21261 RTX_FRAME_RELATED_P (insn) = 1;
21266 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21267 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21269 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21270 GEN_INT (info->gp_save_offset
21273 rtx mem = gen_frame_mem (reg_mode, addr);
21274 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21276 insn = emit_move_insn (reg, mem);
21277 if (DEFAULT_ABI == ABI_V4)
21279 if (frame_pointer_needed
21280 && info->first_gp_reg_save + i
21281 == HARD_FRAME_POINTER_REGNUM)
21283 add_reg_note (insn, REG_CFA_DEF_CFA,
21284 plus_constant (frame_reg_rtx, sp_offset));
21285 RTX_FRAME_RELATED_P (insn) = 1;
21288 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21294 if (restore_lr && !restoring_GPRs_inline)
21296 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21297 info->lr_save_offset + sp_offset);
21299 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21300 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21301 gen_rtx_REG (Pmode, 0));
21304 /* Restore fpr's if we need to do it without calling a function. */
21305 if (restoring_FPRs_inline)
21306 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21307 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
21308 && ! call_used_regs[info->first_fp_reg_save+i]))
21310 rtx addr, mem, reg;
21311 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21312 GEN_INT (info->fp_save_offset
21315 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21316 ? DFmode : SFmode), addr);
21317 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21318 ? DFmode : SFmode),
21319 info->first_fp_reg_save + i);
21321 emit_move_insn (reg, mem);
21322 if (DEFAULT_ABI == ABI_V4)
21323 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21327 /* If we saved cr, restore it here. Just those that were used. */
21328 if (info->cr_save_p)
21330 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21331 if (DEFAULT_ABI == ABI_V4)
21333 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
21337 /* If this is V.4, unwind the stack pointer after all of the loads
21339 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21340 sp_offset, !restoring_FPRs_inline);
21345 REG_NOTES (insn) = cfa_restores;
21346 cfa_restores = NULL_RTX;
21348 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
21349 RTX_FRAME_RELATED_P (insn) = 1;
21352 if (crtl->calls_eh_return)
21354 rtx sa = EH_RETURN_STACKADJ_RTX;
21355 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
21361 bool lr = (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
21362 if (! restoring_FPRs_inline)
21363 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
21365 p = rtvec_alloc (2);
21367 RTVEC_ELT (p, 0) = ret_rtx;
21368 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
21369 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
21370 : gen_rtx_CLOBBER (VOIDmode,
21371 gen_rtx_REG (Pmode, 65)));
21373 /* If we have to restore more than two FP registers, branch to the
21374 restore function. It will return to our caller. */
21375 if (! restoring_FPRs_inline)
21380 sym = rs6000_savres_routine_sym (info,
21384 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
21385 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
21386 gen_rtx_REG (Pmode,
21387 DEFAULT_ABI == ABI_AIX
21389 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21392 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
21393 GEN_INT (info->fp_save_offset + 8*i));
21394 mem = gen_frame_mem (DFmode, addr);
21396 RTVEC_ELT (p, i+4) =
21397 gen_rtx_SET (VOIDmode,
21398 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
21403 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
21407 /* Write function epilogue. */
21410 rs6000_output_function_epilogue (FILE *file,
21411 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
21414 macho_branch_islands ();
21415 /* Mach-O doesn't support labels at the end of objects, so if
21416 it looks like we might want one, insert a NOP. */
21418 rtx insn = get_last_insn ();
21421 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
21422 insn = PREV_INSN (insn);
21426 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
21427 fputs ("\tnop\n", file);
21431 /* Output a traceback table here. See /usr/include/sys/debug.h for info
21434 We don't output a traceback table if -finhibit-size-directive was
21435 used. The documentation for -finhibit-size-directive reads
21436 ``don't output a @code{.size} assembler directive, or anything
21437 else that would cause trouble if the function is split in the
21438 middle, and the two halves are placed at locations far apart in
21439 memory.'' The traceback table has this property, since it
21440 includes the offset from the start of the function to the
21441 traceback table itself.
21443 System V.4 Powerpc's (and the embedded ABI derived from it) use a
21444 different traceback table. */
21445 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
21446 && rs6000_traceback != traceback_none && !cfun->is_thunk)
21448 const char *fname = NULL;
21449 const char *language_string = lang_hooks.name;
21450 int fixed_parms = 0, float_parms = 0, parm_info = 0;
21452 int optional_tbtab;
21453 rs6000_stack_t *info = rs6000_stack_info ();
21455 if (rs6000_traceback == traceback_full)
21456 optional_tbtab = 1;
21457 else if (rs6000_traceback == traceback_part)
21458 optional_tbtab = 0;
21460 optional_tbtab = !optimize_size && !TARGET_ELF;
21462 if (optional_tbtab)
21464 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
21465 while (*fname == '.') /* V.4 encodes . in the name */
21468 /* Need label immediately before tbtab, so we can compute
21469 its offset from the function start. */
21470 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
21471 ASM_OUTPUT_LABEL (file, fname);
21474 /* The .tbtab pseudo-op can only be used for the first eight
21475 expressions, since it can't handle the possibly variable
21476 length fields that follow. However, if you omit the optional
21477 fields, the assembler outputs zeros for all optional fields
21478 anyways, giving each variable length field is minimum length
21479 (as defined in sys/debug.h). Thus we can not use the .tbtab
21480 pseudo-op at all. */
21482 /* An all-zero word flags the start of the tbtab, for debuggers
21483 that have to find it by searching forward from the entry
21484 point or from the current pc. */
21485 fputs ("\t.long 0\n", file);
21487 /* Tbtab format type. Use format type 0. */
21488 fputs ("\t.byte 0,", file);
21490 /* Language type. Unfortunately, there does not seem to be any
21491 official way to discover the language being compiled, so we
21492 use language_string.
21493 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
21494 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
21495 a number, so for now use 9. LTO and Go aren't assigned numbers
21496 either, so for now use 0. */
21497 if (! strcmp (language_string, "GNU C")
21498 || ! strcmp (language_string, "GNU GIMPLE")
21499 || ! strcmp (language_string, "GNU Go"))
21501 else if (! strcmp (language_string, "GNU F77")
21502 || ! strcmp (language_string, "GNU Fortran"))
21504 else if (! strcmp (language_string, "GNU Pascal"))
21506 else if (! strcmp (language_string, "GNU Ada"))
21508 else if (! strcmp (language_string, "GNU C++")
21509 || ! strcmp (language_string, "GNU Objective-C++"))
21511 else if (! strcmp (language_string, "GNU Java"))
21513 else if (! strcmp (language_string, "GNU Objective-C"))
21516 gcc_unreachable ();
21517 fprintf (file, "%d,", i);
21519 /* 8 single bit fields: global linkage (not set for C extern linkage,
21520 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
21521 from start of procedure stored in tbtab, internal function, function
21522 has controlled storage, function has no toc, function uses fp,
21523 function logs/aborts fp operations. */
21524 /* Assume that fp operations are used if any fp reg must be saved. */
21525 fprintf (file, "%d,",
21526 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
21528 /* 6 bitfields: function is interrupt handler, name present in
21529 proc table, function calls alloca, on condition directives
21530 (controls stack walks, 3 bits), saves condition reg, saves
21532 /* The `function calls alloca' bit seems to be set whenever reg 31 is
21533 set up as a frame pointer, even when there is no alloca call. */
21534 fprintf (file, "%d,",
21535 ((optional_tbtab << 6)
21536 | ((optional_tbtab & frame_pointer_needed) << 5)
21537 | (info->cr_save_p << 1)
21538 | (info->lr_save_p)));
21540 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
21542 fprintf (file, "%d,",
21543 (info->push_p << 7) | (64 - info->first_fp_reg_save));
21545 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
21546 fprintf (file, "%d,", (32 - first_reg_to_save ()));
21548 if (optional_tbtab)
21550 /* Compute the parameter info from the function decl argument
21553 int next_parm_info_bit = 31;
21555 for (decl = DECL_ARGUMENTS (current_function_decl);
21556 decl; decl = DECL_CHAIN (decl))
21558 rtx parameter = DECL_INCOMING_RTL (decl);
21559 enum machine_mode mode = GET_MODE (parameter);
21561 if (GET_CODE (parameter) == REG)
21563 if (SCALAR_FLOAT_MODE_P (mode))
21584 gcc_unreachable ();
21587 /* If only one bit will fit, don't or in this entry. */
21588 if (next_parm_info_bit > 0)
21589 parm_info |= (bits << (next_parm_info_bit - 1));
21590 next_parm_info_bit -= 2;
21594 fixed_parms += ((GET_MODE_SIZE (mode)
21595 + (UNITS_PER_WORD - 1))
21597 next_parm_info_bit -= 1;
21603 /* Number of fixed point parameters. */
21604 /* This is actually the number of words of fixed point parameters; thus
21605 an 8 byte struct counts as 2; and thus the maximum value is 8. */
21606 fprintf (file, "%d,", fixed_parms);
21608 /* 2 bitfields: number of floating point parameters (7 bits), parameters
21610 /* This is actually the number of fp registers that hold parameters;
21611 and thus the maximum value is 13. */
21612 /* Set parameters on stack bit if parameters are not in their original
21613 registers, regardless of whether they are on the stack? Xlc
21614 seems to set the bit when not optimizing. */
21615 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
21617 if (! optional_tbtab)
21620 /* Optional fields follow. Some are variable length. */
21622 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
21623 11 double float. */
21624 /* There is an entry for each parameter in a register, in the order that
21625 they occur in the parameter list. Any intervening arguments on the
21626 stack are ignored. If the list overflows a long (max possible length
21627 34 bits) then completely leave off all elements that don't fit. */
21628 /* Only emit this long if there was at least one parameter. */
21629 if (fixed_parms || float_parms)
21630 fprintf (file, "\t.long %d\n", parm_info);
21632 /* Offset from start of code to tb table. */
21633 fputs ("\t.long ", file);
21634 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
21635 RS6000_OUTPUT_BASENAME (file, fname);
21637 rs6000_output_function_entry (file, fname);
21640 /* Interrupt handler mask. */
21641 /* Omit this long, since we never set the interrupt handler bit
21644 /* Number of CTL (controlled storage) anchors. */
21645 /* Omit this long, since the has_ctl bit is never set above. */
21647 /* Displacement into stack of each CTL anchor. */
21648 /* Omit this list of longs, because there are no CTL anchors. */
21650 /* Length of function name. */
21653 fprintf (file, "\t.short %d\n", (int) strlen (fname));
21655 /* Function name. */
21656 assemble_string (fname, strlen (fname));
21658 /* Register for alloca automatic storage; this is always reg 31.
21659 Only emit this if the alloca bit was set above. */
21660 if (frame_pointer_needed)
21661 fputs ("\t.byte 31\n", file);
21663 fputs ("\t.align 2\n", file);
21667 /* A C compound statement that outputs the assembler code for a thunk
21668 function, used to implement C++ virtual function calls with
21669 multiple inheritance. The thunk acts as a wrapper around a virtual
21670 function, adjusting the implicit object parameter before handing
21671 control off to the real function.
21673 First, emit code to add the integer DELTA to the location that
21674 contains the incoming first argument. Assume that this argument
21675 contains a pointer, and is the one used to pass the `this' pointer
21676 in C++. This is the incoming argument *before* the function
21677 prologue, e.g. `%o0' on a sparc. The addition must preserve the
21678 values of all other incoming arguments.
21680 After the addition, emit code to jump to FUNCTION, which is a
21681 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
21682 not touch the return address. Hence returning from FUNCTION will
21683 return to whoever called the current `thunk'.
21685 The effect must be as if FUNCTION had been called directly with the
21686 adjusted first argument. This macro is responsible for emitting
21687 all of the code for a thunk function; output_function_prologue()
21688 and output_function_epilogue() are not invoked.
21690 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
21691 been extracted from it.) It might possibly be useful on some
21692 targets, but probably not.
21694 If you do not define this macro, the target-independent code in the
21695 C++ frontend will generate a less efficient heavyweight thunk that
21696 calls FUNCTION instead of jumping to it. The generic approach does
21697 not support varargs. */
21700 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
21701 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
21704 rtx this_rtx, insn, funexp;
21706 reload_completed = 1;
21707 epilogue_completed = 1;
21709 /* Mark the end of the (empty) prologue. */
21710 emit_note (NOTE_INSN_PROLOGUE_END);
21712 /* Find the "this" pointer. If the function returns a structure,
21713 the structure return pointer is in r3. */
21714 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
21715 this_rtx = gen_rtx_REG (Pmode, 4);
21717 this_rtx = gen_rtx_REG (Pmode, 3);
21719 /* Apply the constant offset, if required. */
21721 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
21723 /* Apply the offset from the vtable, if required. */
21726 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
21727 rtx tmp = gen_rtx_REG (Pmode, 12);
21729 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
21730 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
21732 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
21733 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
21737 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
21739 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
21741 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
21744 /* Generate a tail call to the target function. */
21745 if (!TREE_USED (function))
21747 assemble_external (function);
21748 TREE_USED (function) = 1;
21750 funexp = XEXP (DECL_RTL (function), 0);
21751 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
21754 if (MACHOPIC_INDIRECT)
21755 funexp = machopic_indirect_call_target (funexp);
21758 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
21759 generate sibcall RTL explicitly. */
21760 insn = emit_call_insn (
21761 gen_rtx_PARALLEL (VOIDmode,
21763 gen_rtx_CALL (VOIDmode,
21764 funexp, const0_rtx),
21765 gen_rtx_USE (VOIDmode, const0_rtx),
21766 gen_rtx_USE (VOIDmode,
21767 gen_rtx_REG (SImode,
21770 SIBLING_CALL_P (insn) = 1;
21773 /* Run just enough of rest_of_compilation to get the insns emitted.
21774 There's not really enough bulk here to make other passes such as
21775 instruction scheduling worth while. Note that use_thunk calls
21776 assemble_start_function and assemble_end_function. */
21777 insn = get_insns ();
21778 insn_locators_alloc ();
21779 shorten_branches (insn);
21780 final_start_function (insn, file, 1);
21781 final (insn, file, 1);
21782 final_end_function ();
21784 reload_completed = 0;
21785 epilogue_completed = 0;
21788 /* A quick summary of the various types of 'constant-pool tables'
21791 Target Flags Name One table per
21792 AIX (none) AIX TOC object file
21793 AIX -mfull-toc AIX TOC object file
21794 AIX -mminimal-toc AIX minimal TOC translation unit
21795 SVR4/EABI (none) SVR4 SDATA object file
21796 SVR4/EABI -fpic SVR4 pic object file
21797 SVR4/EABI -fPIC SVR4 PIC translation unit
21798 SVR4/EABI -mrelocatable EABI TOC function
21799 SVR4/EABI -maix AIX TOC object file
21800 SVR4/EABI -maix -mminimal-toc
21801 AIX minimal TOC translation unit
21803 Name Reg. Set by entries contains:
21804 made by addrs? fp? sum?
21806 AIX TOC 2 crt0 as Y option option
21807 AIX minimal TOC 30 prolog gcc Y Y option
21808 SVR4 SDATA 13 crt0 gcc N Y N
21809 SVR4 pic 30 prolog ld Y not yet N
21810 SVR4 PIC 30 prolog gcc Y option option
21811 EABI TOC 30 prolog gcc Y option option
21815 /* Hash functions for the hash table. */
21818 rs6000_hash_constant (rtx k)
21820 enum rtx_code code = GET_CODE (k);
21821 enum machine_mode mode = GET_MODE (k);
21822 unsigned result = (code << 3) ^ mode;
21823 const char *format;
21826 format = GET_RTX_FORMAT (code);
21827 flen = strlen (format);
21833 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
21836 if (mode != VOIDmode)
21837 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
21849 for (; fidx < flen; fidx++)
21850 switch (format[fidx])
21855 const char *str = XSTR (k, fidx);
21856 len = strlen (str);
21857 result = result * 613 + len;
21858 for (i = 0; i < len; i++)
21859 result = result * 613 + (unsigned) str[i];
21864 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
21868 result = result * 613 + (unsigned) XINT (k, fidx);
21871 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
21872 result = result * 613 + (unsigned) XWINT (k, fidx);
21876 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
21877 result = result * 613 + (unsigned) (XWINT (k, fidx)
21884 gcc_unreachable ();
21891 toc_hash_function (const void *hash_entry)
21893 const struct toc_hash_struct *thc =
21894 (const struct toc_hash_struct *) hash_entry;
21895 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
21898 /* Compare H1 and H2 for equivalence. */
21901 toc_hash_eq (const void *h1, const void *h2)
21903 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
21904 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
21906 if (((const struct toc_hash_struct *) h1)->key_mode
21907 != ((const struct toc_hash_struct *) h2)->key_mode)
21910 return rtx_equal_p (r1, r2);
21913 /* These are the names given by the C++ front-end to vtables, and
21914 vtable-like objects. Ideally, this logic should not be here;
21915 instead, there should be some programmatic way of inquiring as
21916 to whether or not an object is a vtable. */
21918 #define VTABLE_NAME_P(NAME) \
21919 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
21920 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
21921 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
21922 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
21923 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
21925 #ifdef NO_DOLLAR_IN_LABEL
21926 /* Return a GGC-allocated character string translating dollar signs in
21927 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
21930 rs6000_xcoff_strip_dollar (const char *name)
21936 q = (const char *) strchr (name, '$');
21938 if (q == 0 || q == name)
21941 len = strlen (name);
21942 strip = XALLOCAVEC (char, len + 1);
21943 strcpy (strip, name);
21944 p = strip + (q - name);
21948 p = strchr (p + 1, '$');
21951 return ggc_alloc_string (strip, len);
21956 rs6000_output_symbol_ref (FILE *file, rtx x)
21958 /* Currently C++ toc references to vtables can be emitted before it
21959 is decided whether the vtable is public or private. If this is
21960 the case, then the linker will eventually complain that there is
21961 a reference to an unknown section. Thus, for vtables only,
21962 we emit the TOC reference to reference the symbol and not the
21964 const char *name = XSTR (x, 0);
21966 if (VTABLE_NAME_P (name))
21968 RS6000_OUTPUT_BASENAME (file, name);
21971 assemble_name (file, name);
21974 /* Output a TOC entry. We derive the entry name from what is being
21978 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
21981 const char *name = buf;
21983 HOST_WIDE_INT offset = 0;
21985 gcc_assert (!TARGET_NO_TOC);
21987 /* When the linker won't eliminate them, don't output duplicate
21988 TOC entries (this happens on AIX if there is any kind of TOC,
21989 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
21991 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
21993 struct toc_hash_struct *h;
21996 /* Create toc_hash_table. This can't be done at TARGET_OPTION_OVERRIDE
21997 time because GGC is not initialized at that point. */
21998 if (toc_hash_table == NULL)
21999 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
22000 toc_hash_eq, NULL);
22002 h = ggc_alloc_toc_hash_struct ();
22004 h->key_mode = mode;
22005 h->labelno = labelno;
22007 found = htab_find_slot (toc_hash_table, h, INSERT);
22008 if (*found == NULL)
22010 else /* This is indeed a duplicate.
22011 Set this label equal to that label. */
22013 fputs ("\t.set ", file);
22014 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22015 fprintf (file, "%d,", labelno);
22016 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22017 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
22023 /* If we're going to put a double constant in the TOC, make sure it's
22024 aligned properly when strict alignment is on. */
22025 if (GET_CODE (x) == CONST_DOUBLE
22026 && STRICT_ALIGNMENT
22027 && GET_MODE_BITSIZE (mode) >= 64
22028 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
22029 ASM_OUTPUT_ALIGN (file, 3);
22032 (*targetm.asm_out.internal_label) (file, "LC", labelno);
22034 /* Handle FP constants specially. Note that if we have a minimal
22035 TOC, things we put here aren't actually in the TOC, so we can allow
22037 if (GET_CODE (x) == CONST_DOUBLE &&
22038 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
22040 REAL_VALUE_TYPE rv;
22043 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22044 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22045 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
22047 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
22051 if (TARGET_MINIMAL_TOC)
22052 fputs (DOUBLE_INT_ASM_OP, file);
22054 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22055 k[0] & 0xffffffff, k[1] & 0xffffffff,
22056 k[2] & 0xffffffff, k[3] & 0xffffffff);
22057 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
22058 k[0] & 0xffffffff, k[1] & 0xffffffff,
22059 k[2] & 0xffffffff, k[3] & 0xffffffff);
22064 if (TARGET_MINIMAL_TOC)
22065 fputs ("\t.long ", file);
22067 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22068 k[0] & 0xffffffff, k[1] & 0xffffffff,
22069 k[2] & 0xffffffff, k[3] & 0xffffffff);
22070 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
22071 k[0] & 0xffffffff, k[1] & 0xffffffff,
22072 k[2] & 0xffffffff, k[3] & 0xffffffff);
22076 else if (GET_CODE (x) == CONST_DOUBLE &&
22077 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
22079 REAL_VALUE_TYPE rv;
22082 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22084 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22085 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
22087 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
22091 if (TARGET_MINIMAL_TOC)
22092 fputs (DOUBLE_INT_ASM_OP, file);
22094 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22095 k[0] & 0xffffffff, k[1] & 0xffffffff);
22096 fprintf (file, "0x%lx%08lx\n",
22097 k[0] & 0xffffffff, k[1] & 0xffffffff);
22102 if (TARGET_MINIMAL_TOC)
22103 fputs ("\t.long ", file);
22105 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22106 k[0] & 0xffffffff, k[1] & 0xffffffff);
22107 fprintf (file, "0x%lx,0x%lx\n",
22108 k[0] & 0xffffffff, k[1] & 0xffffffff);
22112 else if (GET_CODE (x) == CONST_DOUBLE &&
22113 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
22115 REAL_VALUE_TYPE rv;
22118 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22119 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22120 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
22122 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
22126 if (TARGET_MINIMAL_TOC)
22127 fputs (DOUBLE_INT_ASM_OP, file);
22129 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22130 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
22135 if (TARGET_MINIMAL_TOC)
22136 fputs ("\t.long ", file);
22138 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22139 fprintf (file, "0x%lx\n", l & 0xffffffff);
22143 else if (GET_MODE (x) == VOIDmode
22144 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
22146 unsigned HOST_WIDE_INT low;
22147 HOST_WIDE_INT high;
22149 if (GET_CODE (x) == CONST_DOUBLE)
22151 low = CONST_DOUBLE_LOW (x);
22152 high = CONST_DOUBLE_HIGH (x);
22155 #if HOST_BITS_PER_WIDE_INT == 32
22158 high = (low & 0x80000000) ? ~0 : 0;
22162 low = INTVAL (x) & 0xffffffff;
22163 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
22167 /* TOC entries are always Pmode-sized, but since this
22168 is a bigendian machine then if we're putting smaller
22169 integer constants in the TOC we have to pad them.
22170 (This is still a win over putting the constants in
22171 a separate constant pool, because then we'd have
22172 to have both a TOC entry _and_ the actual constant.)
22174 For a 32-bit target, CONST_INT values are loaded and shifted
22175 entirely within `low' and can be stored in one TOC entry. */
22177 /* It would be easy to make this work, but it doesn't now. */
22178 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
22180 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
22182 #if HOST_BITS_PER_WIDE_INT == 32
22183 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
22184 POINTER_SIZE, &low, &high, 0);
22187 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
22188 high = (HOST_WIDE_INT) low >> 32;
22195 if (TARGET_MINIMAL_TOC)
22196 fputs (DOUBLE_INT_ASM_OP, file);
22198 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22199 (long) high & 0xffffffff, (long) low & 0xffffffff);
22200 fprintf (file, "0x%lx%08lx\n",
22201 (long) high & 0xffffffff, (long) low & 0xffffffff);
22206 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
22208 if (TARGET_MINIMAL_TOC)
22209 fputs ("\t.long ", file);
22211 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22212 (long) high & 0xffffffff, (long) low & 0xffffffff);
22213 fprintf (file, "0x%lx,0x%lx\n",
22214 (long) high & 0xffffffff, (long) low & 0xffffffff);
22218 if (TARGET_MINIMAL_TOC)
22219 fputs ("\t.long ", file);
22221 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
22222 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
22228 if (GET_CODE (x) == CONST)
22230 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
22231 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
22233 base = XEXP (XEXP (x, 0), 0);
22234 offset = INTVAL (XEXP (XEXP (x, 0), 1));
22237 switch (GET_CODE (base))
22240 name = XSTR (base, 0);
22244 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
22245 CODE_LABEL_NUMBER (XEXP (base, 0)));
22249 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
22253 gcc_unreachable ();
22256 if (TARGET_MINIMAL_TOC)
22257 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
22260 fputs ("\t.tc ", file);
22261 RS6000_OUTPUT_BASENAME (file, name);
22264 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
22266 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
22268 fputs ("[TC],", file);
22271 /* Currently C++ toc references to vtables can be emitted before it
22272 is decided whether the vtable is public or private. If this is
22273 the case, then the linker will eventually complain that there is
22274 a TOC reference to an unknown section. Thus, for vtables only,
22275 we emit the TOC reference to reference the symbol and not the
22277 if (VTABLE_NAME_P (name))
22279 RS6000_OUTPUT_BASENAME (file, name);
22281 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
22282 else if (offset > 0)
22283 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
22286 output_addr_const (file, x);
22290 /* Output an assembler pseudo-op to write an ASCII string of N characters
22291 starting at P to FILE.
22293 On the RS/6000, we have to do this using the .byte operation and
22294 write out special characters outside the quoted string.
22295 Also, the assembler is broken; very long strings are truncated,
22296 so we must artificially break them up early. */
22299 output_ascii (FILE *file, const char *p, int n)
22302 int i, count_string;
22303 const char *for_string = "\t.byte \"";
22304 const char *for_decimal = "\t.byte ";
22305 const char *to_close = NULL;
22308 for (i = 0; i < n; i++)
22311 if (c >= ' ' && c < 0177)
22314 fputs (for_string, file);
22317 /* Write two quotes to get one. */
22325 for_decimal = "\"\n\t.byte ";
22329 if (count_string >= 512)
22331 fputs (to_close, file);
22333 for_string = "\t.byte \"";
22334 for_decimal = "\t.byte ";
22342 fputs (for_decimal, file);
22343 fprintf (file, "%d", c);
22345 for_string = "\n\t.byte \"";
22346 for_decimal = ", ";
22352 /* Now close the string if we have written one. Then end the line. */
22354 fputs (to_close, file);
22357 /* Generate a unique section name for FILENAME for a section type
22358 represented by SECTION_DESC. Output goes into BUF.
22360 SECTION_DESC can be any string, as long as it is different for each
22361 possible section type.
22363 We name the section in the same manner as xlc. The name begins with an
22364 underscore followed by the filename (after stripping any leading directory
22365 names) with the last period replaced by the string SECTION_DESC. If
22366 FILENAME does not contain a period, SECTION_DESC is appended to the end of
22370 rs6000_gen_section_name (char **buf, const char *filename,
22371 const char *section_desc)
22373 const char *q, *after_last_slash, *last_period = 0;
22377 after_last_slash = filename;
22378 for (q = filename; *q; q++)
22381 after_last_slash = q + 1;
22382 else if (*q == '.')
22386 len = strlen (after_last_slash) + strlen (section_desc) + 2;
22387 *buf = (char *) xmalloc (len);
22392 for (q = after_last_slash; *q; q++)
22394 if (q == last_period)
22396 strcpy (p, section_desc);
22397 p += strlen (section_desc);
22401 else if (ISALNUM (*q))
22405 if (last_period == 0)
22406 strcpy (p, section_desc);
22411 /* Emit profile function. */
22414 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
22416 /* Non-standard profiling for kernels, which just saves LR then calls
22417 _mcount without worrying about arg saves. The idea is to change
22418 the function prologue as little as possible as it isn't easy to
22419 account for arg save/restore code added just for _mcount. */
22420 if (TARGET_PROFILE_KERNEL)
22423 if (DEFAULT_ABI == ABI_AIX)
22425 #ifndef NO_PROFILE_COUNTERS
22426 # define NO_PROFILE_COUNTERS 0
22428 if (NO_PROFILE_COUNTERS)
22429 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22430 LCT_NORMAL, VOIDmode, 0);
22434 const char *label_name;
22437 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
22438 label_name = ggc_strdup ((*targetm.strip_name_encoding) (buf));
22439 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
22441 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22442 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
22445 else if (DEFAULT_ABI == ABI_DARWIN)
22447 const char *mcount_name = RS6000_MCOUNT;
22448 int caller_addr_regno = LR_REGNO;
22450 /* Be conservative and always set this, at least for now. */
22451 crtl->uses_pic_offset_table = 1;
22454 /* For PIC code, set up a stub and collect the caller's address
22455 from r0, which is where the prologue puts it. */
22456 if (MACHOPIC_INDIRECT
22457 && crtl->uses_pic_offset_table)
22458 caller_addr_regno = 0;
22460 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
22461 LCT_NORMAL, VOIDmode, 1,
22462 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
22466 /* Write function profiler code. */
22469 output_function_profiler (FILE *file, int labelno)
22473 switch (DEFAULT_ABI)
22476 gcc_unreachable ();
22481 warning (0, "no profiling of 64-bit code for this ABI");
22484 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
22485 fprintf (file, "\tmflr %s\n", reg_names[0]);
22486 if (NO_PROFILE_COUNTERS)
22488 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22489 reg_names[0], reg_names[1]);
22491 else if (TARGET_SECURE_PLT && flag_pic)
22493 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
22494 reg_names[0], reg_names[1]);
22495 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
22496 asm_fprintf (file, "\t{cau|addis} %s,%s,",
22497 reg_names[12], reg_names[12]);
22498 assemble_name (file, buf);
22499 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
22500 assemble_name (file, buf);
22501 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
22503 else if (flag_pic == 1)
22505 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
22506 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22507 reg_names[0], reg_names[1]);
22508 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
22509 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
22510 assemble_name (file, buf);
22511 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
22513 else if (flag_pic > 1)
22515 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22516 reg_names[0], reg_names[1]);
22517 /* Now, we need to get the address of the label. */
22518 fputs ("\tbcl 20,31,1f\n\t.long ", file);
22519 assemble_name (file, buf);
22520 fputs ("-.\n1:", file);
22521 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
22522 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
22523 reg_names[0], reg_names[11]);
22524 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
22525 reg_names[0], reg_names[0], reg_names[11]);
22529 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
22530 assemble_name (file, buf);
22531 fputs ("@ha\n", file);
22532 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22533 reg_names[0], reg_names[1]);
22534 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
22535 assemble_name (file, buf);
22536 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
22539 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
22540 fprintf (file, "\tbl %s%s\n",
22541 RS6000_MCOUNT, flag_pic ? "@plt" : "");
22546 if (!TARGET_PROFILE_KERNEL)
22548 /* Don't do anything, done in output_profile_hook (). */
22552 gcc_assert (!TARGET_32BIT);
22554 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
22555 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
22557 if (cfun->static_chain_decl != NULL)
22559 asm_fprintf (file, "\tstd %s,24(%s)\n",
22560 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
22561 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
22562 asm_fprintf (file, "\tld %s,24(%s)\n",
22563 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
22566 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
22574 /* The following variable value is the last issued insn. */
22576 static rtx last_scheduled_insn;
22578 /* The following variable helps to balance issuing of load and
22579 store instructions */
22581 static int load_store_pendulum;
22583 /* Power4 load update and store update instructions are cracked into a
22584 load or store and an integer insn which are executed in the same cycle.
22585 Branches have their own dispatch slot which does not count against the
22586 GCC issue rate, but it changes the program flow so there are no other
22587 instructions to issue in this cycle. */
22590 rs6000_variable_issue_1 (rtx insn, int more)
22592 last_scheduled_insn = insn;
22593 if (GET_CODE (PATTERN (insn)) == USE
22594 || GET_CODE (PATTERN (insn)) == CLOBBER)
22596 cached_can_issue_more = more;
22597 return cached_can_issue_more;
22600 if (insn_terminates_group_p (insn, current_group))
22602 cached_can_issue_more = 0;
22603 return cached_can_issue_more;
22606 /* If no reservation, but reach here */
22607 if (recog_memoized (insn) < 0)
22610 if (rs6000_sched_groups)
22612 if (is_microcoded_insn (insn))
22613 cached_can_issue_more = 0;
22614 else if (is_cracked_insn (insn))
22615 cached_can_issue_more = more > 2 ? more - 2 : 0;
22617 cached_can_issue_more = more - 1;
22619 return cached_can_issue_more;
22622 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
22625 cached_can_issue_more = more - 1;
22626 return cached_can_issue_more;
22630 rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more)
22632 int r = rs6000_variable_issue_1 (insn, more);
22634 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r);
22638 /* Adjust the cost of a scheduling dependency. Return the new cost of
22639 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
22642 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
22644 enum attr_type attr_type;
22646 if (! recog_memoized (insn))
22649 switch (REG_NOTE_KIND (link))
22653 /* Data dependency; DEP_INSN writes a register that INSN reads
22654 some cycles later. */
22656 /* Separate a load from a narrower, dependent store. */
22657 if (rs6000_sched_groups
22658 && GET_CODE (PATTERN (insn)) == SET
22659 && GET_CODE (PATTERN (dep_insn)) == SET
22660 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
22661 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
22662 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
22663 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
22666 attr_type = get_attr_type (insn);
22671 /* Tell the first scheduling pass about the latency between
22672 a mtctr and bctr (and mtlr and br/blr). The first
22673 scheduling pass will not know about this latency since
22674 the mtctr instruction, which has the latency associated
22675 to it, will be generated by reload. */
22676 return TARGET_POWER ? 5 : 4;
22678 /* Leave some extra cycles between a compare and its
22679 dependent branch, to inhibit expensive mispredicts. */
22680 if ((rs6000_cpu_attr == CPU_PPC603
22681 || rs6000_cpu_attr == CPU_PPC604
22682 || rs6000_cpu_attr == CPU_PPC604E
22683 || rs6000_cpu_attr == CPU_PPC620
22684 || rs6000_cpu_attr == CPU_PPC630
22685 || rs6000_cpu_attr == CPU_PPC750
22686 || rs6000_cpu_attr == CPU_PPC7400
22687 || rs6000_cpu_attr == CPU_PPC7450
22688 || rs6000_cpu_attr == CPU_POWER4
22689 || rs6000_cpu_attr == CPU_POWER5
22690 || rs6000_cpu_attr == CPU_POWER7
22691 || rs6000_cpu_attr == CPU_CELL)
22692 && recog_memoized (dep_insn)
22693 && (INSN_CODE (dep_insn) >= 0))
22695 switch (get_attr_type (dep_insn))
22699 case TYPE_DELAYED_COMPARE:
22700 case TYPE_IMUL_COMPARE:
22701 case TYPE_LMUL_COMPARE:
22702 case TYPE_FPCOMPARE:
22703 case TYPE_CR_LOGICAL:
22704 case TYPE_DELAYED_CR:
22713 case TYPE_STORE_UX:
22715 case TYPE_FPSTORE_U:
22716 case TYPE_FPSTORE_UX:
22717 if ((rs6000_cpu == PROCESSOR_POWER6)
22718 && recog_memoized (dep_insn)
22719 && (INSN_CODE (dep_insn) >= 0))
22722 if (GET_CODE (PATTERN (insn)) != SET)
22723 /* If this happens, we have to extend this to schedule
22724 optimally. Return default for now. */
22727 /* Adjust the cost for the case where the value written
22728 by a fixed point operation is used as the address
22729 gen value on a store. */
22730 switch (get_attr_type (dep_insn))
22737 if (! store_data_bypass_p (dep_insn, insn))
22741 case TYPE_LOAD_EXT:
22742 case TYPE_LOAD_EXT_U:
22743 case TYPE_LOAD_EXT_UX:
22744 case TYPE_VAR_SHIFT_ROTATE:
22745 case TYPE_VAR_DELAYED_COMPARE:
22747 if (! store_data_bypass_p (dep_insn, insn))
22753 case TYPE_FAST_COMPARE:
22756 case TYPE_INSERT_WORD:
22757 case TYPE_INSERT_DWORD:
22758 case TYPE_FPLOAD_U:
22759 case TYPE_FPLOAD_UX:
22761 case TYPE_STORE_UX:
22762 case TYPE_FPSTORE_U:
22763 case TYPE_FPSTORE_UX:
22765 if (! store_data_bypass_p (dep_insn, insn))
22773 case TYPE_IMUL_COMPARE:
22774 case TYPE_LMUL_COMPARE:
22776 if (! store_data_bypass_p (dep_insn, insn))
22782 if (! store_data_bypass_p (dep_insn, insn))
22788 if (! store_data_bypass_p (dep_insn, insn))
22801 case TYPE_LOAD_EXT:
22802 case TYPE_LOAD_EXT_U:
22803 case TYPE_LOAD_EXT_UX:
22804 if ((rs6000_cpu == PROCESSOR_POWER6)
22805 && recog_memoized (dep_insn)
22806 && (INSN_CODE (dep_insn) >= 0))
22809 /* Adjust the cost for the case where the value written
22810 by a fixed point instruction is used within the address
22811 gen portion of a subsequent load(u)(x) */
22812 switch (get_attr_type (dep_insn))
22819 if (set_to_load_agen (dep_insn, insn))
22823 case TYPE_LOAD_EXT:
22824 case TYPE_LOAD_EXT_U:
22825 case TYPE_LOAD_EXT_UX:
22826 case TYPE_VAR_SHIFT_ROTATE:
22827 case TYPE_VAR_DELAYED_COMPARE:
22829 if (set_to_load_agen (dep_insn, insn))
22835 case TYPE_FAST_COMPARE:
22838 case TYPE_INSERT_WORD:
22839 case TYPE_INSERT_DWORD:
22840 case TYPE_FPLOAD_U:
22841 case TYPE_FPLOAD_UX:
22843 case TYPE_STORE_UX:
22844 case TYPE_FPSTORE_U:
22845 case TYPE_FPSTORE_UX:
22847 if (set_to_load_agen (dep_insn, insn))
22855 case TYPE_IMUL_COMPARE:
22856 case TYPE_LMUL_COMPARE:
22858 if (set_to_load_agen (dep_insn, insn))
22864 if (set_to_load_agen (dep_insn, insn))
22870 if (set_to_load_agen (dep_insn, insn))
22881 if ((rs6000_cpu == PROCESSOR_POWER6)
22882 && recog_memoized (dep_insn)
22883 && (INSN_CODE (dep_insn) >= 0)
22884 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
22891 /* Fall out to return default cost. */
22895 case REG_DEP_OUTPUT:
22896 /* Output dependency; DEP_INSN writes a register that INSN writes some
22898 if ((rs6000_cpu == PROCESSOR_POWER6)
22899 && recog_memoized (dep_insn)
22900 && (INSN_CODE (dep_insn) >= 0))
22902 attr_type = get_attr_type (insn);
22907 if (get_attr_type (dep_insn) == TYPE_FP)
22911 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
22919 /* Anti dependency; DEP_INSN reads a register that INSN writes some
22924 gcc_unreachable ();
22930 /* Debug version of rs6000_adjust_cost. */
22933 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
22935 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
22941 switch (REG_NOTE_KIND (link))
22943 default: dep = "unknown depencency"; break;
22944 case REG_DEP_TRUE: dep = "data dependency"; break;
22945 case REG_DEP_OUTPUT: dep = "output dependency"; break;
22946 case REG_DEP_ANTI: dep = "anti depencency"; break;
22950 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
22951 "%s, insn:\n", ret, cost, dep);
22959 /* The function returns a true if INSN is microcoded.
22960 Return false otherwise. */
22963 is_microcoded_insn (rtx insn)
22965 if (!insn || !NONDEBUG_INSN_P (insn)
22966 || GET_CODE (PATTERN (insn)) == USE
22967 || GET_CODE (PATTERN (insn)) == CLOBBER)
22970 if (rs6000_cpu_attr == CPU_CELL)
22971 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
22973 if (rs6000_sched_groups)
22975 enum attr_type type = get_attr_type (insn);
22976 if (type == TYPE_LOAD_EXT_U
22977 || type == TYPE_LOAD_EXT_UX
22978 || type == TYPE_LOAD_UX
22979 || type == TYPE_STORE_UX
22980 || type == TYPE_MFCR)
22987 /* The function returns true if INSN is cracked into 2 instructions
22988 by the processor (and therefore occupies 2 issue slots). */
22991 is_cracked_insn (rtx insn)
22993 if (!insn || !NONDEBUG_INSN_P (insn)
22994 || GET_CODE (PATTERN (insn)) == USE
22995 || GET_CODE (PATTERN (insn)) == CLOBBER)
22998 if (rs6000_sched_groups)
23000 enum attr_type type = get_attr_type (insn);
23001 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
23002 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
23003 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
23004 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
23005 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
23006 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
23007 || type == TYPE_IDIV || type == TYPE_LDIV
23008 || type == TYPE_INSERT_WORD)
23015 /* The function returns true if INSN can be issued only from
23016 the branch slot. */
23019 is_branch_slot_insn (rtx insn)
23021 if (!insn || !NONDEBUG_INSN_P (insn)
23022 || GET_CODE (PATTERN (insn)) == USE
23023 || GET_CODE (PATTERN (insn)) == CLOBBER)
23026 if (rs6000_sched_groups)
23028 enum attr_type type = get_attr_type (insn);
23029 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
23037 /* The function returns true if out_inst sets a value that is
23038 used in the address generation computation of in_insn */
23040 set_to_load_agen (rtx out_insn, rtx in_insn)
23042 rtx out_set, in_set;
23044 /* For performance reasons, only handle the simple case where
23045 both loads are a single_set. */
23046 out_set = single_set (out_insn);
23049 in_set = single_set (in_insn);
23051 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
23057 /* The function returns true if the target storage location of
23058 out_insn is adjacent to the target storage location of in_insn */
23059 /* Return 1 if memory locations are adjacent. */
23062 adjacent_mem_locations (rtx insn1, rtx insn2)
23065 rtx a = get_store_dest (PATTERN (insn1));
23066 rtx b = get_store_dest (PATTERN (insn2));
23068 if ((GET_CODE (XEXP (a, 0)) == REG
23069 || (GET_CODE (XEXP (a, 0)) == PLUS
23070 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
23071 && (GET_CODE (XEXP (b, 0)) == REG
23072 || (GET_CODE (XEXP (b, 0)) == PLUS
23073 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
23075 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
23078 if (GET_CODE (XEXP (a, 0)) == PLUS)
23080 reg0 = XEXP (XEXP (a, 0), 0);
23081 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
23084 reg0 = XEXP (a, 0);
23086 if (GET_CODE (XEXP (b, 0)) == PLUS)
23088 reg1 = XEXP (XEXP (b, 0), 0);
23089 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
23092 reg1 = XEXP (b, 0);
23094 val_diff = val1 - val0;
23096 return ((REGNO (reg0) == REGNO (reg1))
23097 && ((MEM_SIZE_KNOWN_P (a) && val_diff == MEM_SIZE (a))
23098 || (MEM_SIZE_KNOWN_P (b) && val_diff == -MEM_SIZE (b))));
23104 /* A C statement (sans semicolon) to update the integer scheduling
23105 priority INSN_PRIORITY (INSN). Increase the priority to execute the
23106 INSN earlier, reduce the priority to execute INSN later. Do not
23107 define this macro if you do not need to adjust the scheduling
23108 priorities of insns. */
23111 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
23113 /* On machines (like the 750) which have asymmetric integer units,
23114 where one integer unit can do multiply and divides and the other
23115 can't, reduce the priority of multiply/divide so it is scheduled
23116 before other integer operations. */
23119 if (! INSN_P (insn))
23122 if (GET_CODE (PATTERN (insn)) == USE)
23125 switch (rs6000_cpu_attr) {
23127 switch (get_attr_type (insn))
23134 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
23135 priority, priority);
23136 if (priority >= 0 && priority < 0x01000000)
23143 if (insn_must_be_first_in_group (insn)
23144 && reload_completed
23145 && current_sched_info->sched_max_insns_priority
23146 && rs6000_sched_restricted_insns_priority)
23149 /* Prioritize insns that can be dispatched only in the first
23151 if (rs6000_sched_restricted_insns_priority == 1)
23152 /* Attach highest priority to insn. This means that in
23153 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
23154 precede 'priority' (critical path) considerations. */
23155 return current_sched_info->sched_max_insns_priority;
23156 else if (rs6000_sched_restricted_insns_priority == 2)
23157 /* Increase priority of insn by a minimal amount. This means that in
23158 haifa-sched.c:ready_sort(), only 'priority' (critical path)
23159 considerations precede dispatch-slot restriction considerations. */
23160 return (priority + 1);
23163 if (rs6000_cpu == PROCESSOR_POWER6
23164 && ((load_store_pendulum == -2 && is_load_insn (insn))
23165 || (load_store_pendulum == 2 && is_store_insn (insn))))
23166 /* Attach highest priority to insn if the scheduler has just issued two
23167 stores and this instruction is a load, or two loads and this instruction
23168 is a store. Power6 wants loads and stores scheduled alternately
23170 return current_sched_info->sched_max_insns_priority;
23175 /* Return true if the instruction is nonpipelined on the Cell. */
23177 is_nonpipeline_insn (rtx insn)
23179 enum attr_type type;
23180 if (!insn || !NONDEBUG_INSN_P (insn)
23181 || GET_CODE (PATTERN (insn)) == USE
23182 || GET_CODE (PATTERN (insn)) == CLOBBER)
23185 type = get_attr_type (insn);
23186 if (type == TYPE_IMUL
23187 || type == TYPE_IMUL2
23188 || type == TYPE_IMUL3
23189 || type == TYPE_LMUL
23190 || type == TYPE_IDIV
23191 || type == TYPE_LDIV
23192 || type == TYPE_SDIV
23193 || type == TYPE_DDIV
23194 || type == TYPE_SSQRT
23195 || type == TYPE_DSQRT
23196 || type == TYPE_MFCR
23197 || type == TYPE_MFCRF
23198 || type == TYPE_MFJMPR)
23206 /* Return how many instructions the machine can issue per cycle. */
23209 rs6000_issue_rate (void)
23211 /* Unless scheduling for register pressure, use issue rate of 1 for
23212 first scheduling pass to decrease degradation. */
23213 if (!reload_completed && !flag_sched_pressure)
23216 switch (rs6000_cpu_attr) {
23217 case CPU_RIOS1: /* ? */
23219 case CPU_PPC601: /* ? */
23228 case CPU_PPCE300C2:
23229 case CPU_PPCE300C3:
23230 case CPU_PPCE500MC:
23231 case CPU_PPCE500MC64:
23251 /* Return how many instructions to look ahead for better insn
23255 rs6000_use_sched_lookahead (void)
23257 if (rs6000_cpu_attr == CPU_PPC8540)
23259 if (rs6000_cpu_attr == CPU_CELL)
23260 return (reload_completed ? 8 : 0);
23264 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
23266 rs6000_use_sched_lookahead_guard (rtx insn)
23268 if (rs6000_cpu_attr != CPU_CELL)
23271 if (insn == NULL_RTX || !INSN_P (insn))
23274 if (!reload_completed
23275 || is_nonpipeline_insn (insn)
23276 || is_microcoded_insn (insn))
23282 /* Determine is PAT refers to memory. */
23285 is_mem_ref (rtx pat)
23291 /* stack_tie does not produce any real memory traffic. */
23292 if (GET_CODE (pat) == UNSPEC
23293 && XINT (pat, 1) == UNSPEC_TIE)
23296 if (GET_CODE (pat) == MEM)
23299 /* Recursively process the pattern. */
23300 fmt = GET_RTX_FORMAT (GET_CODE (pat));
23302 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
23305 ret |= is_mem_ref (XEXP (pat, i));
23306 else if (fmt[i] == 'E')
23307 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
23308 ret |= is_mem_ref (XVECEXP (pat, i, j));
23314 /* Determine if PAT is a PATTERN of a load insn. */
23317 is_load_insn1 (rtx pat)
23319 if (!pat || pat == NULL_RTX)
23322 if (GET_CODE (pat) == SET)
23323 return is_mem_ref (SET_SRC (pat));
23325 if (GET_CODE (pat) == PARALLEL)
23329 for (i = 0; i < XVECLEN (pat, 0); i++)
23330 if (is_load_insn1 (XVECEXP (pat, 0, i)))
23337 /* Determine if INSN loads from memory. */
23340 is_load_insn (rtx insn)
23342 if (!insn || !INSN_P (insn))
23345 if (GET_CODE (insn) == CALL_INSN)
23348 return is_load_insn1 (PATTERN (insn));
23351 /* Determine if PAT is a PATTERN of a store insn. */
23354 is_store_insn1 (rtx pat)
23356 if (!pat || pat == NULL_RTX)
23359 if (GET_CODE (pat) == SET)
23360 return is_mem_ref (SET_DEST (pat));
23362 if (GET_CODE (pat) == PARALLEL)
23366 for (i = 0; i < XVECLEN (pat, 0); i++)
23367 if (is_store_insn1 (XVECEXP (pat, 0, i)))
23374 /* Determine if INSN stores to memory. */
23377 is_store_insn (rtx insn)
23379 if (!insn || !INSN_P (insn))
23382 return is_store_insn1 (PATTERN (insn));
23385 /* Return the dest of a store insn. */
23388 get_store_dest (rtx pat)
23390 gcc_assert (is_store_insn1 (pat));
23392 if (GET_CODE (pat) == SET)
23393 return SET_DEST (pat);
23394 else if (GET_CODE (pat) == PARALLEL)
23398 for (i = 0; i < XVECLEN (pat, 0); i++)
23400 rtx inner_pat = XVECEXP (pat, 0, i);
23401 if (GET_CODE (inner_pat) == SET
23402 && is_mem_ref (SET_DEST (inner_pat)))
23406 /* We shouldn't get here, because we should have either a simple
23407 store insn or a store with update which are covered above. */
23411 /* Returns whether the dependence between INSN and NEXT is considered
23412 costly by the given target. */
23415 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
23420 /* If the flag is not enabled - no dependence is considered costly;
23421 allow all dependent insns in the same group.
23422 This is the most aggressive option. */
23423 if (rs6000_sched_costly_dep == no_dep_costly)
23426 /* If the flag is set to 1 - a dependence is always considered costly;
23427 do not allow dependent instructions in the same group.
23428 This is the most conservative option. */
23429 if (rs6000_sched_costly_dep == all_deps_costly)
23432 insn = DEP_PRO (dep);
23433 next = DEP_CON (dep);
23435 if (rs6000_sched_costly_dep == store_to_load_dep_costly
23436 && is_load_insn (next)
23437 && is_store_insn (insn))
23438 /* Prevent load after store in the same group. */
23441 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
23442 && is_load_insn (next)
23443 && is_store_insn (insn)
23444 && DEP_TYPE (dep) == REG_DEP_TRUE)
23445 /* Prevent load after store in the same group if it is a true
23449 /* The flag is set to X; dependences with latency >= X are considered costly,
23450 and will not be scheduled in the same group. */
23451 if (rs6000_sched_costly_dep <= max_dep_latency
23452 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
23458 /* Return the next insn after INSN that is found before TAIL is reached,
23459 skipping any "non-active" insns - insns that will not actually occupy
23460 an issue slot. Return NULL_RTX if such an insn is not found. */
23463 get_next_active_insn (rtx insn, rtx tail)
23465 if (insn == NULL_RTX || insn == tail)
23470 insn = NEXT_INSN (insn);
23471 if (insn == NULL_RTX || insn == tail)
23476 || (NONJUMP_INSN_P (insn)
23477 && GET_CODE (PATTERN (insn)) != USE
23478 && GET_CODE (PATTERN (insn)) != CLOBBER
23479 && INSN_CODE (insn) != CODE_FOR_stack_tie))
23485 /* We are about to begin issuing insns for this clock cycle. */
23488 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
23489 rtx *ready ATTRIBUTE_UNUSED,
23490 int *pn_ready ATTRIBUTE_UNUSED,
23491 int clock_var ATTRIBUTE_UNUSED)
23493 int n_ready = *pn_ready;
23496 fprintf (dump, "// rs6000_sched_reorder :\n");
23498 /* Reorder the ready list, if the second to last ready insn
23499 is a nonepipeline insn. */
23500 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
23502 if (is_nonpipeline_insn (ready[n_ready - 1])
23503 && (recog_memoized (ready[n_ready - 2]) > 0))
23504 /* Simply swap first two insns. */
23506 rtx tmp = ready[n_ready - 1];
23507 ready[n_ready - 1] = ready[n_ready - 2];
23508 ready[n_ready - 2] = tmp;
23512 if (rs6000_cpu == PROCESSOR_POWER6)
23513 load_store_pendulum = 0;
23515 return rs6000_issue_rate ();
23518 /* Like rs6000_sched_reorder, but called after issuing each insn. */
23521 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
23522 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
23525 fprintf (dump, "// rs6000_sched_reorder2 :\n");
23527 /* For Power6, we need to handle some special cases to try and keep the
23528 store queue from overflowing and triggering expensive flushes.
23530 This code monitors how load and store instructions are being issued
23531 and skews the ready list one way or the other to increase the likelihood
23532 that a desired instruction is issued at the proper time.
23534 A couple of things are done. First, we maintain a "load_store_pendulum"
23535 to track the current state of load/store issue.
23537 - If the pendulum is at zero, then no loads or stores have been
23538 issued in the current cycle so we do nothing.
23540 - If the pendulum is 1, then a single load has been issued in this
23541 cycle and we attempt to locate another load in the ready list to
23544 - If the pendulum is -2, then two stores have already been
23545 issued in this cycle, so we increase the priority of the first load
23546 in the ready list to increase it's likelihood of being chosen first
23549 - If the pendulum is -1, then a single store has been issued in this
23550 cycle and we attempt to locate another store in the ready list to
23551 issue with it, preferring a store to an adjacent memory location to
23552 facilitate store pairing in the store queue.
23554 - If the pendulum is 2, then two loads have already been
23555 issued in this cycle, so we increase the priority of the first store
23556 in the ready list to increase it's likelihood of being chosen first
23559 - If the pendulum < -2 or > 2, then do nothing.
23561 Note: This code covers the most common scenarios. There exist non
23562 load/store instructions which make use of the LSU and which
23563 would need to be accounted for to strictly model the behavior
23564 of the machine. Those instructions are currently unaccounted
23565 for to help minimize compile time overhead of this code.
23567 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
23573 if (is_store_insn (last_scheduled_insn))
23574 /* Issuing a store, swing the load_store_pendulum to the left */
23575 load_store_pendulum--;
23576 else if (is_load_insn (last_scheduled_insn))
23577 /* Issuing a load, swing the load_store_pendulum to the right */
23578 load_store_pendulum++;
23580 return cached_can_issue_more;
23582 /* If the pendulum is balanced, or there is only one instruction on
23583 the ready list, then all is well, so return. */
23584 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
23585 return cached_can_issue_more;
23587 if (load_store_pendulum == 1)
23589 /* A load has been issued in this cycle. Scan the ready list
23590 for another load to issue with it */
23595 if (is_load_insn (ready[pos]))
23597 /* Found a load. Move it to the head of the ready list,
23598 and adjust it's priority so that it is more likely to
23601 for (i=pos; i<*pn_ready-1; i++)
23602 ready[i] = ready[i + 1];
23603 ready[*pn_ready-1] = tmp;
23605 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23606 INSN_PRIORITY (tmp)++;
23612 else if (load_store_pendulum == -2)
23614 /* Two stores have been issued in this cycle. Increase the
23615 priority of the first load in the ready list to favor it for
23616 issuing in the next cycle. */
23621 if (is_load_insn (ready[pos])
23623 && INSN_PRIORITY_KNOWN (ready[pos]))
23625 INSN_PRIORITY (ready[pos])++;
23627 /* Adjust the pendulum to account for the fact that a load
23628 was found and increased in priority. This is to prevent
23629 increasing the priority of multiple loads */
23630 load_store_pendulum--;
23637 else if (load_store_pendulum == -1)
23639 /* A store has been issued in this cycle. Scan the ready list for
23640 another store to issue with it, preferring a store to an adjacent
23642 int first_store_pos = -1;
23648 if (is_store_insn (ready[pos]))
23650 /* Maintain the index of the first store found on the
23652 if (first_store_pos == -1)
23653 first_store_pos = pos;
23655 if (is_store_insn (last_scheduled_insn)
23656 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
23658 /* Found an adjacent store. Move it to the head of the
23659 ready list, and adjust it's priority so that it is
23660 more likely to stay there */
23662 for (i=pos; i<*pn_ready-1; i++)
23663 ready[i] = ready[i + 1];
23664 ready[*pn_ready-1] = tmp;
23666 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23667 INSN_PRIORITY (tmp)++;
23669 first_store_pos = -1;
23677 if (first_store_pos >= 0)
23679 /* An adjacent store wasn't found, but a non-adjacent store was,
23680 so move the non-adjacent store to the front of the ready
23681 list, and adjust its priority so that it is more likely to
23683 tmp = ready[first_store_pos];
23684 for (i=first_store_pos; i<*pn_ready-1; i++)
23685 ready[i] = ready[i + 1];
23686 ready[*pn_ready-1] = tmp;
23687 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23688 INSN_PRIORITY (tmp)++;
23691 else if (load_store_pendulum == 2)
23693 /* Two loads have been issued in this cycle. Increase the priority
23694 of the first store in the ready list to favor it for issuing in
23700 if (is_store_insn (ready[pos])
23702 && INSN_PRIORITY_KNOWN (ready[pos]))
23704 INSN_PRIORITY (ready[pos])++;
23706 /* Adjust the pendulum to account for the fact that a store
23707 was found and increased in priority. This is to prevent
23708 increasing the priority of multiple stores */
23709 load_store_pendulum++;
23718 return cached_can_issue_more;
23721 /* Return whether the presence of INSN causes a dispatch group termination
23722 of group WHICH_GROUP.
23724 If WHICH_GROUP == current_group, this function will return true if INSN
23725 causes the termination of the current group (i.e, the dispatch group to
23726 which INSN belongs). This means that INSN will be the last insn in the
23727 group it belongs to.
23729 If WHICH_GROUP == previous_group, this function will return true if INSN
23730 causes the termination of the previous group (i.e, the dispatch group that
23731 precedes the group to which INSN belongs). This means that INSN will be
23732 the first insn in the group it belongs to). */
23735 insn_terminates_group_p (rtx insn, enum group_termination which_group)
23742 first = insn_must_be_first_in_group (insn);
23743 last = insn_must_be_last_in_group (insn);
23748 if (which_group == current_group)
23750 else if (which_group == previous_group)
23758 insn_must_be_first_in_group (rtx insn)
23760 enum attr_type type;
23763 || GET_CODE (insn) == NOTE
23764 || DEBUG_INSN_P (insn)
23765 || GET_CODE (PATTERN (insn)) == USE
23766 || GET_CODE (PATTERN (insn)) == CLOBBER)
23769 switch (rs6000_cpu)
23771 case PROCESSOR_POWER5:
23772 if (is_cracked_insn (insn))
23774 case PROCESSOR_POWER4:
23775 if (is_microcoded_insn (insn))
23778 if (!rs6000_sched_groups)
23781 type = get_attr_type (insn);
23788 case TYPE_DELAYED_CR:
23789 case TYPE_CR_LOGICAL:
23803 case PROCESSOR_POWER6:
23804 type = get_attr_type (insn);
23808 case TYPE_INSERT_DWORD:
23812 case TYPE_VAR_SHIFT_ROTATE:
23819 case TYPE_INSERT_WORD:
23820 case TYPE_DELAYED_COMPARE:
23821 case TYPE_IMUL_COMPARE:
23822 case TYPE_LMUL_COMPARE:
23823 case TYPE_FPCOMPARE:
23834 case TYPE_LOAD_EXT_UX:
23836 case TYPE_STORE_UX:
23837 case TYPE_FPLOAD_U:
23838 case TYPE_FPLOAD_UX:
23839 case TYPE_FPSTORE_U:
23840 case TYPE_FPSTORE_UX:
23846 case PROCESSOR_POWER7:
23847 type = get_attr_type (insn);
23851 case TYPE_CR_LOGICAL:
23858 case TYPE_DELAYED_COMPARE:
23859 case TYPE_VAR_DELAYED_COMPARE:
23865 case TYPE_LOAD_EXT:
23866 case TYPE_LOAD_EXT_U:
23867 case TYPE_LOAD_EXT_UX:
23869 case TYPE_STORE_UX:
23870 case TYPE_FPLOAD_U:
23871 case TYPE_FPLOAD_UX:
23872 case TYPE_FPSTORE_U:
23873 case TYPE_FPSTORE_UX:
23889 insn_must_be_last_in_group (rtx insn)
23891 enum attr_type type;
23894 || GET_CODE (insn) == NOTE
23895 || DEBUG_INSN_P (insn)
23896 || GET_CODE (PATTERN (insn)) == USE
23897 || GET_CODE (PATTERN (insn)) == CLOBBER)
23900 switch (rs6000_cpu) {
23901 case PROCESSOR_POWER4:
23902 case PROCESSOR_POWER5:
23903 if (is_microcoded_insn (insn))
23906 if (is_branch_slot_insn (insn))
23910 case PROCESSOR_POWER6:
23911 type = get_attr_type (insn);
23918 case TYPE_VAR_SHIFT_ROTATE:
23925 case TYPE_DELAYED_COMPARE:
23926 case TYPE_IMUL_COMPARE:
23927 case TYPE_LMUL_COMPARE:
23928 case TYPE_FPCOMPARE:
23942 case PROCESSOR_POWER7:
23943 type = get_attr_type (insn);
23951 case TYPE_LOAD_EXT_U:
23952 case TYPE_LOAD_EXT_UX:
23953 case TYPE_STORE_UX:
23966 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
23967 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
23970 is_costly_group (rtx *group_insns, rtx next_insn)
23973 int issue_rate = rs6000_issue_rate ();
23975 for (i = 0; i < issue_rate; i++)
23977 sd_iterator_def sd_it;
23979 rtx insn = group_insns[i];
23984 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
23986 rtx next = DEP_CON (dep);
23988 if (next == next_insn
23989 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
23997 /* Utility of the function redefine_groups.
23998 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
23999 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
24000 to keep it "far" (in a separate group) from GROUP_INSNS, following
24001 one of the following schemes, depending on the value of the flag
24002 -minsert_sched_nops = X:
24003 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
24004 in order to force NEXT_INSN into a separate group.
24005 (2) X < sched_finish_regroup_exact: insert exactly X nops.
24006 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
24007 insertion (has a group just ended, how many vacant issue slots remain in the
24008 last group, and how many dispatch groups were encountered so far). */
24011 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
24012 rtx next_insn, bool *group_end, int can_issue_more,
24017 int issue_rate = rs6000_issue_rate ();
24018 bool end = *group_end;
24021 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
24022 return can_issue_more;
24024 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
24025 return can_issue_more;
24027 force = is_costly_group (group_insns, next_insn);
24029 return can_issue_more;
24031 if (sched_verbose > 6)
24032 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
24033 *group_count ,can_issue_more);
24035 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
24038 can_issue_more = 0;
24040 /* Since only a branch can be issued in the last issue_slot, it is
24041 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
24042 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
24043 in this case the last nop will start a new group and the branch
24044 will be forced to the new group. */
24045 if (can_issue_more && !is_branch_slot_insn (next_insn))
24048 while (can_issue_more > 0)
24051 emit_insn_before (nop, next_insn);
24059 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
24061 int n_nops = rs6000_sched_insert_nops;
24063 /* Nops can't be issued from the branch slot, so the effective
24064 issue_rate for nops is 'issue_rate - 1'. */
24065 if (can_issue_more == 0)
24066 can_issue_more = issue_rate;
24068 if (can_issue_more == 0)
24070 can_issue_more = issue_rate - 1;
24073 for (i = 0; i < issue_rate; i++)
24075 group_insns[i] = 0;
24082 emit_insn_before (nop, next_insn);
24083 if (can_issue_more == issue_rate - 1) /* new group begins */
24086 if (can_issue_more == 0)
24088 can_issue_more = issue_rate - 1;
24091 for (i = 0; i < issue_rate; i++)
24093 group_insns[i] = 0;
24099 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
24102 /* Is next_insn going to start a new group? */
24105 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24106 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24107 || (can_issue_more < issue_rate &&
24108 insn_terminates_group_p (next_insn, previous_group)));
24109 if (*group_end && end)
24112 if (sched_verbose > 6)
24113 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
24114 *group_count, can_issue_more);
24115 return can_issue_more;
24118 return can_issue_more;
24121 /* This function tries to synch the dispatch groups that the compiler "sees"
24122 with the dispatch groups that the processor dispatcher is expected to
24123 form in practice. It tries to achieve this synchronization by forcing the
24124 estimated processor grouping on the compiler (as opposed to the function
24125 'pad_goups' which tries to force the scheduler's grouping on the processor).
24127 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
24128 examines the (estimated) dispatch groups that will be formed by the processor
24129 dispatcher. It marks these group boundaries to reflect the estimated
24130 processor grouping, overriding the grouping that the scheduler had marked.
24131 Depending on the value of the flag '-minsert-sched-nops' this function can
24132 force certain insns into separate groups or force a certain distance between
24133 them by inserting nops, for example, if there exists a "costly dependence"
24136 The function estimates the group boundaries that the processor will form as
24137 follows: It keeps track of how many vacant issue slots are available after
24138 each insn. A subsequent insn will start a new group if one of the following
24140 - no more vacant issue slots remain in the current dispatch group.
24141 - only the last issue slot, which is the branch slot, is vacant, but the next
24142 insn is not a branch.
24143 - only the last 2 or less issue slots, including the branch slot, are vacant,
24144 which means that a cracked insn (which occupies two issue slots) can't be
24145 issued in this group.
24146 - less than 'issue_rate' slots are vacant, and the next insn always needs to
24147 start a new group. */
24150 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24152 rtx insn, next_insn;
24154 int can_issue_more;
24157 int group_count = 0;
24161 issue_rate = rs6000_issue_rate ();
24162 group_insns = XALLOCAVEC (rtx, issue_rate);
24163 for (i = 0; i < issue_rate; i++)
24165 group_insns[i] = 0;
24167 can_issue_more = issue_rate;
24169 insn = get_next_active_insn (prev_head_insn, tail);
24172 while (insn != NULL_RTX)
24174 slot = (issue_rate - can_issue_more);
24175 group_insns[slot] = insn;
24177 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24178 if (insn_terminates_group_p (insn, current_group))
24179 can_issue_more = 0;
24181 next_insn = get_next_active_insn (insn, tail);
24182 if (next_insn == NULL_RTX)
24183 return group_count + 1;
24185 /* Is next_insn going to start a new group? */
24187 = (can_issue_more == 0
24188 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24189 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24190 || (can_issue_more < issue_rate &&
24191 insn_terminates_group_p (next_insn, previous_group)));
24193 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
24194 next_insn, &group_end, can_issue_more,
24200 can_issue_more = 0;
24201 for (i = 0; i < issue_rate; i++)
24203 group_insns[i] = 0;
24207 if (GET_MODE (next_insn) == TImode && can_issue_more)
24208 PUT_MODE (next_insn, VOIDmode);
24209 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
24210 PUT_MODE (next_insn, TImode);
24213 if (can_issue_more == 0)
24214 can_issue_more = issue_rate;
24217 return group_count;
24220 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
24221 dispatch group boundaries that the scheduler had marked. Pad with nops
24222 any dispatch groups which have vacant issue slots, in order to force the
24223 scheduler's grouping on the processor dispatcher. The function
24224 returns the number of dispatch groups found. */
24227 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24229 rtx insn, next_insn;
24232 int can_issue_more;
24234 int group_count = 0;
24236 /* Initialize issue_rate. */
24237 issue_rate = rs6000_issue_rate ();
24238 can_issue_more = issue_rate;
24240 insn = get_next_active_insn (prev_head_insn, tail);
24241 next_insn = get_next_active_insn (insn, tail);
24243 while (insn != NULL_RTX)
24246 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24248 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
24250 if (next_insn == NULL_RTX)
24255 /* If the scheduler had marked group termination at this location
24256 (between insn and next_insn), and neither insn nor next_insn will
24257 force group termination, pad the group with nops to force group
24260 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
24261 && !insn_terminates_group_p (insn, current_group)
24262 && !insn_terminates_group_p (next_insn, previous_group))
24264 if (!is_branch_slot_insn (next_insn))
24267 while (can_issue_more)
24270 emit_insn_before (nop, next_insn);
24275 can_issue_more = issue_rate;
24280 next_insn = get_next_active_insn (insn, tail);
24283 return group_count;
24286 /* We're beginning a new block. Initialize data structures as necessary. */
24289 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
24290 int sched_verbose ATTRIBUTE_UNUSED,
24291 int max_ready ATTRIBUTE_UNUSED)
24293 last_scheduled_insn = NULL_RTX;
24294 load_store_pendulum = 0;
24297 /* The following function is called at the end of scheduling BB.
24298 After reload, it inserts nops at insn group bundling. */
24301 rs6000_sched_finish (FILE *dump, int sched_verbose)
24306 fprintf (dump, "=== Finishing schedule.\n");
24308 if (reload_completed && rs6000_sched_groups)
24310 /* Do not run sched_finish hook when selective scheduling enabled. */
24311 if (sel_sched_p ())
24314 if (rs6000_sched_insert_nops == sched_finish_none)
24317 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
24318 n_groups = pad_groups (dump, sched_verbose,
24319 current_sched_info->prev_head,
24320 current_sched_info->next_tail);
24322 n_groups = redefine_groups (dump, sched_verbose,
24323 current_sched_info->prev_head,
24324 current_sched_info->next_tail);
24326 if (sched_verbose >= 6)
24328 fprintf (dump, "ngroups = %d\n", n_groups);
24329 print_rtl (dump, current_sched_info->prev_head);
24330 fprintf (dump, "Done finish_sched\n");
24335 struct _rs6000_sched_context
24337 short cached_can_issue_more;
24338 rtx last_scheduled_insn;
24339 int load_store_pendulum;
24342 typedef struct _rs6000_sched_context rs6000_sched_context_def;
24343 typedef rs6000_sched_context_def *rs6000_sched_context_t;
24345 /* Allocate store for new scheduling context. */
24347 rs6000_alloc_sched_context (void)
24349 return xmalloc (sizeof (rs6000_sched_context_def));
24352 /* If CLEAN_P is true then initializes _SC with clean data,
24353 and from the global context otherwise. */
24355 rs6000_init_sched_context (void *_sc, bool clean_p)
24357 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24361 sc->cached_can_issue_more = 0;
24362 sc->last_scheduled_insn = NULL_RTX;
24363 sc->load_store_pendulum = 0;
24367 sc->cached_can_issue_more = cached_can_issue_more;
24368 sc->last_scheduled_insn = last_scheduled_insn;
24369 sc->load_store_pendulum = load_store_pendulum;
24373 /* Sets the global scheduling context to the one pointed to by _SC. */
24375 rs6000_set_sched_context (void *_sc)
24377 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24379 gcc_assert (sc != NULL);
24381 cached_can_issue_more = sc->cached_can_issue_more;
24382 last_scheduled_insn = sc->last_scheduled_insn;
24383 load_store_pendulum = sc->load_store_pendulum;
24388 rs6000_free_sched_context (void *_sc)
24390 gcc_assert (_sc != NULL);
24396 /* Length in units of the trampoline for entering a nested function. */
24399 rs6000_trampoline_size (void)
24403 switch (DEFAULT_ABI)
24406 gcc_unreachable ();
24409 ret = (TARGET_32BIT) ? 12 : 24;
24414 ret = (TARGET_32BIT) ? 40 : 48;
24421 /* Emit RTL insns to initialize the variable parts of a trampoline.
24422 FNADDR is an RTX for the address of the function's pure code.
24423 CXT is an RTX for the static chain value for the function. */
24426 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
24428 int regsize = (TARGET_32BIT) ? 4 : 8;
24429 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
24430 rtx ctx_reg = force_reg (Pmode, cxt);
24431 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
24433 switch (DEFAULT_ABI)
24436 gcc_unreachable ();
24438 /* Under AIX, just build the 3 word function descriptor */
24441 rtx fnmem, fn_reg, toc_reg;
24443 if (!TARGET_POINTERS_TO_NESTED_FUNCTIONS)
24444 error ("-mno-r11 must not be used if you have trampolines");
24446 fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
24447 fn_reg = gen_reg_rtx (Pmode);
24448 toc_reg = gen_reg_rtx (Pmode);
24450 /* Macro to shorten the code expansions below. */
24451 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
24453 m_tramp = replace_equiv_address (m_tramp, addr);
24455 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
24456 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
24457 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
24458 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
24459 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
24465 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
24468 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
24469 LCT_NORMAL, VOIDmode, 4,
24471 GEN_INT (rs6000_trampoline_size ()), SImode,
24479 /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
24480 identifier as an argument, so the front end shouldn't look it up. */
24483 rs6000_attribute_takes_identifier_p (const_tree attr_id)
24485 return is_attribute_p ("altivec", attr_id);
24488 /* Handle the "altivec" attribute. The attribute may have
24489 arguments as follows:
24491 __attribute__((altivec(vector__)))
24492 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
24493 __attribute__((altivec(bool__))) (always followed by 'unsigned')
24495 and may appear more than once (e.g., 'vector bool char') in a
24496 given declaration. */
24499 rs6000_handle_altivec_attribute (tree *node,
24500 tree name ATTRIBUTE_UNUSED,
24502 int flags ATTRIBUTE_UNUSED,
24503 bool *no_add_attrs)
24505 tree type = *node, result = NULL_TREE;
24506 enum machine_mode mode;
24509 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
24510 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
24511 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
24514 while (POINTER_TYPE_P (type)
24515 || TREE_CODE (type) == FUNCTION_TYPE
24516 || TREE_CODE (type) == METHOD_TYPE
24517 || TREE_CODE (type) == ARRAY_TYPE)
24518 type = TREE_TYPE (type);
24520 mode = TYPE_MODE (type);
24522 /* Check for invalid AltiVec type qualifiers. */
24523 if (type == long_double_type_node)
24524 error ("use of %<long double%> in AltiVec types is invalid");
24525 else if (type == boolean_type_node)
24526 error ("use of boolean types in AltiVec types is invalid");
24527 else if (TREE_CODE (type) == COMPLEX_TYPE)
24528 error ("use of %<complex%> in AltiVec types is invalid");
24529 else if (DECIMAL_FLOAT_MODE_P (mode))
24530 error ("use of decimal floating point types in AltiVec types is invalid");
24531 else if (!TARGET_VSX)
24533 if (type == long_unsigned_type_node || type == long_integer_type_node)
24536 error ("use of %<long%> in AltiVec types is invalid for "
24537 "64-bit code without -mvsx");
24538 else if (rs6000_warn_altivec_long)
24539 warning (0, "use of %<long%> in AltiVec types is deprecated; "
24542 else if (type == long_long_unsigned_type_node
24543 || type == long_long_integer_type_node)
24544 error ("use of %<long long%> in AltiVec types is invalid without "
24546 else if (type == double_type_node)
24547 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
24550 switch (altivec_type)
24553 unsigned_p = TYPE_UNSIGNED (type);
24557 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
24560 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
24563 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
24566 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
24568 case SFmode: result = V4SF_type_node; break;
24569 case DFmode: result = V2DF_type_node; break;
24570 /* If the user says 'vector int bool', we may be handed the 'bool'
24571 attribute _before_ the 'vector' attribute, and so select the
24572 proper type in the 'b' case below. */
24573 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
24574 case V2DImode: case V2DFmode:
24582 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
24583 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
24584 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
24585 case QImode: case V16QImode: result = bool_V16QI_type_node;
24592 case V8HImode: result = pixel_V8HI_type_node;
24598 /* Propagate qualifiers attached to the element type
24599 onto the vector type. */
24600 if (result && result != type && TYPE_QUALS (type))
24601 result = build_qualified_type (result, TYPE_QUALS (type));
24603 *no_add_attrs = true; /* No need to hang on to the attribute. */
24606 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
24611 /* AltiVec defines four built-in scalar types that serve as vector
24612 elements; we must teach the compiler how to mangle them. */
24614 static const char *
24615 rs6000_mangle_type (const_tree type)
24617 type = TYPE_MAIN_VARIANT (type);
24619 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
24620 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
24623 if (type == bool_char_type_node) return "U6__boolc";
24624 if (type == bool_short_type_node) return "U6__bools";
24625 if (type == pixel_type_node) return "u7__pixel";
24626 if (type == bool_int_type_node) return "U6__booli";
24627 if (type == bool_long_type_node) return "U6__booll";
24629 /* Mangle IBM extended float long double as `g' (__float128) on
24630 powerpc*-linux where long-double-64 previously was the default. */
24631 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
24633 && TARGET_LONG_DOUBLE_128
24634 && !TARGET_IEEEQUAD)
24637 /* For all other types, use normal C++ mangling. */
24641 /* Handle a "longcall" or "shortcall" attribute; arguments as in
24642 struct attribute_spec.handler. */
24645 rs6000_handle_longcall_attribute (tree *node, tree name,
24646 tree args ATTRIBUTE_UNUSED,
24647 int flags ATTRIBUTE_UNUSED,
24648 bool *no_add_attrs)
24650 if (TREE_CODE (*node) != FUNCTION_TYPE
24651 && TREE_CODE (*node) != FIELD_DECL
24652 && TREE_CODE (*node) != TYPE_DECL)
24654 warning (OPT_Wattributes, "%qE attribute only applies to functions",
24656 *no_add_attrs = true;
24662 /* Set longcall attributes on all functions declared when
24663 rs6000_default_long_calls is true. */
24665 rs6000_set_default_type_attributes (tree type)
24667 if (rs6000_default_long_calls
24668 && (TREE_CODE (type) == FUNCTION_TYPE
24669 || TREE_CODE (type) == METHOD_TYPE))
24670 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
24672 TYPE_ATTRIBUTES (type));
24675 darwin_set_default_type_attributes (type);
24679 /* Return a reference suitable for calling a function with the
24680 longcall attribute. */
24683 rs6000_longcall_ref (rtx call_ref)
24685 const char *call_name;
24688 if (GET_CODE (call_ref) != SYMBOL_REF)
24691 /* System V adds '.' to the internal name, so skip them. */
24692 call_name = XSTR (call_ref, 0);
24693 if (*call_name == '.')
24695 while (*call_name == '.')
24698 node = get_identifier (call_name);
24699 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
24702 return force_reg (Pmode, call_ref);
24705 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
24706 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
24709 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
24710 struct attribute_spec.handler. */
24712 rs6000_handle_struct_attribute (tree *node, tree name,
24713 tree args ATTRIBUTE_UNUSED,
24714 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
24717 if (DECL_P (*node))
24719 if (TREE_CODE (*node) == TYPE_DECL)
24720 type = &TREE_TYPE (*node);
24725 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
24726 || TREE_CODE (*type) == UNION_TYPE)))
24728 warning (OPT_Wattributes, "%qE attribute ignored", name);
24729 *no_add_attrs = true;
24732 else if ((is_attribute_p ("ms_struct", name)
24733 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
24734 || ((is_attribute_p ("gcc_struct", name)
24735 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
24737 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
24739 *no_add_attrs = true;
24746 rs6000_ms_bitfield_layout_p (const_tree record_type)
24748 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
24749 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
24750 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
24753 #ifdef USING_ELFOS_H
24755 /* A get_unnamed_section callback, used for switching to toc_section. */
24758 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
24760 if (DEFAULT_ABI == ABI_AIX
24761 && TARGET_MINIMAL_TOC
24762 && !TARGET_RELOCATABLE)
24764 if (!toc_initialized)
24766 toc_initialized = 1;
24767 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
24768 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
24769 fprintf (asm_out_file, "\t.tc ");
24770 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
24771 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24772 fprintf (asm_out_file, "\n");
24774 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24775 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24776 fprintf (asm_out_file, " = .+32768\n");
24779 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24781 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
24782 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
24785 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24786 if (!toc_initialized)
24788 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24789 fprintf (asm_out_file, " = .+32768\n");
24790 toc_initialized = 1;
24795 /* Implement TARGET_ASM_INIT_SECTIONS. */
24798 rs6000_elf_asm_init_sections (void)
24801 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
24804 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
24805 SDATA2_SECTION_ASM_OP);
24808 /* Implement TARGET_SELECT_RTX_SECTION. */
24811 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
24812 unsigned HOST_WIDE_INT align)
24814 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
24815 return toc_section;
24817 return default_elf_select_rtx_section (mode, x, align);
24820 /* For a SYMBOL_REF, set generic flags and then perform some
24821 target-specific processing.
24823 When the AIX ABI is requested on a non-AIX system, replace the
24824 function name with the real name (with a leading .) rather than the
24825 function descriptor name. This saves a lot of overriding code to
24826 read the prefixes. */
24829 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
24831 default_encode_section_info (decl, rtl, first);
24834 && TREE_CODE (decl) == FUNCTION_DECL
24836 && DEFAULT_ABI == ABI_AIX)
24838 rtx sym_ref = XEXP (rtl, 0);
24839 size_t len = strlen (XSTR (sym_ref, 0));
24840 char *str = XALLOCAVEC (char, len + 2);
24842 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
24843 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
24848 compare_section_name (const char *section, const char *templ)
24852 len = strlen (templ);
24853 return (strncmp (section, templ, len) == 0
24854 && (section[len] == 0 || section[len] == '.'));
24858 rs6000_elf_in_small_data_p (const_tree decl)
24860 if (rs6000_sdata == SDATA_NONE)
24863 /* We want to merge strings, so we never consider them small data. */
24864 if (TREE_CODE (decl) == STRING_CST)
24867 /* Functions are never in the small data area. */
24868 if (TREE_CODE (decl) == FUNCTION_DECL)
24871 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
24873 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
24874 if (compare_section_name (section, ".sdata")
24875 || compare_section_name (section, ".sdata2")
24876 || compare_section_name (section, ".gnu.linkonce.s")
24877 || compare_section_name (section, ".sbss")
24878 || compare_section_name (section, ".sbss2")
24879 || compare_section_name (section, ".gnu.linkonce.sb")
24880 || strcmp (section, ".PPC.EMB.sdata0") == 0
24881 || strcmp (section, ".PPC.EMB.sbss0") == 0)
24886 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
24889 && size <= g_switch_value
24890 /* If it's not public, and we're not going to reference it there,
24891 there's no need to put it in the small data section. */
24892 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
24899 #endif /* USING_ELFOS_H */
24901 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
24904 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
24906 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
24909 /* Return a REG that occurs in ADDR with coefficient 1.
24910 ADDR can be effectively incremented by incrementing REG.
24912 r0 is special and we must not select it as an address
24913 register by this routine since our caller will try to
24914 increment the returned register via an "la" instruction. */
24917 find_addr_reg (rtx addr)
24919 while (GET_CODE (addr) == PLUS)
24921 if (GET_CODE (XEXP (addr, 0)) == REG
24922 && REGNO (XEXP (addr, 0)) != 0)
24923 addr = XEXP (addr, 0);
24924 else if (GET_CODE (XEXP (addr, 1)) == REG
24925 && REGNO (XEXP (addr, 1)) != 0)
24926 addr = XEXP (addr, 1);
24927 else if (CONSTANT_P (XEXP (addr, 0)))
24928 addr = XEXP (addr, 1);
24929 else if (CONSTANT_P (XEXP (addr, 1)))
24930 addr = XEXP (addr, 0);
24932 gcc_unreachable ();
24934 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
24939 rs6000_fatal_bad_address (rtx op)
24941 fatal_insn ("bad address", op);
24946 typedef struct branch_island_d {
24947 tree function_name;
24952 DEF_VEC_O(branch_island);
24953 DEF_VEC_ALLOC_O(branch_island,gc);
24955 static VEC(branch_island,gc) *branch_islands;
24957 /* Remember to generate a branch island for far calls to the given
24961 add_compiler_branch_island (tree label_name, tree function_name,
24964 branch_island *bi = VEC_safe_push (branch_island, gc, branch_islands, NULL);
24966 bi->function_name = function_name;
24967 bi->label_name = label_name;
24968 bi->line_number = line_number;
24971 /* Generate far-jump branch islands for everything recorded in
24972 branch_islands. Invoked immediately after the last instruction of
24973 the epilogue has been emitted; the branch islands must be appended
24974 to, and contiguous with, the function body. Mach-O stubs are
24975 generated in machopic_output_stub(). */
24978 macho_branch_islands (void)
24982 while (!VEC_empty (branch_island, branch_islands))
24984 branch_island *bi = VEC_last (branch_island, branch_islands);
24985 const char *label = IDENTIFIER_POINTER (bi->label_name);
24986 const char *name = IDENTIFIER_POINTER (bi->function_name);
24987 char name_buf[512];
24988 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
24989 if (name[0] == '*' || name[0] == '&')
24990 strcpy (name_buf, name+1);
24994 strcpy (name_buf+1, name);
24996 strcpy (tmp_buf, "\n");
24997 strcat (tmp_buf, label);
24998 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
24999 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25000 dbxout_stabd (N_SLINE, bi->line_number);
25001 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25004 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
25005 strcat (tmp_buf, label);
25006 strcat (tmp_buf, "_pic\n");
25007 strcat (tmp_buf, label);
25008 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
25010 strcat (tmp_buf, "\taddis r11,r11,ha16(");
25011 strcat (tmp_buf, name_buf);
25012 strcat (tmp_buf, " - ");
25013 strcat (tmp_buf, label);
25014 strcat (tmp_buf, "_pic)\n");
25016 strcat (tmp_buf, "\tmtlr r0\n");
25018 strcat (tmp_buf, "\taddi r12,r11,lo16(");
25019 strcat (tmp_buf, name_buf);
25020 strcat (tmp_buf, " - ");
25021 strcat (tmp_buf, label);
25022 strcat (tmp_buf, "_pic)\n");
25024 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
25028 strcat (tmp_buf, ":\nlis r12,hi16(");
25029 strcat (tmp_buf, name_buf);
25030 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
25031 strcat (tmp_buf, name_buf);
25032 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
25034 output_asm_insn (tmp_buf, 0);
25035 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25036 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25037 dbxout_stabd (N_SLINE, bi->line_number);
25038 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25039 VEC_pop (branch_island, branch_islands);
25043 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
25044 already there or not. */
25047 no_previous_def (tree function_name)
25052 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25053 if (function_name == bi->function_name)
25058 /* GET_PREV_LABEL gets the label name from the previous definition of
25062 get_prev_label (tree function_name)
25067 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25068 if (function_name == bi->function_name)
25069 return bi->label_name;
25073 /* INSN is either a function call or a millicode call. It may have an
25074 unconditional jump in its delay slot.
25076 CALL_DEST is the routine we are calling. */
25079 output_call (rtx insn, rtx *operands, int dest_operand_number,
25080 int cookie_operand_number)
25082 static char buf[256];
25083 if (darwin_emit_branch_islands
25084 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
25085 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
25088 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
25090 if (no_previous_def (funname))
25092 rtx label_rtx = gen_label_rtx ();
25093 char *label_buf, temp_buf[256];
25094 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
25095 CODE_LABEL_NUMBER (label_rtx));
25096 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
25097 labelname = get_identifier (label_buf);
25098 add_compiler_branch_island (labelname, funname, insn_line (insn));
25101 labelname = get_prev_label (funname);
25103 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
25104 instruction will reach 'foo', otherwise link as 'bl L42'".
25105 "L42" should be a 'branch island', that will do a far jump to
25106 'foo'. Branch islands are generated in
25107 macho_branch_islands(). */
25108 sprintf (buf, "jbsr %%z%d,%.246s",
25109 dest_operand_number, IDENTIFIER_POINTER (labelname));
25112 sprintf (buf, "bl %%z%d", dest_operand_number);
25116 /* Generate PIC and indirect symbol stubs. */
25119 machopic_output_stub (FILE *file, const char *symb, const char *stub)
25121 unsigned int length;
25122 char *symbol_name, *lazy_ptr_name;
25123 char *local_label_0;
25124 static int label = 0;
25126 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
25127 symb = (*targetm.strip_name_encoding) (symb);
25130 length = strlen (symb);
25131 symbol_name = XALLOCAVEC (char, length + 32);
25132 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
25134 lazy_ptr_name = XALLOCAVEC (char, length + 32);
25135 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
25138 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
25140 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
25144 fprintf (file, "\t.align 5\n");
25146 fprintf (file, "%s:\n", stub);
25147 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25150 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
25151 sprintf (local_label_0, "\"L%011d$spb\"", label);
25153 fprintf (file, "\tmflr r0\n");
25154 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
25155 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
25156 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
25157 lazy_ptr_name, local_label_0);
25158 fprintf (file, "\tmtlr r0\n");
25159 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
25160 (TARGET_64BIT ? "ldu" : "lwzu"),
25161 lazy_ptr_name, local_label_0);
25162 fprintf (file, "\tmtctr r12\n");
25163 fprintf (file, "\tbctr\n");
25167 fprintf (file, "\t.align 4\n");
25169 fprintf (file, "%s:\n", stub);
25170 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25172 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
25173 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
25174 (TARGET_64BIT ? "ldu" : "lwzu"),
25176 fprintf (file, "\tmtctr r12\n");
25177 fprintf (file, "\tbctr\n");
25180 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
25181 fprintf (file, "%s:\n", lazy_ptr_name);
25182 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25183 fprintf (file, "%sdyld_stub_binding_helper\n",
25184 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
25187 /* Legitimize PIC addresses. If the address is already
25188 position-independent, we return ORIG. Newly generated
25189 position-independent addresses go into a reg. This is REG if non
25190 zero, otherwise we allocate register(s) as necessary. */
25192 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
25195 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
25200 if (reg == NULL && ! reload_in_progress && ! reload_completed)
25201 reg = gen_reg_rtx (Pmode);
25203 if (GET_CODE (orig) == CONST)
25207 if (GET_CODE (XEXP (orig, 0)) == PLUS
25208 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
25211 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
25213 /* Use a different reg for the intermediate value, as
25214 it will be marked UNCHANGING. */
25215 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
25216 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
25219 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
25222 if (GET_CODE (offset) == CONST_INT)
25224 if (SMALL_INT (offset))
25225 return plus_constant (base, INTVAL (offset));
25226 else if (! reload_in_progress && ! reload_completed)
25227 offset = force_reg (Pmode, offset);
25230 rtx mem = force_const_mem (Pmode, orig);
25231 return machopic_legitimize_pic_address (mem, Pmode, reg);
25234 return gen_rtx_PLUS (Pmode, base, offset);
25237 /* Fall back on generic machopic code. */
25238 return machopic_legitimize_pic_address (orig, mode, reg);
25241 /* Output a .machine directive for the Darwin assembler, and call
25242 the generic start_file routine. */
25245 rs6000_darwin_file_start (void)
25247 static const struct
25253 { "ppc64", "ppc64", MASK_64BIT },
25254 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
25255 { "power4", "ppc970", 0 },
25256 { "G5", "ppc970", 0 },
25257 { "7450", "ppc7450", 0 },
25258 { "7400", "ppc7400", MASK_ALTIVEC },
25259 { "G4", "ppc7400", 0 },
25260 { "750", "ppc750", 0 },
25261 { "740", "ppc750", 0 },
25262 { "G3", "ppc750", 0 },
25263 { "604e", "ppc604e", 0 },
25264 { "604", "ppc604", 0 },
25265 { "603e", "ppc603", 0 },
25266 { "603", "ppc603", 0 },
25267 { "601", "ppc601", 0 },
25268 { NULL, "ppc", 0 } };
25269 const char *cpu_id = "";
25272 rs6000_file_start ();
25273 darwin_file_start ();
25275 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
25277 if (rs6000_default_cpu != 0 && rs6000_default_cpu[0] != '\0')
25278 cpu_id = rs6000_default_cpu;
25280 if (global_options_set.x_rs6000_cpu_index)
25281 cpu_id = processor_target_table[rs6000_cpu_index].name;
25283 /* Look through the mapping array. Pick the first name that either
25284 matches the argument, has a bit set in IF_SET that is also set
25285 in the target flags, or has a NULL name. */
25288 while (mapping[i].arg != NULL
25289 && strcmp (mapping[i].arg, cpu_id) != 0
25290 && (mapping[i].if_set & target_flags) == 0)
25293 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
25296 #endif /* TARGET_MACHO */
25300 rs6000_elf_reloc_rw_mask (void)
25304 else if (DEFAULT_ABI == ABI_AIX)
25310 /* Record an element in the table of global constructors. SYMBOL is
25311 a SYMBOL_REF of the function to be called; PRIORITY is a number
25312 between 0 and MAX_INIT_PRIORITY.
25314 This differs from default_named_section_asm_out_constructor in
25315 that we have special handling for -mrelocatable. */
25318 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
25320 const char *section = ".ctors";
25323 if (priority != DEFAULT_INIT_PRIORITY)
25325 sprintf (buf, ".ctors.%.5u",
25326 /* Invert the numbering so the linker puts us in the proper
25327 order; constructors are run from right to left, and the
25328 linker sorts in increasing order. */
25329 MAX_INIT_PRIORITY - priority);
25333 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25334 assemble_align (POINTER_SIZE);
25336 if (TARGET_RELOCATABLE)
25338 fputs ("\t.long (", asm_out_file);
25339 output_addr_const (asm_out_file, symbol);
25340 fputs (")@fixup\n", asm_out_file);
25343 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25347 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
25349 const char *section = ".dtors";
25352 if (priority != DEFAULT_INIT_PRIORITY)
25354 sprintf (buf, ".dtors.%.5u",
25355 /* Invert the numbering so the linker puts us in the proper
25356 order; constructors are run from right to left, and the
25357 linker sorts in increasing order. */
25358 MAX_INIT_PRIORITY - priority);
25362 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25363 assemble_align (POINTER_SIZE);
25365 if (TARGET_RELOCATABLE)
25367 fputs ("\t.long (", asm_out_file);
25368 output_addr_const (asm_out_file, symbol);
25369 fputs (")@fixup\n", asm_out_file);
25372 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25376 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
25380 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
25381 ASM_OUTPUT_LABEL (file, name);
25382 fputs (DOUBLE_INT_ASM_OP, file);
25383 rs6000_output_function_entry (file, name);
25384 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
25387 fputs ("\t.size\t", file);
25388 assemble_name (file, name);
25389 fputs (",24\n\t.type\t.", file);
25390 assemble_name (file, name);
25391 fputs (",@function\n", file);
25392 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
25394 fputs ("\t.globl\t.", file);
25395 assemble_name (file, name);
25400 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25401 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25402 rs6000_output_function_entry (file, name);
25403 fputs (":\n", file);
25407 if (TARGET_RELOCATABLE
25408 && !TARGET_SECURE_PLT
25409 && (get_pool_size () != 0 || crtl->profile)
25414 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
25416 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
25417 fprintf (file, "\t.long ");
25418 assemble_name (file, buf);
25420 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
25421 assemble_name (file, buf);
25425 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25426 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25428 if (DEFAULT_ABI == ABI_AIX)
25430 const char *desc_name, *orig_name;
25432 orig_name = (*targetm.strip_name_encoding) (name);
25433 desc_name = orig_name;
25434 while (*desc_name == '.')
25437 if (TREE_PUBLIC (decl))
25438 fprintf (file, "\t.globl %s\n", desc_name);
25440 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25441 fprintf (file, "%s:\n", desc_name);
25442 fprintf (file, "\t.long %s\n", orig_name);
25443 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
25444 if (DEFAULT_ABI == ABI_AIX)
25445 fputs ("\t.long 0\n", file);
25446 fprintf (file, "\t.previous\n");
25448 ASM_OUTPUT_LABEL (file, name);
25452 rs6000_elf_file_end (void)
25454 #ifdef HAVE_AS_GNU_ATTRIBUTE
25455 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
25457 if (rs6000_passes_float)
25458 fprintf (asm_out_file, "\t.gnu_attribute 4, %d\n",
25459 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
25460 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
25462 if (rs6000_passes_vector)
25463 fprintf (asm_out_file, "\t.gnu_attribute 8, %d\n",
25464 (TARGET_ALTIVEC_ABI ? 2
25465 : TARGET_SPE_ABI ? 3
25467 if (rs6000_returns_struct)
25468 fprintf (asm_out_file, "\t.gnu_attribute 12, %d\n",
25469 aix_struct_return ? 2 : 1);
25472 #ifdef POWERPC_LINUX
25474 file_end_indicate_exec_stack ();
25481 rs6000_xcoff_asm_output_anchor (rtx symbol)
25485 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
25486 SYMBOL_REF_BLOCK_OFFSET (symbol));
25487 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
25491 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
25493 fputs (GLOBAL_ASM_OP, stream);
25494 RS6000_OUTPUT_BASENAME (stream, name);
25495 putc ('\n', stream);
25498 /* A get_unnamed_decl callback, used for read-only sections. PTR
25499 points to the section string variable. */
25502 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
25504 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
25505 *(const char *const *) directive,
25506 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
25509 /* Likewise for read-write sections. */
25512 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
25514 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
25515 *(const char *const *) directive,
25516 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
25519 /* A get_unnamed_section callback, used for switching to toc_section. */
25522 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
25524 if (TARGET_MINIMAL_TOC)
25526 /* toc_section is always selected at least once from
25527 rs6000_xcoff_file_start, so this is guaranteed to
25528 always be defined once and only once in each file. */
25529 if (!toc_initialized)
25531 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
25532 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
25533 toc_initialized = 1;
25535 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
25536 (TARGET_32BIT ? "" : ",3"));
25539 fputs ("\t.toc\n", asm_out_file);
25542 /* Implement TARGET_ASM_INIT_SECTIONS. */
25545 rs6000_xcoff_asm_init_sections (void)
25547 read_only_data_section
25548 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
25549 &xcoff_read_only_section_name);
25551 private_data_section
25552 = get_unnamed_section (SECTION_WRITE,
25553 rs6000_xcoff_output_readwrite_section_asm_op,
25554 &xcoff_private_data_section_name);
25556 read_only_private_data_section
25557 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
25558 &xcoff_private_data_section_name);
25561 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
25563 readonly_data_section = read_only_data_section;
25564 exception_section = data_section;
25568 rs6000_xcoff_reloc_rw_mask (void)
25574 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
25575 tree decl ATTRIBUTE_UNUSED)
25578 static const char * const suffix[3] = { "PR", "RO", "RW" };
25580 if (flags & SECTION_CODE)
25582 else if (flags & SECTION_WRITE)
25587 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
25588 (flags & SECTION_CODE) ? "." : "",
25589 name, suffix[smclass], flags & SECTION_ENTSIZE);
25593 rs6000_xcoff_select_section (tree decl, int reloc,
25594 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
25596 if (decl_readonly_section (decl, reloc))
25598 if (TREE_PUBLIC (decl))
25599 return read_only_data_section;
25601 return read_only_private_data_section;
25605 if (TREE_PUBLIC (decl))
25606 return data_section;
25608 return private_data_section;
25613 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
25617 /* Use select_section for private and uninitialized data. */
25618 if (!TREE_PUBLIC (decl)
25619 || DECL_COMMON (decl)
25620 || DECL_INITIAL (decl) == NULL_TREE
25621 || DECL_INITIAL (decl) == error_mark_node
25622 || (flag_zero_initialized_in_bss
25623 && initializer_zerop (DECL_INITIAL (decl))))
25626 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
25627 name = (*targetm.strip_name_encoding) (name);
25628 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
25631 /* Select section for constant in constant pool.
25633 On RS/6000, all constants are in the private read-only data area.
25634 However, if this is being placed in the TOC it must be output as a
25638 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
25639 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
25641 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
25642 return toc_section;
25644 return read_only_private_data_section;
25647 /* Remove any trailing [DS] or the like from the symbol name. */
25649 static const char *
25650 rs6000_xcoff_strip_name_encoding (const char *name)
25655 len = strlen (name);
25656 if (name[len - 1] == ']')
25657 return ggc_alloc_string (name, len - 4);
25662 /* Section attributes. AIX is always PIC. */
25664 static unsigned int
25665 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
25667 unsigned int align;
25668 unsigned int flags = default_section_type_flags (decl, name, reloc);
25670 /* Align to at least UNIT size. */
25671 if (flags & SECTION_CODE)
25672 align = MIN_UNITS_PER_WORD;
25674 /* Increase alignment of large objects if not already stricter. */
25675 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
25676 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
25677 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
25679 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
25682 /* Output at beginning of assembler file.
25684 Initialize the section names for the RS/6000 at this point.
25686 Specify filename, including full path, to assembler.
25688 We want to go into the TOC section so at least one .toc will be emitted.
25689 Also, in order to output proper .bs/.es pairs, we need at least one static
25690 [RW] section emitted.
25692 Finally, declare mcount when profiling to make the assembler happy. */
25695 rs6000_xcoff_file_start (void)
25697 rs6000_gen_section_name (&xcoff_bss_section_name,
25698 main_input_filename, ".bss_");
25699 rs6000_gen_section_name (&xcoff_private_data_section_name,
25700 main_input_filename, ".rw_");
25701 rs6000_gen_section_name (&xcoff_read_only_section_name,
25702 main_input_filename, ".ro_");
25704 fputs ("\t.file\t", asm_out_file);
25705 output_quoted_string (asm_out_file, main_input_filename);
25706 fputc ('\n', asm_out_file);
25707 if (write_symbols != NO_DEBUG)
25708 switch_to_section (private_data_section);
25709 switch_to_section (text_section);
25711 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
25712 rs6000_file_start ();
25715 /* Output at end of assembler file.
25716 On the RS/6000, referencing data should automatically pull in text. */
25719 rs6000_xcoff_file_end (void)
25721 switch_to_section (text_section);
25722 fputs ("_section_.text:\n", asm_out_file);
25723 switch_to_section (data_section);
25724 fputs (TARGET_32BIT
25725 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
25728 #endif /* TARGET_XCOFF */
25730 /* Compute a (partial) cost for rtx X. Return true if the complete
25731 cost has been computed, and false if subexpressions should be
25732 scanned. In either case, *TOTAL contains the cost result. */
25735 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
25738 enum machine_mode mode = GET_MODE (x);
25742 /* On the RS/6000, if it is valid in the insn, it is free. */
25744 if (((outer_code == SET
25745 || outer_code == PLUS
25746 || outer_code == MINUS)
25747 && (satisfies_constraint_I (x)
25748 || satisfies_constraint_L (x)))
25749 || (outer_code == AND
25750 && (satisfies_constraint_K (x)
25752 ? satisfies_constraint_L (x)
25753 : satisfies_constraint_J (x))
25754 || mask_operand (x, mode)
25756 && mask64_operand (x, DImode))))
25757 || ((outer_code == IOR || outer_code == XOR)
25758 && (satisfies_constraint_K (x)
25760 ? satisfies_constraint_L (x)
25761 : satisfies_constraint_J (x))))
25762 || outer_code == ASHIFT
25763 || outer_code == ASHIFTRT
25764 || outer_code == LSHIFTRT
25765 || outer_code == ROTATE
25766 || outer_code == ROTATERT
25767 || outer_code == ZERO_EXTRACT
25768 || (outer_code == MULT
25769 && satisfies_constraint_I (x))
25770 || ((outer_code == DIV || outer_code == UDIV
25771 || outer_code == MOD || outer_code == UMOD)
25772 && exact_log2 (INTVAL (x)) >= 0)
25773 || (outer_code == COMPARE
25774 && (satisfies_constraint_I (x)
25775 || satisfies_constraint_K (x)))
25776 || ((outer_code == EQ || outer_code == NE)
25777 && (satisfies_constraint_I (x)
25778 || satisfies_constraint_K (x)
25780 ? satisfies_constraint_L (x)
25781 : satisfies_constraint_J (x))))
25782 || (outer_code == GTU
25783 && satisfies_constraint_I (x))
25784 || (outer_code == LTU
25785 && satisfies_constraint_P (x)))
25790 else if ((outer_code == PLUS
25791 && reg_or_add_cint_operand (x, VOIDmode))
25792 || (outer_code == MINUS
25793 && reg_or_sub_cint_operand (x, VOIDmode))
25794 || ((outer_code == SET
25795 || outer_code == IOR
25796 || outer_code == XOR)
25798 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
25800 *total = COSTS_N_INSNS (1);
25806 if (mode == DImode && code == CONST_DOUBLE)
25808 if ((outer_code == IOR || outer_code == XOR)
25809 && CONST_DOUBLE_HIGH (x) == 0
25810 && (CONST_DOUBLE_LOW (x)
25811 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
25816 else if ((outer_code == AND && and64_2_operand (x, DImode))
25817 || ((outer_code == SET
25818 || outer_code == IOR
25819 || outer_code == XOR)
25820 && CONST_DOUBLE_HIGH (x) == 0))
25822 *total = COSTS_N_INSNS (1);
25832 /* When optimizing for size, MEM should be slightly more expensive
25833 than generating address, e.g., (plus (reg) (const)).
25834 L1 cache latency is about two instructions. */
25835 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
25844 if (FLOAT_MODE_P (mode))
25845 *total = rs6000_cost->fp;
25847 *total = COSTS_N_INSNS (1);
25851 if (GET_CODE (XEXP (x, 1)) == CONST_INT
25852 && satisfies_constraint_I (XEXP (x, 1)))
25854 if (INTVAL (XEXP (x, 1)) >= -256
25855 && INTVAL (XEXP (x, 1)) <= 255)
25856 *total = rs6000_cost->mulsi_const9;
25858 *total = rs6000_cost->mulsi_const;
25860 else if (mode == SFmode)
25861 *total = rs6000_cost->fp;
25862 else if (FLOAT_MODE_P (mode))
25863 *total = rs6000_cost->dmul;
25864 else if (mode == DImode)
25865 *total = rs6000_cost->muldi;
25867 *total = rs6000_cost->mulsi;
25871 if (mode == SFmode)
25872 *total = rs6000_cost->fp;
25874 *total = rs6000_cost->dmul;
25879 if (FLOAT_MODE_P (mode))
25881 *total = mode == DFmode ? rs6000_cost->ddiv
25882 : rs6000_cost->sdiv;
25889 if (GET_CODE (XEXP (x, 1)) == CONST_INT
25890 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
25892 if (code == DIV || code == MOD)
25894 *total = COSTS_N_INSNS (2);
25897 *total = COSTS_N_INSNS (1);
25901 if (GET_MODE (XEXP (x, 1)) == DImode)
25902 *total = rs6000_cost->divdi;
25904 *total = rs6000_cost->divsi;
25906 /* Add in shift and subtract for MOD. */
25907 if (code == MOD || code == UMOD)
25908 *total += COSTS_N_INSNS (2);
25913 *total = COSTS_N_INSNS (4);
25917 *total = COSTS_N_INSNS (TARGET_POPCNTD ? 1 : 6);
25921 *total = COSTS_N_INSNS (TARGET_CMPB ? 2 : 6);
25925 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
25937 *total = COSTS_N_INSNS (1);
25945 /* Handle mul_highpart. */
25946 if (outer_code == TRUNCATE
25947 && GET_CODE (XEXP (x, 0)) == MULT)
25949 if (mode == DImode)
25950 *total = rs6000_cost->muldi;
25952 *total = rs6000_cost->mulsi;
25955 else if (outer_code == AND)
25958 *total = COSTS_N_INSNS (1);
25963 if (GET_CODE (XEXP (x, 0)) == MEM)
25966 *total = COSTS_N_INSNS (1);
25972 if (!FLOAT_MODE_P (mode))
25974 *total = COSTS_N_INSNS (1);
25980 case UNSIGNED_FLOAT:
25983 case FLOAT_TRUNCATE:
25984 *total = rs6000_cost->fp;
25988 if (mode == DFmode)
25991 *total = rs6000_cost->fp;
25995 switch (XINT (x, 1))
25998 *total = rs6000_cost->fp;
26010 *total = COSTS_N_INSNS (1);
26013 else if (FLOAT_MODE_P (mode)
26014 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
26016 *total = rs6000_cost->fp;
26024 /* Carry bit requires mode == Pmode.
26025 NEG or PLUS already counted so only add one. */
26027 && (outer_code == NEG || outer_code == PLUS))
26029 *total = COSTS_N_INSNS (1);
26032 if (outer_code == SET)
26034 if (XEXP (x, 1) == const0_rtx)
26036 if (TARGET_ISEL && !TARGET_MFCRF)
26037 *total = COSTS_N_INSNS (8);
26039 *total = COSTS_N_INSNS (2);
26042 else if (mode == Pmode)
26044 *total = COSTS_N_INSNS (3);
26053 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
26055 if (TARGET_ISEL && !TARGET_MFCRF)
26056 *total = COSTS_N_INSNS (8);
26058 *total = COSTS_N_INSNS (2);
26062 if (outer_code == COMPARE)
26076 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
26079 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
26082 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
26085 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
26086 "total = %d, speed = %s, x:\n",
26087 ret ? "complete" : "scan inner",
26088 GET_RTX_NAME (code),
26089 GET_RTX_NAME (outer_code),
26091 speed ? "true" : "false");
26098 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
26101 rs6000_debug_address_cost (rtx x, bool speed)
26103 int ret = TARGET_ADDRESS_COST (x, speed);
26105 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
26106 ret, speed ? "true" : "false");
26113 /* A C expression returning the cost of moving data from a register of class
26114 CLASS1 to one of CLASS2. */
26117 rs6000_register_move_cost (enum machine_mode mode,
26118 reg_class_t from, reg_class_t to)
26122 if (TARGET_DEBUG_COST)
26125 /* Moves from/to GENERAL_REGS. */
26126 if (reg_classes_intersect_p (to, GENERAL_REGS)
26127 || reg_classes_intersect_p (from, GENERAL_REGS))
26129 reg_class_t rclass = from;
26131 if (! reg_classes_intersect_p (to, GENERAL_REGS))
26134 if (rclass == FLOAT_REGS || rclass == ALTIVEC_REGS || rclass == VSX_REGS)
26135 ret = (rs6000_memory_move_cost (mode, rclass, false)
26136 + rs6000_memory_move_cost (mode, GENERAL_REGS, false));
26138 /* It's more expensive to move CR_REGS than CR0_REGS because of the
26140 else if (rclass == CR_REGS)
26143 /* For those processors that have slow LR/CTR moves, make them more
26144 expensive than memory in order to bias spills to memory .*/
26145 else if ((rs6000_cpu == PROCESSOR_POWER6
26146 || rs6000_cpu == PROCESSOR_POWER7)
26147 && reg_classes_intersect_p (rclass, LINK_OR_CTR_REGS))
26148 ret = 6 * hard_regno_nregs[0][mode];
26151 /* A move will cost one instruction per GPR moved. */
26152 ret = 2 * hard_regno_nregs[0][mode];
26155 /* If we have VSX, we can easily move between FPR or Altivec registers. */
26156 else if (VECTOR_UNIT_VSX_P (mode)
26157 && reg_classes_intersect_p (to, VSX_REGS)
26158 && reg_classes_intersect_p (from, VSX_REGS))
26159 ret = 2 * hard_regno_nregs[32][mode];
26161 /* Moving between two similar registers is just one instruction. */
26162 else if (reg_classes_intersect_p (to, from))
26163 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
26165 /* Everything else has to go through GENERAL_REGS. */
26167 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
26168 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
26170 if (TARGET_DEBUG_COST)
26172 if (dbg_cost_ctrl == 1)
26174 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
26175 ret, GET_MODE_NAME (mode), reg_class_names[from],
26176 reg_class_names[to]);
26183 /* A C expressions returning the cost of moving data of MODE from a register to
26187 rs6000_memory_move_cost (enum machine_mode mode, reg_class_t rclass,
26188 bool in ATTRIBUTE_UNUSED)
26192 if (TARGET_DEBUG_COST)
26195 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
26196 ret = 4 * hard_regno_nregs[0][mode];
26197 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
26198 ret = 4 * hard_regno_nregs[32][mode];
26199 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
26200 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
26202 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
26204 if (TARGET_DEBUG_COST)
26206 if (dbg_cost_ctrl == 1)
26208 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
26209 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
26216 /* Returns a code for a target-specific builtin that implements
26217 reciprocal of the function, or NULL_TREE if not available. */
26220 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
26221 bool sqrt ATTRIBUTE_UNUSED)
26223 if (optimize_insn_for_size_p ())
26229 case VSX_BUILTIN_XVSQRTDP:
26230 if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode))
26233 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
26235 case VSX_BUILTIN_XVSQRTSP:
26236 if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode))
26239 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V4SF];
26248 case BUILT_IN_SQRT:
26249 if (!RS6000_RECIP_AUTO_RSQRTE_P (DFmode))
26252 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRT];
26254 case BUILT_IN_SQRTF:
26255 if (!RS6000_RECIP_AUTO_RSQRTE_P (SFmode))
26258 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
26265 /* Load up a constant. If the mode is a vector mode, splat the value across
26266 all of the vector elements. */
26269 rs6000_load_constant_and_splat (enum machine_mode mode, REAL_VALUE_TYPE dconst)
26273 if (mode == SFmode || mode == DFmode)
26275 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, mode);
26276 reg = force_reg (mode, d);
26278 else if (mode == V4SFmode)
26280 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, SFmode);
26281 rtvec v = gen_rtvec (4, d, d, d, d);
26282 reg = gen_reg_rtx (mode);
26283 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26285 else if (mode == V2DFmode)
26287 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, DFmode);
26288 rtvec v = gen_rtvec (2, d, d);
26289 reg = gen_reg_rtx (mode);
26290 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26293 gcc_unreachable ();
26298 /* Generate an FMA instruction. */
26301 rs6000_emit_madd (rtx target, rtx m1, rtx m2, rtx a)
26303 enum machine_mode mode = GET_MODE (target);
26306 dst = expand_ternary_op (mode, fma_optab, m1, m2, a, target, 0);
26307 gcc_assert (dst != NULL);
26310 emit_move_insn (target, dst);
26313 /* Generate a FMSUB instruction: dst = fma(m1, m2, -a). */
26316 rs6000_emit_msub (rtx target, rtx m1, rtx m2, rtx a)
26318 enum machine_mode mode = GET_MODE (target);
26321 /* Altivec does not support fms directly;
26322 generate in terms of fma in that case. */
26323 if (optab_handler (fms_optab, mode) != CODE_FOR_nothing)
26324 dst = expand_ternary_op (mode, fms_optab, m1, m2, a, target, 0);
26327 a = expand_unop (mode, neg_optab, a, NULL_RTX, 0);
26328 dst = expand_ternary_op (mode, fma_optab, m1, m2, a, target, 0);
26330 gcc_assert (dst != NULL);
26333 emit_move_insn (target, dst);
26336 /* Generate a FNMSUB instruction: dst = -fma(m1, m2, -a). */
26339 rs6000_emit_nmsub (rtx dst, rtx m1, rtx m2, rtx a)
26341 enum machine_mode mode = GET_MODE (dst);
26344 /* This is a tad more complicated, since the fnma_optab is for
26345 a different expression: fma(-m1, m2, a), which is the same
26346 thing except in the case of signed zeros.
26348 Fortunately we know that if FMA is supported that FNMSUB is
26349 also supported in the ISA. Just expand it directly. */
26351 gcc_assert (optab_handler (fma_optab, mode) != CODE_FOR_nothing);
26353 r = gen_rtx_NEG (mode, a);
26354 r = gen_rtx_FMA (mode, m1, m2, r);
26355 r = gen_rtx_NEG (mode, r);
26356 emit_insn (gen_rtx_SET (VOIDmode, dst, r));
26359 /* Newton-Raphson approximation of floating point divide with just 2 passes
26360 (either single precision floating point, or newer machines with higher
26361 accuracy estimates). Support both scalar and vector divide. Assumes no
26362 trapping math and finite arguments. */
26365 rs6000_emit_swdiv_high_precision (rtx dst, rtx n, rtx d)
26367 enum machine_mode mode = GET_MODE (dst);
26368 rtx x0, e0, e1, y1, u0, v0;
26369 enum insn_code code = optab_handler (smul_optab, mode);
26370 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26371 rtx one = rs6000_load_constant_and_splat (mode, dconst1);
26373 gcc_assert (code != CODE_FOR_nothing);
26375 /* x0 = 1./d estimate */
26376 x0 = gen_reg_rtx (mode);
26377 emit_insn (gen_rtx_SET (VOIDmode, x0,
26378 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26381 e0 = gen_reg_rtx (mode);
26382 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - (d * x0) */
26384 e1 = gen_reg_rtx (mode);
26385 rs6000_emit_madd (e1, e0, e0, e0); /* e1 = (e0 * e0) + e0 */
26387 y1 = gen_reg_rtx (mode);
26388 rs6000_emit_madd (y1, e1, x0, x0); /* y1 = (e1 * x0) + x0 */
26390 u0 = gen_reg_rtx (mode);
26391 emit_insn (gen_mul (u0, n, y1)); /* u0 = n * y1 */
26393 v0 = gen_reg_rtx (mode);
26394 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - (d * u0) */
26396 rs6000_emit_madd (dst, v0, y1, u0); /* dst = (v0 * y1) + u0 */
26399 /* Newton-Raphson approximation of floating point divide that has a low
26400 precision estimate. Assumes no trapping math and finite arguments. */
26403 rs6000_emit_swdiv_low_precision (rtx dst, rtx n, rtx d)
26405 enum machine_mode mode = GET_MODE (dst);
26406 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
26407 enum insn_code code = optab_handler (smul_optab, mode);
26408 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26410 gcc_assert (code != CODE_FOR_nothing);
26412 one = rs6000_load_constant_and_splat (mode, dconst1);
26414 /* x0 = 1./d estimate */
26415 x0 = gen_reg_rtx (mode);
26416 emit_insn (gen_rtx_SET (VOIDmode, x0,
26417 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26420 e0 = gen_reg_rtx (mode);
26421 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - d * x0 */
26423 y1 = gen_reg_rtx (mode);
26424 rs6000_emit_madd (y1, e0, x0, x0); /* y1 = x0 + e0 * x0 */
26426 e1 = gen_reg_rtx (mode);
26427 emit_insn (gen_mul (e1, e0, e0)); /* e1 = e0 * e0 */
26429 y2 = gen_reg_rtx (mode);
26430 rs6000_emit_madd (y2, e1, y1, y1); /* y2 = y1 + e1 * y1 */
26432 e2 = gen_reg_rtx (mode);
26433 emit_insn (gen_mul (e2, e1, e1)); /* e2 = e1 * e1 */
26435 y3 = gen_reg_rtx (mode);
26436 rs6000_emit_madd (y3, e2, y2, y2); /* y3 = y2 + e2 * y2 */
26438 u0 = gen_reg_rtx (mode);
26439 emit_insn (gen_mul (u0, n, y3)); /* u0 = n * y3 */
26441 v0 = gen_reg_rtx (mode);
26442 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - d * u0 */
26444 rs6000_emit_madd (dst, v0, y3, u0); /* dst = u0 + v0 * y3 */
26447 /* Newton-Raphson approximation of floating point divide DST = N/D. If NOTE_P,
26448 add a reg_note saying that this was a division. Support both scalar and
26449 vector divide. Assumes no trapping math and finite arguments. */
26452 rs6000_emit_swdiv (rtx dst, rtx n, rtx d, bool note_p)
26454 enum machine_mode mode = GET_MODE (dst);
26456 if (RS6000_RECIP_HIGH_PRECISION_P (mode))
26457 rs6000_emit_swdiv_high_precision (dst, n, d);
26459 rs6000_emit_swdiv_low_precision (dst, n, d);
26462 add_reg_note (get_last_insn (), REG_EQUAL, gen_rtx_DIV (mode, n, d));
26465 /* Newton-Raphson approximation of single/double-precision floating point
26466 rsqrt. Assumes no trapping math and finite arguments. */
26469 rs6000_emit_swrsqrt (rtx dst, rtx src)
26471 enum machine_mode mode = GET_MODE (src);
26472 rtx x0 = gen_reg_rtx (mode);
26473 rtx y = gen_reg_rtx (mode);
26474 int passes = (TARGET_RECIP_PRECISION) ? 2 : 3;
26475 REAL_VALUE_TYPE dconst3_2;
26478 enum insn_code code = optab_handler (smul_optab, mode);
26479 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26481 gcc_assert (code != CODE_FOR_nothing);
26483 /* Load up the constant 1.5 either as a scalar, or as a vector. */
26484 real_from_integer (&dconst3_2, VOIDmode, 3, 0, 0);
26485 SET_REAL_EXP (&dconst3_2, REAL_EXP (&dconst3_2) - 1);
26487 halfthree = rs6000_load_constant_and_splat (mode, dconst3_2);
26489 /* x0 = rsqrt estimate */
26490 emit_insn (gen_rtx_SET (VOIDmode, x0,
26491 gen_rtx_UNSPEC (mode, gen_rtvec (1, src),
26494 /* y = 0.5 * src = 1.5 * src - src -> fewer constants */
26495 rs6000_emit_msub (y, src, halfthree, src);
26497 for (i = 0; i < passes; i++)
26499 rtx x1 = gen_reg_rtx (mode);
26500 rtx u = gen_reg_rtx (mode);
26501 rtx v = gen_reg_rtx (mode);
26503 /* x1 = x0 * (1.5 - y * (x0 * x0)) */
26504 emit_insn (gen_mul (u, x0, x0));
26505 rs6000_emit_nmsub (v, y, u, halfthree);
26506 emit_insn (gen_mul (x1, x0, v));
26510 emit_move_insn (dst, x0);
26514 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
26515 (Power7) targets. DST is the target, and SRC is the argument operand. */
26518 rs6000_emit_popcount (rtx dst, rtx src)
26520 enum machine_mode mode = GET_MODE (dst);
26523 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
26524 if (TARGET_POPCNTD)
26526 if (mode == SImode)
26527 emit_insn (gen_popcntdsi2 (dst, src));
26529 emit_insn (gen_popcntddi2 (dst, src));
26533 tmp1 = gen_reg_rtx (mode);
26535 if (mode == SImode)
26537 emit_insn (gen_popcntbsi2 (tmp1, src));
26538 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
26540 tmp2 = force_reg (SImode, tmp2);
26541 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
26545 emit_insn (gen_popcntbdi2 (tmp1, src));
26546 tmp2 = expand_mult (DImode, tmp1,
26547 GEN_INT ((HOST_WIDE_INT)
26548 0x01010101 << 32 | 0x01010101),
26550 tmp2 = force_reg (DImode, tmp2);
26551 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
26556 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
26557 target, and SRC is the argument operand. */
26560 rs6000_emit_parity (rtx dst, rtx src)
26562 enum machine_mode mode = GET_MODE (dst);
26565 tmp = gen_reg_rtx (mode);
26567 /* Use the PPC ISA 2.05 prtyw/prtyd instruction if we can. */
26570 if (mode == SImode)
26572 emit_insn (gen_popcntbsi2 (tmp, src));
26573 emit_insn (gen_paritysi2_cmpb (dst, tmp));
26577 emit_insn (gen_popcntbdi2 (tmp, src));
26578 emit_insn (gen_paritydi2_cmpb (dst, tmp));
26583 if (mode == SImode)
26585 /* Is mult+shift >= shift+xor+shift+xor? */
26586 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
26588 rtx tmp1, tmp2, tmp3, tmp4;
26590 tmp1 = gen_reg_rtx (SImode);
26591 emit_insn (gen_popcntbsi2 (tmp1, src));
26593 tmp2 = gen_reg_rtx (SImode);
26594 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
26595 tmp3 = gen_reg_rtx (SImode);
26596 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
26598 tmp4 = gen_reg_rtx (SImode);
26599 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
26600 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
26603 rs6000_emit_popcount (tmp, src);
26604 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
26608 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
26609 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
26611 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
26613 tmp1 = gen_reg_rtx (DImode);
26614 emit_insn (gen_popcntbdi2 (tmp1, src));
26616 tmp2 = gen_reg_rtx (DImode);
26617 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
26618 tmp3 = gen_reg_rtx (DImode);
26619 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
26621 tmp4 = gen_reg_rtx (DImode);
26622 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
26623 tmp5 = gen_reg_rtx (DImode);
26624 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
26626 tmp6 = gen_reg_rtx (DImode);
26627 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
26628 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
26631 rs6000_emit_popcount (tmp, src);
26632 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
26636 /* Return an RTX representing where to find the function value of a
26637 function returning MODE. */
26639 rs6000_complex_function_value (enum machine_mode mode)
26641 unsigned int regno;
26643 enum machine_mode inner = GET_MODE_INNER (mode);
26644 unsigned int inner_bytes = GET_MODE_SIZE (inner);
26646 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26647 regno = FP_ARG_RETURN;
26650 regno = GP_ARG_RETURN;
26652 /* 32-bit is OK since it'll go in r3/r4. */
26653 if (TARGET_32BIT && inner_bytes >= 4)
26654 return gen_rtx_REG (mode, regno);
26657 if (inner_bytes >= 8)
26658 return gen_rtx_REG (mode, regno);
26660 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
26662 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
26663 GEN_INT (inner_bytes));
26664 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
26667 /* Target hook for TARGET_FUNCTION_VALUE.
26669 On the SPE, both FPs and vectors are returned in r3.
26671 On RS/6000 an integer value is in r3 and a floating-point value is in
26672 fp1, unless -msoft-float. */
26675 rs6000_function_value (const_tree valtype,
26676 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
26677 bool outgoing ATTRIBUTE_UNUSED)
26679 enum machine_mode mode;
26680 unsigned int regno;
26682 /* Special handling for structs in darwin64. */
26684 && rs6000_darwin64_struct_check_p (TYPE_MODE (valtype), valtype))
26686 CUMULATIVE_ARGS valcum;
26690 valcum.fregno = FP_ARG_MIN_REG;
26691 valcum.vregno = ALTIVEC_ARG_MIN_REG;
26692 /* Do a trial code generation as if this were going to be passed as
26693 an argument; if any part goes in memory, we return NULL. */
26694 valret = rs6000_darwin64_record_arg (&valcum, valtype, true, /* retval= */ true);
26697 /* Otherwise fall through to standard ABI rules. */
26700 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
26702 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26703 return gen_rtx_PARALLEL (DImode,
26705 gen_rtx_EXPR_LIST (VOIDmode,
26706 gen_rtx_REG (SImode, GP_ARG_RETURN),
26708 gen_rtx_EXPR_LIST (VOIDmode,
26709 gen_rtx_REG (SImode,
26710 GP_ARG_RETURN + 1),
26713 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
26715 return gen_rtx_PARALLEL (DCmode,
26717 gen_rtx_EXPR_LIST (VOIDmode,
26718 gen_rtx_REG (SImode, GP_ARG_RETURN),
26720 gen_rtx_EXPR_LIST (VOIDmode,
26721 gen_rtx_REG (SImode,
26722 GP_ARG_RETURN + 1),
26724 gen_rtx_EXPR_LIST (VOIDmode,
26725 gen_rtx_REG (SImode,
26726 GP_ARG_RETURN + 2),
26728 gen_rtx_EXPR_LIST (VOIDmode,
26729 gen_rtx_REG (SImode,
26730 GP_ARG_RETURN + 3),
26734 mode = TYPE_MODE (valtype);
26735 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
26736 || POINTER_TYPE_P (valtype))
26737 mode = TARGET_32BIT ? SImode : DImode;
26739 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26740 /* _Decimal128 must use an even/odd register pair. */
26741 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26742 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
26743 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
26744 regno = FP_ARG_RETURN;
26745 else if (TREE_CODE (valtype) == COMPLEX_TYPE
26746 && targetm.calls.split_complex_arg)
26747 return rs6000_complex_function_value (mode);
26748 /* VSX is a superset of Altivec and adds V2DImode/V2DFmode. Since the same
26749 return register is used in both cases, and we won't see V2DImode/V2DFmode
26750 for pure altivec, combine the two cases. */
26751 else if (TREE_CODE (valtype) == VECTOR_TYPE
26752 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
26753 && ALTIVEC_OR_VSX_VECTOR_MODE (mode))
26754 regno = ALTIVEC_ARG_RETURN;
26755 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26756 && (mode == DFmode || mode == DCmode
26757 || mode == TFmode || mode == TCmode))
26758 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26760 regno = GP_ARG_RETURN;
26762 return gen_rtx_REG (mode, regno);
26765 /* Define how to find the value returned by a library function
26766 assuming the value has mode MODE. */
26768 rs6000_libcall_value (enum machine_mode mode)
26770 unsigned int regno;
26772 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
26774 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26775 return gen_rtx_PARALLEL (DImode,
26777 gen_rtx_EXPR_LIST (VOIDmode,
26778 gen_rtx_REG (SImode, GP_ARG_RETURN),
26780 gen_rtx_EXPR_LIST (VOIDmode,
26781 gen_rtx_REG (SImode,
26782 GP_ARG_RETURN + 1),
26786 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26787 /* _Decimal128 must use an even/odd register pair. */
26788 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26789 else if (SCALAR_FLOAT_MODE_P (mode)
26790 && TARGET_HARD_FLOAT && TARGET_FPRS
26791 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
26792 regno = FP_ARG_RETURN;
26793 /* VSX is a superset of Altivec and adds V2DImode/V2DFmode. Since the same
26794 return register is used in both cases, and we won't see V2DImode/V2DFmode
26795 for pure altivec, combine the two cases. */
26796 else if (ALTIVEC_OR_VSX_VECTOR_MODE (mode)
26797 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
26798 regno = ALTIVEC_ARG_RETURN;
26799 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
26800 return rs6000_complex_function_value (mode);
26801 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26802 && (mode == DFmode || mode == DCmode
26803 || mode == TFmode || mode == TCmode))
26804 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26806 regno = GP_ARG_RETURN;
26808 return gen_rtx_REG (mode, regno);
26812 /* Given FROM and TO register numbers, say whether this elimination is allowed.
26813 Frame pointer elimination is automatically handled.
26815 For the RS/6000, if frame pointer elimination is being done, we would like
26816 to convert ap into fp, not sp.
26818 We need r30 if -mminimal-toc was specified, and there are constant pool
26822 rs6000_can_eliminate (const int from, const int to)
26824 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
26825 ? ! frame_pointer_needed
26826 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
26827 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
26831 /* Define the offset between two registers, FROM to be eliminated and its
26832 replacement TO, at the start of a routine. */
26834 rs6000_initial_elimination_offset (int from, int to)
26836 rs6000_stack_t *info = rs6000_stack_info ();
26837 HOST_WIDE_INT offset;
26839 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26840 offset = info->push_p ? 0 : -info->total_size;
26841 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26843 offset = info->push_p ? 0 : -info->total_size;
26844 if (FRAME_GROWS_DOWNWARD)
26845 offset += info->fixed_size + info->vars_size + info->parm_size;
26847 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26848 offset = FRAME_GROWS_DOWNWARD
26849 ? info->fixed_size + info->vars_size + info->parm_size
26851 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26852 offset = info->total_size;
26853 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26854 offset = info->push_p ? info->total_size : 0;
26855 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
26858 gcc_unreachable ();
26864 rs6000_dwarf_register_span (rtx reg)
26868 unsigned regno = REGNO (reg);
26869 enum machine_mode mode = GET_MODE (reg);
26873 && (SPE_VECTOR_MODE (GET_MODE (reg))
26874 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
26875 && mode != SFmode && mode != SDmode && mode != SCmode)))
26880 regno = REGNO (reg);
26882 /* The duality of the SPE register size wreaks all kinds of havoc.
26883 This is a way of distinguishing r0 in 32-bits from r0 in
26885 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
26886 gcc_assert (words <= 4);
26887 for (i = 0; i < words; i++, regno++)
26889 if (BYTES_BIG_ENDIAN)
26891 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
26892 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
26896 parts[2 * i] = gen_rtx_REG (SImode, regno);
26897 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
26901 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
26904 /* Fill in sizes for SPE register high parts in table used by unwinder. */
26907 rs6000_init_dwarf_reg_sizes_extra (tree address)
26912 enum machine_mode mode = TYPE_MODE (char_type_node);
26913 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
26914 rtx mem = gen_rtx_MEM (BLKmode, addr);
26915 rtx value = gen_int_mode (4, mode);
26917 for (i = 1201; i < 1232; i++)
26919 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
26920 HOST_WIDE_INT offset
26921 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
26923 emit_move_insn (adjust_address (mem, mode, offset), value);
26928 /* Map internal gcc register numbers to DWARF2 register numbers. */
26931 rs6000_dbx_register_number (unsigned int regno)
26933 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
26935 if (regno == MQ_REGNO)
26937 if (regno == LR_REGNO)
26939 if (regno == CTR_REGNO)
26941 if (CR_REGNO_P (regno))
26942 return regno - CR0_REGNO + 86;
26943 if (regno == CA_REGNO)
26944 return 101; /* XER */
26945 if (ALTIVEC_REGNO_P (regno))
26946 return regno - FIRST_ALTIVEC_REGNO + 1124;
26947 if (regno == VRSAVE_REGNO)
26949 if (regno == VSCR_REGNO)
26951 if (regno == SPE_ACC_REGNO)
26953 if (regno == SPEFSCR_REGNO)
26955 /* SPE high reg number. We get these values of regno from
26956 rs6000_dwarf_register_span. */
26957 gcc_assert (regno >= 1200 && regno < 1232);
26961 /* target hook eh_return_filter_mode */
26962 static enum machine_mode
26963 rs6000_eh_return_filter_mode (void)
26965 return TARGET_32BIT ? SImode : word_mode;
26968 /* Target hook for scalar_mode_supported_p. */
26970 rs6000_scalar_mode_supported_p (enum machine_mode mode)
26972 if (DECIMAL_FLOAT_MODE_P (mode))
26973 return default_decimal_float_supported_p ();
26975 return default_scalar_mode_supported_p (mode);
26978 /* Target hook for vector_mode_supported_p. */
26980 rs6000_vector_mode_supported_p (enum machine_mode mode)
26983 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
26986 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
26989 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
26996 /* Target hook for invalid_arg_for_unprototyped_fn. */
26997 static const char *
26998 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
27000 return (!rs6000_darwin64_abi
27002 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
27003 && (funcdecl == NULL_TREE
27004 || (TREE_CODE (funcdecl) == FUNCTION_DECL
27005 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
27006 ? N_("AltiVec argument passed to unprototyped function")
27010 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
27011 setup by using __stack_chk_fail_local hidden function instead of
27012 calling __stack_chk_fail directly. Otherwise it is better to call
27013 __stack_chk_fail directly. */
27015 static tree ATTRIBUTE_UNUSED
27016 rs6000_stack_protect_fail (void)
27018 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
27019 ? default_hidden_stack_protect_fail ()
27020 : default_external_stack_protect_fail ();
27024 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
27025 int num_operands ATTRIBUTE_UNUSED)
27027 if (rs6000_warn_cell_microcode)
27030 int insn_code_number = recog_memoized (insn);
27031 location_t location = locator_location (INSN_LOCATOR (insn));
27033 /* Punt on insns we cannot recognize. */
27034 if (insn_code_number < 0)
27037 temp = get_insn_template (insn_code_number, insn);
27039 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
27040 warning_at (location, OPT_mwarn_cell_microcode,
27041 "emitting microcode insn %s\t[%s] #%d",
27042 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27043 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
27044 warning_at (location, OPT_mwarn_cell_microcode,
27045 "emitting conditional microcode insn %s\t[%s] #%d",
27046 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27051 /* Mask options that we want to support inside of attribute((target)) and
27052 #pragma GCC target operations. Note, we do not include things like
27053 64/32-bit, endianess, hard/soft floating point, etc. that would have
27054 different calling sequences. */
27056 struct rs6000_opt_mask {
27057 const char *name; /* option name */
27058 int mask; /* mask to set */
27059 bool invert; /* invert sense of mask */
27060 bool valid_target; /* option is a target option */
27063 static struct rs6000_opt_mask const rs6000_opt_masks[] =
27065 { "altivec", MASK_ALTIVEC, false, true },
27066 { "cmpb", MASK_CMPB, false, true },
27067 { "dlmzb", MASK_DLMZB, false, true },
27068 { "fprnd", MASK_FPRND, false, true },
27069 { "hard-dfp", MASK_DFP, false, true },
27070 { "isel", MASK_ISEL, false, true },
27071 { "mfcrf", MASK_MFCRF, false, true },
27072 { "mfpgpr", MASK_MFPGPR, false, true },
27073 { "mulhw", MASK_MULHW, false, true },
27074 { "multiple", MASK_MULTIPLE, false, true },
27075 { "update", MASK_NO_UPDATE, true , true },
27076 { "popcntb", MASK_POPCNTB, false, true },
27077 { "popcntd", MASK_POPCNTD, false, true },
27078 { "powerpc-gfxopt", MASK_PPC_GFXOPT, false, true },
27079 { "powerpc-gpopt", MASK_PPC_GPOPT, false, true },
27080 { "recip-precision", MASK_RECIP_PRECISION, false, true },
27081 { "string", MASK_STRING, false, true },
27082 { "vsx", MASK_VSX, false, true },
27085 { "aix64", MASK_64BIT, false, false },
27086 { "aix32", MASK_64BIT, true, false },
27088 { "64", MASK_64BIT, false, false },
27089 { "32", MASK_64BIT, true, false },
27093 { "eabi", MASK_EABI, false, false },
27095 #ifdef MASK_LITTLE_ENDIAN
27096 { "little", MASK_LITTLE_ENDIAN, false, false },
27097 { "big", MASK_LITTLE_ENDIAN, true, false },
27099 #ifdef MASK_RELOCATABLE
27100 { "relocatable", MASK_RELOCATABLE, false, false },
27102 #ifdef MASK_STRICT_ALIGN
27103 { "strict-align", MASK_STRICT_ALIGN, false, false },
27105 { "power", MASK_POWER, false, false },
27106 { "power2", MASK_POWER2, false, false },
27107 { "powerpc", MASK_POWERPC, false, false },
27108 { "soft-float", MASK_SOFT_FLOAT, false, false },
27109 { "string", MASK_STRING, false, false },
27112 /* Option variables that we want to support inside attribute((target)) and
27113 #pragma GCC target operations. */
27115 struct rs6000_opt_var {
27116 const char *name; /* option name */
27117 size_t global_offset; /* offset of the option in global_options. */
27118 size_t target_offset; /* offset of the option in target optiosn. */
27121 static struct rs6000_opt_var const rs6000_opt_vars[] =
27124 offsetof (struct gcc_options, x_TARGET_FRIZ),
27125 offsetof (struct cl_target_option, x_TARGET_FRIZ), },
27126 { "avoid-indexed-addresses",
27127 offsetof (struct gcc_options, x_TARGET_AVOID_XFORM),
27128 offsetof (struct cl_target_option, x_TARGET_AVOID_XFORM) },
27130 offsetof (struct gcc_options, x_rs6000_paired_float),
27131 offsetof (struct cl_target_option, x_rs6000_paired_float), },
27133 offsetof (struct gcc_options, x_rs6000_default_long_calls),
27134 offsetof (struct cl_target_option, x_rs6000_default_long_calls), },
27137 /* Inner function to handle attribute((target("..."))) and #pragma GCC target
27138 parsing. Return true if there were no errors. */
27141 rs6000_inner_target_options (tree args, bool attr_p)
27145 if (args == NULL_TREE)
27148 else if (TREE_CODE (args) == STRING_CST)
27150 char *p = ASTRDUP (TREE_STRING_POINTER (args));
27153 while ((q = strtok (p, ",")) != NULL)
27155 bool error_p = false;
27156 bool not_valid_p = false;
27157 const char *cpu_opt = NULL;
27160 if (strncmp (q, "cpu=", 4) == 0)
27162 int cpu_index = rs6000_cpu_name_lookup (q+4);
27163 if (cpu_index >= 0)
27164 rs6000_cpu_index = cpu_index;
27171 else if (strncmp (q, "tune=", 5) == 0)
27173 int tune_index = rs6000_cpu_name_lookup (q+5);
27174 if (tune_index >= 0)
27175 rs6000_tune_index = tune_index;
27185 bool invert = false;
27189 if (strncmp (r, "no-", 3) == 0)
27195 for (i = 0; i < ARRAY_SIZE (rs6000_opt_masks); i++)
27196 if (strcmp (r, rs6000_opt_masks[i].name) == 0)
27198 int mask = rs6000_opt_masks[i].mask;
27200 if (!rs6000_opt_masks[i].valid_target)
27201 not_valid_p = true;
27205 target_flags_explicit |= mask;
27207 if (rs6000_opt_masks[i].invert)
27211 target_flags &= ~mask;
27213 target_flags |= mask;
27218 if (error_p && !not_valid_p)
27220 for (i = 0; i < ARRAY_SIZE (rs6000_opt_vars); i++)
27221 if (strcmp (r, rs6000_opt_vars[i].name) == 0)
27223 size_t j = rs6000_opt_vars[i].global_offset;
27224 ((int *) &global_options)[j] = !invert;
27233 const char *eprefix, *esuffix;
27238 eprefix = "__attribute__((__target__(";
27243 eprefix = "#pragma GCC target ";
27248 error ("invalid cpu \"%s\" for %s\"%s\"%s", cpu_opt, eprefix,
27250 else if (not_valid_p)
27251 error ("%s\"%s\"%s is not allowed", eprefix, q, esuffix);
27253 error ("%s\"%s\"%s is invalid", eprefix, q, esuffix);
27258 else if (TREE_CODE (args) == TREE_LIST)
27262 tree value = TREE_VALUE (args);
27265 bool ret2 = rs6000_inner_target_options (value, attr_p);
27269 args = TREE_CHAIN (args);
27271 while (args != NULL_TREE);
27275 gcc_unreachable ();
27280 /* Print out the target options as a list for -mdebug=target. */
27283 rs6000_debug_target_options (tree args, const char *prefix)
27285 if (args == NULL_TREE)
27286 fprintf (stderr, "%s<NULL>", prefix);
27288 else if (TREE_CODE (args) == STRING_CST)
27290 char *p = ASTRDUP (TREE_STRING_POINTER (args));
27293 while ((q = strtok (p, ",")) != NULL)
27296 fprintf (stderr, "%s\"%s\"", prefix, q);
27301 else if (TREE_CODE (args) == TREE_LIST)
27305 tree value = TREE_VALUE (args);
27308 rs6000_debug_target_options (value, prefix);
27311 args = TREE_CHAIN (args);
27313 while (args != NULL_TREE);
27317 gcc_unreachable ();
27323 /* Hook to validate attribute((target("..."))). */
27326 rs6000_valid_attribute_p (tree fndecl,
27327 tree ARG_UNUSED (name),
27331 struct cl_target_option cur_target;
27333 tree old_optimize = build_optimization_node ();
27334 tree new_target, new_optimize;
27335 tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
27337 gcc_assert ((fndecl != NULL_TREE) && (args != NULL_TREE));
27339 if (TARGET_DEBUG_TARGET)
27341 tree tname = DECL_NAME (fndecl);
27342 fprintf (stderr, "\n==================== rs6000_valid_attribute_p:\n");
27344 fprintf (stderr, "function: %.*s\n",
27345 (int) IDENTIFIER_LENGTH (tname),
27346 IDENTIFIER_POINTER (tname));
27348 fprintf (stderr, "function: unknown\n");
27350 fprintf (stderr, "args:");
27351 rs6000_debug_target_options (args, " ");
27352 fprintf (stderr, "\n");
27355 fprintf (stderr, "flags: 0x%x\n", flags);
27357 fprintf (stderr, "--------------------\n");
27360 old_optimize = build_optimization_node ();
27361 func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
27363 /* If the function changed the optimization levels as well as setting target
27364 options, start with the optimizations specified. */
27365 if (func_optimize && func_optimize != old_optimize)
27366 cl_optimization_restore (&global_options,
27367 TREE_OPTIMIZATION (func_optimize));
27369 /* The target attributes may also change some optimization flags, so update
27370 the optimization options if necessary. */
27371 cl_target_option_save (&cur_target, &global_options);
27372 rs6000_cpu_index = rs6000_tune_index = -1;
27373 ret = rs6000_inner_target_options (args, true);
27375 /* Set up any additional state. */
27378 ret = rs6000_option_override_internal (false);
27379 new_target = build_target_option_node ();
27384 new_optimize = build_optimization_node ();
27391 DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target;
27393 if (old_optimize != new_optimize)
27394 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
27397 cl_target_option_restore (&global_options, &cur_target);
27399 if (old_optimize != new_optimize)
27400 cl_optimization_restore (&global_options,
27401 TREE_OPTIMIZATION (old_optimize));
27407 /* Hook to validate the current #pragma GCC target and set the state, and
27408 update the macros based on what was changed. If ARGS is NULL, then
27409 POP_TARGET is used to reset the options. */
27412 rs6000_pragma_target_parse (tree args, tree pop_target)
27417 if (TARGET_DEBUG_TARGET)
27419 fprintf (stderr, "\n==================== rs6000_pragma_target_parse\n");
27420 fprintf (stderr, "args:");
27421 rs6000_debug_target_options (args, " ");
27422 fprintf (stderr, "\n");
27426 fprintf (stderr, "pop_target:\n");
27427 debug_tree (pop_target);
27430 fprintf (stderr, "pop_target: <NULL>\n");
27432 fprintf (stderr, "--------------------\n");
27438 cur_tree = ((pop_target)
27440 : target_option_default_node);
27441 cl_target_option_restore (&global_options,
27442 TREE_TARGET_OPTION (cur_tree));
27446 rs6000_cpu_index = rs6000_tune_index = -1;
27447 ret = rs6000_inner_target_options (args, false);
27448 cur_tree = build_target_option_node ();
27455 target_option_current_node = cur_tree;
27461 /* Remember the last target of rs6000_set_current_function. */
27462 static GTY(()) tree rs6000_previous_fndecl;
27464 /* Establish appropriate back-end context for processing the function
27465 FNDECL. The argument might be NULL to indicate processing at top
27466 level, outside of any function scope. */
27468 rs6000_set_current_function (tree fndecl)
27470 tree old_tree = (rs6000_previous_fndecl
27471 ? DECL_FUNCTION_SPECIFIC_TARGET (rs6000_previous_fndecl)
27474 tree new_tree = (fndecl
27475 ? DECL_FUNCTION_SPECIFIC_TARGET (fndecl)
27478 if (TARGET_DEBUG_TARGET)
27480 bool print_final = false;
27481 fprintf (stderr, "\n==================== rs6000_set_current_function");
27484 fprintf (stderr, ", fndecl %s (%p)",
27485 (DECL_NAME (fndecl)
27486 ? IDENTIFIER_POINTER (DECL_NAME (fndecl))
27487 : "<unknown>"), (void *)fndecl);
27489 if (rs6000_previous_fndecl)
27490 fprintf (stderr, ", prev_fndecl (%p)", (void *)rs6000_previous_fndecl);
27492 fprintf (stderr, "\n");
27495 fprintf (stderr, "\nnew fndecl target specific options:\n");
27496 debug_tree (new_tree);
27497 print_final = true;
27502 fprintf (stderr, "\nold fndecl target specific options:\n");
27503 debug_tree (old_tree);
27504 print_final = true;
27508 fprintf (stderr, "--------------------\n");
27511 /* Only change the context if the function changes. This hook is called
27512 several times in the course of compiling a function, and we don't want to
27513 slow things down too much or call target_reinit when it isn't safe. */
27514 if (fndecl && fndecl != rs6000_previous_fndecl)
27516 rs6000_previous_fndecl = fndecl;
27517 if (old_tree == new_tree)
27522 cl_target_option_restore (&global_options,
27523 TREE_TARGET_OPTION (new_tree));
27529 struct cl_target_option *def
27530 = TREE_TARGET_OPTION (target_option_current_node);
27532 cl_target_option_restore (&global_options, def);
27539 /* Save the current options */
27542 rs6000_function_specific_save (struct cl_target_option *ptr)
27544 ptr->rs6000_target_flags_explicit = target_flags_explicit;
27547 /* Restore the current options */
27550 rs6000_function_specific_restore (struct cl_target_option *ptr)
27552 target_flags_explicit = ptr->rs6000_target_flags_explicit;
27553 (void) rs6000_option_override_internal (false);
27556 /* Print the current options */
27559 rs6000_function_specific_print (FILE *file, int indent,
27560 struct cl_target_option *ptr)
27563 int flags = ptr->x_target_flags;
27565 /* Print the various mask options. */
27566 for (i = 0; i < ARRAY_SIZE (rs6000_opt_masks); i++)
27567 if ((flags & rs6000_opt_masks[i].mask) != 0)
27569 flags &= ~ rs6000_opt_masks[i].mask;
27570 fprintf (file, "%*s-m%s%s\n", indent, "",
27571 rs6000_opt_masks[i].invert ? "no-" : "",
27572 rs6000_opt_masks[i].name);
27575 /* Print the various options that are variables. */
27576 for (i = 0; i < ARRAY_SIZE (rs6000_opt_vars); i++)
27578 size_t j = rs6000_opt_vars[i].target_offset;
27579 if (((signed char *) ptr)[j])
27580 fprintf (file, "%*s-m%s\n", indent, "",
27581 rs6000_opt_vars[i].name);
27586 /* Hook to determine if one function can safely inline another. */
27589 rs6000_can_inline_p (tree caller, tree callee)
27592 tree caller_tree = DECL_FUNCTION_SPECIFIC_TARGET (caller);
27593 tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (callee);
27595 /* If callee has no option attributes, then it is ok to inline. */
27599 /* If caller has no option attributes, but callee does then it is not ok to
27601 else if (!caller_tree)
27606 struct cl_target_option *caller_opts = TREE_TARGET_OPTION (caller_tree);
27607 struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree);
27609 /* Callee's options should a subset of the caller's, i.e. a vsx function
27610 can inline an altivec function but a non-vsx function can't inline a
27612 if ((caller_opts->x_target_flags & callee_opts->x_target_flags)
27613 == callee_opts->x_target_flags)
27617 if (TARGET_DEBUG_TARGET)
27618 fprintf (stderr, "rs6000_can_inline_p:, caller %s, callee %s, %s inline\n",
27619 (DECL_NAME (caller)
27620 ? IDENTIFIER_POINTER (DECL_NAME (caller))
27622 (DECL_NAME (callee)
27623 ? IDENTIFIER_POINTER (DECL_NAME (callee))
27625 (ret ? "can" : "cannot"));
27630 /* Allocate a stack temp and fixup the address so it meets the particular
27631 memory requirements (either offetable or REG+REG addressing). */
27634 rs6000_allocate_stack_temp (enum machine_mode mode,
27635 bool offsettable_p,
27638 rtx stack = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
27639 rtx addr = XEXP (stack, 0);
27640 int strict_p = (reload_in_progress || reload_completed);
27642 if (!legitimate_indirect_address_p (addr, strict_p))
27645 && !rs6000_legitimate_offset_address_p (mode, addr, strict_p))
27646 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
27648 else if (reg_reg_p && !legitimate_indexed_address_p (addr, strict_p))
27649 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
27655 /* Given a memory reference, if it is not a reg or reg+reg addressing, convert
27656 to such a form to deal with memory reference instructions like STFIWX that
27657 only take reg+reg addressing. */
27660 rs6000_address_for_fpconvert (rtx x)
27662 int strict_p = (reload_in_progress || reload_completed);
27665 gcc_assert (MEM_P (x));
27666 addr = XEXP (x, 0);
27667 if (! legitimate_indirect_address_p (addr, strict_p)
27668 && ! legitimate_indexed_address_p (addr, strict_p))
27670 if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)
27672 rtx reg = XEXP (addr, 0);
27673 HOST_WIDE_INT size = GET_MODE_SIZE (GET_MODE (x));
27674 rtx size_rtx = GEN_INT ((GET_CODE (addr) == PRE_DEC) ? -size : size);
27675 gcc_assert (REG_P (reg));
27676 emit_insn (gen_add3_insn (reg, reg, size_rtx));
27679 else if (GET_CODE (addr) == PRE_MODIFY)
27681 rtx reg = XEXP (addr, 0);
27682 rtx expr = XEXP (addr, 1);
27683 gcc_assert (REG_P (reg));
27684 gcc_assert (GET_CODE (expr) == PLUS);
27685 emit_insn (gen_add3_insn (reg, XEXP (expr, 0), XEXP (expr, 1)));
27689 x = replace_equiv_address (x, copy_addr_to_reg (addr));
27695 /* Given a memory reference, if it is not in the form for altivec memory
27696 reference instructions (i.e. reg or reg+reg addressing with AND of -16),
27697 convert to the altivec format. */
27700 rs6000_address_for_altivec (rtx x)
27702 gcc_assert (MEM_P (x));
27703 if (!altivec_indexed_or_indirect_operand (x, GET_MODE (x)))
27705 rtx addr = XEXP (x, 0);
27706 int strict_p = (reload_in_progress || reload_completed);
27708 if (!legitimate_indexed_address_p (addr, strict_p)
27709 && !legitimate_indirect_address_p (addr, strict_p))
27710 addr = copy_to_mode_reg (Pmode, addr);
27712 addr = gen_rtx_AND (Pmode, addr, GEN_INT (-16));
27713 x = change_address (x, GET_MODE (x), addr);
27719 /* Implement TARGET_LEGITIMATE_CONSTANT_P.
27721 On the RS/6000, all integer constants are acceptable, most won't be valid
27722 for particular insns, though. Only easy FP constants are acceptable. */
27725 rs6000_legitimate_constant_p (enum machine_mode mode, rtx x)
27727 if (rs6000_tls_referenced_p (x))
27730 return ((GET_CODE (x) != CONST_DOUBLE && GET_CODE (x) != CONST_VECTOR)
27731 || GET_MODE (x) == VOIDmode
27732 || (TARGET_POWERPC64 && mode == DImode)
27733 || easy_fp_constant (x, mode)
27734 || easy_vector_constant (x, mode));
27738 /* A function pointer under AIX is a pointer to a data area whose first word
27739 contains the actual address of the function, whose second word contains a
27740 pointer to its TOC, and whose third word contains a value to place in the
27741 static chain register (r11). Note that if we load the static chain, our
27742 "trampoline" need not have any executable code. */
27745 rs6000_call_indirect_aix (rtx value, rtx func_desc, rtx flag)
27751 rtx stack_toc_offset;
27753 rtx func_toc_offset;
27755 rtx func_sc_offset;
27758 rtx (*call_func) (rtx, rtx, rtx, rtx);
27759 rtx (*call_value_func) (rtx, rtx, rtx, rtx, rtx);
27761 stack_ptr = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
27762 toc_reg = gen_rtx_REG (Pmode, TOC_REGNUM);
27764 /* Load up address of the actual function. */
27765 func_desc = force_reg (Pmode, func_desc);
27766 func_addr = gen_reg_rtx (Pmode);
27767 emit_move_insn (func_addr, gen_rtx_MEM (Pmode, func_desc));
27772 stack_toc_offset = GEN_INT (TOC_SAVE_OFFSET_32BIT);
27773 func_toc_offset = GEN_INT (AIX_FUNC_DESC_TOC_32BIT);
27774 func_sc_offset = GEN_INT (AIX_FUNC_DESC_SC_32BIT);
27775 if (TARGET_POINTERS_TO_NESTED_FUNCTIONS)
27777 call_func = gen_call_indirect_aix32bit;
27778 call_value_func = gen_call_value_indirect_aix32bit;
27782 call_func = gen_call_indirect_aix32bit_nor11;
27783 call_value_func = gen_call_value_indirect_aix32bit_nor11;
27788 stack_toc_offset = GEN_INT (TOC_SAVE_OFFSET_64BIT);
27789 func_toc_offset = GEN_INT (AIX_FUNC_DESC_TOC_64BIT);
27790 func_sc_offset = GEN_INT (AIX_FUNC_DESC_SC_64BIT);
27791 if (TARGET_POINTERS_TO_NESTED_FUNCTIONS)
27793 call_func = gen_call_indirect_aix64bit;
27794 call_value_func = gen_call_value_indirect_aix64bit;
27798 call_func = gen_call_indirect_aix64bit_nor11;
27799 call_value_func = gen_call_value_indirect_aix64bit_nor11;
27803 /* Reserved spot to store the TOC. */
27804 stack_toc_mem = gen_frame_mem (Pmode,
27805 gen_rtx_PLUS (Pmode,
27807 stack_toc_offset));
27810 gcc_assert (cfun->machine);
27812 /* Can we optimize saving the TOC in the prologue or do we need to do it at
27814 if (TARGET_SAVE_TOC_INDIRECT && !cfun->calls_alloca)
27815 cfun->machine->save_toc_in_prologue = true;
27819 MEM_VOLATILE_P (stack_toc_mem) = 1;
27820 emit_move_insn (stack_toc_mem, toc_reg);
27823 /* Calculate the address to load the TOC of the called function. We don't
27824 actually load this until the split after reload. */
27825 func_toc_mem = gen_rtx_MEM (Pmode,
27826 gen_rtx_PLUS (Pmode,
27830 /* If we have a static chain, load it up. */
27831 if (TARGET_POINTERS_TO_NESTED_FUNCTIONS)
27833 func_sc_mem = gen_rtx_MEM (Pmode,
27834 gen_rtx_PLUS (Pmode,
27838 sc_reg = gen_rtx_REG (Pmode, STATIC_CHAIN_REGNUM);
27839 emit_move_insn (sc_reg, func_sc_mem);
27842 /* Create the call. */
27844 insn = call_value_func (value, func_addr, flag, func_toc_mem,
27847 insn = call_func (func_addr, flag, func_toc_mem, stack_toc_mem);
27849 emit_call_insn (insn);
27852 /* Return whether we need to always update the saved TOC pointer when we update
27853 the stack pointer. */
27856 rs6000_save_toc_in_prologue_p (void)
27858 return (cfun && cfun->machine && cfun->machine->save_toc_in_prologue);
27861 #include "gt-rs6000.h"