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, int *, bool);
952 static bool rs6000_debug_rtx_costs (rtx, int, 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 (!(CONST_INT_P (x)
4507 || GET_CODE (x) == CONST_DOUBLE
4508 || GET_CODE (x) == CONST_FIXED))
4513 /* Load from constant pool. */
4514 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
4520 /* The vector is initialized only with non-constants. */
4521 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
4522 XVECEXP (vals, 0, 1));
4524 emit_move_insn (target, new_rtx);
4528 /* One field is non-constant and the other one is a constant. Load the
4529 constant from the constant pool and use ps_merge instruction to
4530 construct the whole vector. */
4531 op1 = XVECEXP (vals, 0, 0);
4532 op2 = XVECEXP (vals, 0, 1);
4534 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
4536 tmp = gen_reg_rtx (GET_MODE (constant_op));
4537 emit_move_insn (tmp, constant_op);
4539 if (CONSTANT_P (op1))
4540 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
4542 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
4544 emit_move_insn (target, new_rtx);
4548 paired_expand_vector_move (rtx operands[])
4550 rtx op0 = operands[0], op1 = operands[1];
4552 emit_move_insn (op0, op1);
4555 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
4556 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
4557 operands for the relation operation COND. This is a recursive
4561 paired_emit_vector_compare (enum rtx_code rcode,
4562 rtx dest, rtx op0, rtx op1,
4563 rtx cc_op0, rtx cc_op1)
4565 rtx tmp = gen_reg_rtx (V2SFmode);
4568 gcc_assert (TARGET_PAIRED_FLOAT);
4569 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
4575 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4579 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4580 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
4584 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
4587 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4590 tmp1 = gen_reg_rtx (V2SFmode);
4591 max = gen_reg_rtx (V2SFmode);
4592 min = gen_reg_rtx (V2SFmode);
4593 gen_reg_rtx (V2SFmode);
4595 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4596 emit_insn (gen_selv2sf4
4597 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4598 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
4599 emit_insn (gen_selv2sf4
4600 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4601 emit_insn (gen_subv2sf3 (tmp1, min, max));
4602 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
4605 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
4608 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4611 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
4614 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4617 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
4626 /* Emit vector conditional expression.
4627 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
4628 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
4631 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
4632 rtx cond, rtx cc_op0, rtx cc_op1)
4634 enum rtx_code rcode = GET_CODE (cond);
4636 if (!TARGET_PAIRED_FLOAT)
4639 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
4644 /* Initialize vector TARGET to VALS. */
4647 rs6000_expand_vector_init (rtx target, rtx vals)
4649 enum machine_mode mode = GET_MODE (target);
4650 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4651 int n_elts = GET_MODE_NUNITS (mode);
4652 int n_var = 0, one_var = -1;
4653 bool all_same = true, all_const_zero = true;
4657 for (i = 0; i < n_elts; ++i)
4659 x = XVECEXP (vals, 0, i);
4660 if (!(CONST_INT_P (x)
4661 || GET_CODE (x) == CONST_DOUBLE
4662 || GET_CODE (x) == CONST_FIXED))
4663 ++n_var, one_var = i;
4664 else if (x != CONST0_RTX (inner_mode))
4665 all_const_zero = false;
4667 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
4673 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
4674 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
4675 if ((int_vector_p || TARGET_VSX) && all_const_zero)
4677 /* Zero register. */
4678 emit_insn (gen_rtx_SET (VOIDmode, target,
4679 gen_rtx_XOR (mode, target, target)));
4682 else if (int_vector_p && easy_vector_constant (const_vec, mode))
4684 /* Splat immediate. */
4685 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
4690 /* Load from constant pool. */
4691 emit_move_insn (target, const_vec);
4696 /* Double word values on VSX can use xxpermdi or lxvdsx. */
4697 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4701 rtx element = XVECEXP (vals, 0, 0);
4702 if (mode == V2DFmode)
4703 emit_insn (gen_vsx_splat_v2df (target, element));
4705 emit_insn (gen_vsx_splat_v2di (target, element));
4709 if (mode == V2DFmode)
4711 rtx op0 = copy_to_mode_reg (DFmode, XVECEXP (vals, 0, 0));
4712 rtx op1 = copy_to_mode_reg (DFmode, XVECEXP (vals, 0, 1));
4713 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
4717 rtx op0 = copy_to_mode_reg (DImode, XVECEXP (vals, 0, 0));
4718 rtx op1 = copy_to_mode_reg (DImode, XVECEXP (vals, 0, 1));
4719 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
4725 /* With single precision floating point on VSX, know that internally single
4726 precision is actually represented as a double, and either make 2 V2DF
4727 vectors, and convert these vectors to single precision, or do one
4728 conversion, and splat the result to the other elements. */
4729 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
4733 rtx freg = gen_reg_rtx (V4SFmode);
4734 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
4736 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
4737 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
4741 rtx dbl_even = gen_reg_rtx (V2DFmode);
4742 rtx dbl_odd = gen_reg_rtx (V2DFmode);
4743 rtx flt_even = gen_reg_rtx (V4SFmode);
4744 rtx flt_odd = gen_reg_rtx (V4SFmode);
4746 emit_insn (gen_vsx_concat_v2sf (dbl_even,
4747 copy_to_reg (XVECEXP (vals, 0, 0)),
4748 copy_to_reg (XVECEXP (vals, 0, 1))));
4749 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
4750 copy_to_reg (XVECEXP (vals, 0, 2)),
4751 copy_to_reg (XVECEXP (vals, 0, 3))));
4752 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
4753 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
4754 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
4759 /* Store value to stack temp. Load vector element. Splat. However, splat
4760 of 64-bit items is not supported on Altivec. */
4761 if (all_same && GET_MODE_SIZE (mode) <= 4)
4763 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4764 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
4765 XVECEXP (vals, 0, 0));
4766 x = gen_rtx_UNSPEC (VOIDmode,
4767 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4768 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4770 gen_rtx_SET (VOIDmode,
4773 x = gen_rtx_VEC_SELECT (inner_mode, target,
4774 gen_rtx_PARALLEL (VOIDmode,
4775 gen_rtvec (1, const0_rtx)));
4776 emit_insn (gen_rtx_SET (VOIDmode, target,
4777 gen_rtx_VEC_DUPLICATE (mode, x)));
4781 /* One field is non-constant. Load constant then overwrite
4785 rtx copy = copy_rtx (vals);
4787 /* Load constant part of vector, substitute neighboring value for
4789 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
4790 rs6000_expand_vector_init (target, copy);
4792 /* Insert variable. */
4793 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
4797 /* Construct the vector in memory one field at a time
4798 and load the whole vector. */
4799 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4800 for (i = 0; i < n_elts; i++)
4801 emit_move_insn (adjust_address_nv (mem, inner_mode,
4802 i * GET_MODE_SIZE (inner_mode)),
4803 XVECEXP (vals, 0, i));
4804 emit_move_insn (target, mem);
4807 /* Set field ELT of TARGET to VAL. */
4810 rs6000_expand_vector_set (rtx target, rtx val, int elt)
4812 enum machine_mode mode = GET_MODE (target);
4813 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4814 rtx reg = gen_reg_rtx (mode);
4816 int width = GET_MODE_SIZE (inner_mode);
4819 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4821 rtx (*set_func) (rtx, rtx, rtx, rtx)
4822 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
4823 emit_insn (set_func (target, target, val, GEN_INT (elt)));
4827 /* Load single variable value. */
4828 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4829 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
4830 x = gen_rtx_UNSPEC (VOIDmode,
4831 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4832 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4834 gen_rtx_SET (VOIDmode,
4838 /* Linear sequence. */
4839 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
4840 for (i = 0; i < 16; ++i)
4841 XVECEXP (mask, 0, i) = GEN_INT (i);
4843 /* Set permute mask to insert element into target. */
4844 for (i = 0; i < width; ++i)
4845 XVECEXP (mask, 0, elt*width + i)
4846 = GEN_INT (i + 0x10);
4847 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
4848 x = gen_rtx_UNSPEC (mode,
4849 gen_rtvec (3, target, reg,
4850 force_reg (V16QImode, x)),
4852 emit_insn (gen_rtx_SET (VOIDmode, target, x));
4855 /* Extract field ELT from VEC into TARGET. */
4858 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
4860 enum machine_mode mode = GET_MODE (vec);
4861 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4864 if (VECTOR_MEM_VSX_P (mode))
4871 emit_insn (gen_vsx_extract_v2df (target, vec, GEN_INT (elt)));
4874 emit_insn (gen_vsx_extract_v2di (target, vec, GEN_INT (elt)));
4877 emit_insn (gen_vsx_extract_v4sf (target, vec, GEN_INT (elt)));
4882 /* Allocate mode-sized buffer. */
4883 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4885 emit_move_insn (mem, vec);
4887 /* Add offset to field within buffer matching vector element. */
4888 mem = adjust_address_nv (mem, inner_mode, elt * GET_MODE_SIZE (inner_mode));
4890 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
4893 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
4894 implement ANDing by the mask IN. */
4896 build_mask64_2_operands (rtx in, rtx *out)
4898 #if HOST_BITS_PER_WIDE_INT >= 64
4899 unsigned HOST_WIDE_INT c, lsb, m1, m2;
4902 gcc_assert (GET_CODE (in) == CONST_INT);
4907 /* Assume c initially something like 0x00fff000000fffff. The idea
4908 is to rotate the word so that the middle ^^^^^^ group of zeros
4909 is at the MS end and can be cleared with an rldicl mask. We then
4910 rotate back and clear off the MS ^^ group of zeros with a
4912 c = ~c; /* c == 0xff000ffffff00000 */
4913 lsb = c & -c; /* lsb == 0x0000000000100000 */
4914 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
4915 c = ~c; /* c == 0x00fff000000fffff */
4916 c &= -lsb; /* c == 0x00fff00000000000 */
4917 lsb = c & -c; /* lsb == 0x0000100000000000 */
4918 c = ~c; /* c == 0xff000fffffffffff */
4919 c &= -lsb; /* c == 0xff00000000000000 */
4921 while ((lsb >>= 1) != 0)
4922 shift++; /* shift == 44 on exit from loop */
4923 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
4924 m1 = ~m1; /* m1 == 0x000000ffffffffff */
4925 m2 = ~c; /* m2 == 0x00ffffffffffffff */
4929 /* Assume c initially something like 0xff000f0000000000. The idea
4930 is to rotate the word so that the ^^^ middle group of zeros
4931 is at the LS end and can be cleared with an rldicr mask. We then
4932 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
4934 lsb = c & -c; /* lsb == 0x0000010000000000 */
4935 m2 = -lsb; /* m2 == 0xffffff0000000000 */
4936 c = ~c; /* c == 0x00fff0ffffffffff */
4937 c &= -lsb; /* c == 0x00fff00000000000 */
4938 lsb = c & -c; /* lsb == 0x0000100000000000 */
4939 c = ~c; /* c == 0xff000fffffffffff */
4940 c &= -lsb; /* c == 0xff00000000000000 */
4942 while ((lsb >>= 1) != 0)
4943 shift++; /* shift == 44 on exit from loop */
4944 m1 = ~c; /* m1 == 0x00ffffffffffffff */
4945 m1 >>= shift; /* m1 == 0x0000000000000fff */
4946 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
4949 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
4950 masks will be all 1's. We are guaranteed more than one transition. */
4951 out[0] = GEN_INT (64 - shift);
4952 out[1] = GEN_INT (m1);
4953 out[2] = GEN_INT (shift);
4954 out[3] = GEN_INT (m2);
4962 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
4965 invalid_e500_subreg (rtx op, enum machine_mode mode)
4967 if (TARGET_E500_DOUBLE)
4969 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
4970 subreg:TI and reg:TF. Decimal float modes are like integer
4971 modes (only low part of each register used) for this
4973 if (GET_CODE (op) == SUBREG
4974 && (mode == SImode || mode == DImode || mode == TImode
4975 || mode == DDmode || mode == TDmode)
4976 && REG_P (SUBREG_REG (op))
4977 && (GET_MODE (SUBREG_REG (op)) == DFmode
4978 || GET_MODE (SUBREG_REG (op)) == TFmode))
4981 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
4983 if (GET_CODE (op) == SUBREG
4984 && (mode == DFmode || mode == TFmode)
4985 && REG_P (SUBREG_REG (op))
4986 && (GET_MODE (SUBREG_REG (op)) == DImode
4987 || GET_MODE (SUBREG_REG (op)) == TImode
4988 || GET_MODE (SUBREG_REG (op)) == DDmode
4989 || GET_MODE (SUBREG_REG (op)) == TDmode))
4994 && GET_CODE (op) == SUBREG
4996 && REG_P (SUBREG_REG (op))
4997 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
5003 /* AIX increases natural record alignment to doubleword if the first
5004 field is an FP double while the FP fields remain word aligned. */
5007 rs6000_special_round_type_align (tree type, unsigned int computed,
5008 unsigned int specified)
5010 unsigned int align = MAX (computed, specified);
5011 tree field = TYPE_FIELDS (type);
5013 /* Skip all non field decls */
5014 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5015 field = DECL_CHAIN (field);
5017 if (field != NULL && field != type)
5019 type = TREE_TYPE (field);
5020 while (TREE_CODE (type) == ARRAY_TYPE)
5021 type = TREE_TYPE (type);
5023 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
5024 align = MAX (align, 64);
5030 /* Darwin increases record alignment to the natural alignment of
5034 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
5035 unsigned int specified)
5037 unsigned int align = MAX (computed, specified);
5039 if (TYPE_PACKED (type))
5042 /* Find the first field, looking down into aggregates. */
5044 tree field = TYPE_FIELDS (type);
5045 /* Skip all non field decls */
5046 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5047 field = DECL_CHAIN (field);
5050 /* A packed field does not contribute any extra alignment. */
5051 if (DECL_PACKED (field))
5053 type = TREE_TYPE (field);
5054 while (TREE_CODE (type) == ARRAY_TYPE)
5055 type = TREE_TYPE (type);
5056 } while (AGGREGATE_TYPE_P (type));
5058 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
5059 align = MAX (align, TYPE_ALIGN (type));
5064 /* Return 1 for an operand in small memory on V.4/eabi. */
5067 small_data_operand (rtx op ATTRIBUTE_UNUSED,
5068 enum machine_mode mode ATTRIBUTE_UNUSED)
5073 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
5076 if (DEFAULT_ABI != ABI_V4)
5079 /* Vector and float memory instructions have a limited offset on the
5080 SPE, so using a vector or float variable directly as an operand is
5083 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
5086 if (GET_CODE (op) == SYMBOL_REF)
5089 else if (GET_CODE (op) != CONST
5090 || GET_CODE (XEXP (op, 0)) != PLUS
5091 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
5092 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
5097 rtx sum = XEXP (op, 0);
5098 HOST_WIDE_INT summand;
5100 /* We have to be careful here, because it is the referenced address
5101 that must be 32k from _SDA_BASE_, not just the symbol. */
5102 summand = INTVAL (XEXP (sum, 1));
5103 if (summand < 0 || summand > g_switch_value)
5106 sym_ref = XEXP (sum, 0);
5109 return SYMBOL_REF_SMALL_P (sym_ref);
5115 /* Return true if either operand is a general purpose register. */
5118 gpr_or_gpr_p (rtx op0, rtx op1)
5120 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
5121 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
5125 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
5128 reg_offset_addressing_ok_p (enum machine_mode mode)
5138 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
5139 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
5147 /* Paired vector modes. Only reg+reg addressing is valid. */
5148 if (TARGET_PAIRED_FLOAT)
5160 virtual_stack_registers_memory_p (rtx op)
5164 if (GET_CODE (op) == REG)
5165 regnum = REGNO (op);
5167 else if (GET_CODE (op) == PLUS
5168 && GET_CODE (XEXP (op, 0)) == REG
5169 && GET_CODE (XEXP (op, 1)) == CONST_INT)
5170 regnum = REGNO (XEXP (op, 0));
5175 return (regnum >= FIRST_VIRTUAL_REGISTER
5176 && regnum <= LAST_VIRTUAL_POINTER_REGISTER);
5179 /* Return true if memory accesses to OP are known to never straddle
5183 offsettable_ok_by_alignment (rtx op, HOST_WIDE_INT offset,
5184 enum machine_mode mode)
5187 unsigned HOST_WIDE_INT dsize, dalign;
5189 if (GET_CODE (op) != SYMBOL_REF)
5192 decl = SYMBOL_REF_DECL (op);
5195 if (GET_MODE_SIZE (mode) == 0)
5198 /* -fsection-anchors loses the original SYMBOL_REF_DECL when
5199 replacing memory addresses with an anchor plus offset. We
5200 could find the decl by rummaging around in the block->objects
5201 VEC for the given offset but that seems like too much work. */
5203 if (SYMBOL_REF_HAS_BLOCK_INFO_P (op)
5204 && SYMBOL_REF_ANCHOR_P (op)
5205 && SYMBOL_REF_BLOCK (op) != NULL)
5207 struct object_block *block = SYMBOL_REF_BLOCK (op);
5208 HOST_WIDE_INT lsb, mask;
5210 /* Given the alignment of the block.. */
5211 dalign = block->alignment;
5212 mask = dalign / BITS_PER_UNIT - 1;
5214 /* ..and the combined offset of the anchor and any offset
5215 to this block object.. */
5216 offset += SYMBOL_REF_BLOCK_OFFSET (op);
5217 lsb = offset & -offset;
5219 /* ..find how many bits of the alignment we know for the
5224 return dalign >= GET_MODE_SIZE (mode);
5229 if (TREE_CODE (decl) == FUNCTION_DECL)
5232 if (!DECL_SIZE_UNIT (decl))
5235 if (!host_integerp (DECL_SIZE_UNIT (decl), 1))
5238 dsize = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
5242 dalign = DECL_ALIGN_UNIT (decl);
5243 return dalign >= dsize;
5246 type = TREE_TYPE (decl);
5248 if (TREE_CODE (decl) == STRING_CST)
5249 dsize = TREE_STRING_LENGTH (decl);
5250 else if (TYPE_SIZE_UNIT (type)
5251 && host_integerp (TYPE_SIZE_UNIT (type), 1))
5252 dsize = tree_low_cst (TYPE_SIZE_UNIT (type), 1);
5258 dalign = TYPE_ALIGN (type);
5259 if (CONSTANT_CLASS_P (decl))
5260 dalign = CONSTANT_ALIGNMENT (decl, dalign);
5262 dalign = DATA_ALIGNMENT (decl, dalign);
5263 dalign /= BITS_PER_UNIT;
5264 return dalign >= dsize;
5268 constant_pool_expr_p (rtx op)
5272 split_const (op, &base, &offset);
5273 return (GET_CODE (base) == SYMBOL_REF
5274 && CONSTANT_POOL_ADDRESS_P (base)
5275 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
5278 static rtx tocrel_base, tocrel_offset;
5281 toc_relative_expr_p (rtx op)
5283 if (GET_CODE (op) != CONST)
5286 split_const (op, &tocrel_base, &tocrel_offset);
5287 return (GET_CODE (tocrel_base) == UNSPEC
5288 && XINT (tocrel_base, 1) == UNSPEC_TOCREL);
5291 /* Return true if X is a constant pool address, and also for cmodel=medium
5292 if X is a toc-relative address known to be offsettable within MODE. */
5295 legitimate_constant_pool_address_p (const_rtx x, enum machine_mode mode,
5299 && (GET_CODE (x) == PLUS || GET_CODE (x) == LO_SUM)
5300 && GET_CODE (XEXP (x, 0)) == REG
5301 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5302 || ((TARGET_MINIMAL_TOC
5303 || TARGET_CMODEL != CMODEL_SMALL)
5304 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict)))
5305 && toc_relative_expr_p (XEXP (x, 1))
5306 && (TARGET_CMODEL != CMODEL_MEDIUM
5307 || constant_pool_expr_p (XVECEXP (tocrel_base, 0, 0))
5309 || offsettable_ok_by_alignment (XVECEXP (tocrel_base, 0, 0),
5310 INTVAL (tocrel_offset), mode)));
5314 legitimate_small_data_p (enum machine_mode mode, rtx x)
5316 return (DEFAULT_ABI == ABI_V4
5317 && !flag_pic && !TARGET_TOC
5318 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
5319 && small_data_operand (x, mode));
5322 /* SPE offset addressing is limited to 5-bits worth of double words. */
5323 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
5326 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
5328 unsigned HOST_WIDE_INT offset, extra;
5330 if (GET_CODE (x) != PLUS)
5332 if (GET_CODE (XEXP (x, 0)) != REG)
5334 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5336 if (!reg_offset_addressing_ok_p (mode))
5337 return virtual_stack_registers_memory_p (x);
5338 if (legitimate_constant_pool_address_p (x, mode, strict))
5340 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5343 offset = INTVAL (XEXP (x, 1));
5351 /* SPE vector modes. */
5352 return SPE_CONST_OFFSET_OK (offset);
5355 if (TARGET_E500_DOUBLE)
5356 return SPE_CONST_OFFSET_OK (offset);
5358 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
5360 if (VECTOR_MEM_VSX_P (DFmode))
5365 /* On e500v2, we may have:
5367 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
5369 Which gets addressed with evldd instructions. */
5370 if (TARGET_E500_DOUBLE)
5371 return SPE_CONST_OFFSET_OK (offset);
5373 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
5375 else if (offset & 3)
5380 if (TARGET_E500_DOUBLE)
5381 return (SPE_CONST_OFFSET_OK (offset)
5382 && SPE_CONST_OFFSET_OK (offset + 8));
5386 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
5388 else if (offset & 3)
5399 return offset < 0x10000 - extra;
5403 legitimate_indexed_address_p (rtx x, int strict)
5407 if (GET_CODE (x) != PLUS)
5413 /* Recognize the rtl generated by reload which we know will later be
5414 replaced with proper base and index regs. */
5416 && reload_in_progress
5417 && (REG_P (op0) || GET_CODE (op0) == PLUS)
5421 return (REG_P (op0) && REG_P (op1)
5422 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
5423 && INT_REG_OK_FOR_INDEX_P (op1, strict))
5424 || (INT_REG_OK_FOR_BASE_P (op1, strict)
5425 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
5429 avoiding_indexed_address_p (enum machine_mode mode)
5431 /* Avoid indexed addressing for modes that have non-indexed
5432 load/store instruction forms. */
5433 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
5437 legitimate_indirect_address_p (rtx x, int strict)
5439 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
5443 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
5445 if (!TARGET_MACHO || !flag_pic
5446 || mode != SImode || GET_CODE (x) != MEM)
5450 if (GET_CODE (x) != LO_SUM)
5452 if (GET_CODE (XEXP (x, 0)) != REG)
5454 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
5458 return CONSTANT_P (x);
5462 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
5464 if (GET_CODE (x) != LO_SUM)
5466 if (GET_CODE (XEXP (x, 0)) != REG)
5468 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5470 /* Restrict addressing for DI because of our SUBREG hackery. */
5471 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5472 || mode == DDmode || mode == TDmode
5477 if (TARGET_ELF || TARGET_MACHO)
5479 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
5483 if (GET_MODE_NUNITS (mode) != 1)
5485 if (GET_MODE_BITSIZE (mode) > 64
5486 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
5487 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5488 && (mode == DFmode || mode == DDmode))))
5491 return CONSTANT_P (x);
5498 /* Try machine-dependent ways of modifying an illegitimate address
5499 to be legitimate. If we find one, return the new, valid address.
5500 This is used from only one place: `memory_address' in explow.c.
5502 OLDX is the address as it was before break_out_memory_refs was
5503 called. In some cases it is useful to look at this to decide what
5506 It is always safe for this function to do nothing. It exists to
5507 recognize opportunities to optimize the output.
5509 On RS/6000, first check for the sum of a register with a constant
5510 integer that is out of range. If so, generate code to add the
5511 constant with the low-order 16 bits masked to the register and force
5512 this result into another register (this can be done with `cau').
5513 Then generate an address of REG+(CONST&0xffff), allowing for the
5514 possibility of bit 16 being a one.
5516 Then check for the sum of a register and something not constant, try to
5517 load the other things into a register and return the sum. */
5520 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
5521 enum machine_mode mode)
5523 unsigned int extra = 0;
5525 if (!reg_offset_addressing_ok_p (mode))
5527 if (virtual_stack_registers_memory_p (x))
5530 /* In theory we should not be seeing addresses of the form reg+0,
5531 but just in case it is generated, optimize it away. */
5532 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
5533 return force_reg (Pmode, XEXP (x, 0));
5535 /* Make sure both operands are registers. */
5536 else if (GET_CODE (x) == PLUS)
5537 return gen_rtx_PLUS (Pmode,
5538 force_reg (Pmode, XEXP (x, 0)),
5539 force_reg (Pmode, XEXP (x, 1)));
5541 return force_reg (Pmode, x);
5543 if (GET_CODE (x) == SYMBOL_REF)
5545 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
5547 return rs6000_legitimize_tls_address (x, model);
5557 if (!TARGET_POWERPC64)
5565 extra = TARGET_POWERPC64 ? 8 : 12;
5571 if (GET_CODE (x) == PLUS
5572 && GET_CODE (XEXP (x, 0)) == REG
5573 && GET_CODE (XEXP (x, 1)) == CONST_INT
5574 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
5576 && !((TARGET_POWERPC64
5577 && (mode == DImode || mode == TImode)
5578 && (INTVAL (XEXP (x, 1)) & 3) != 0)
5579 || SPE_VECTOR_MODE (mode)
5580 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5581 || mode == DImode || mode == DDmode
5582 || mode == TDmode))))
5584 HOST_WIDE_INT high_int, low_int;
5586 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
5587 if (low_int >= 0x8000 - extra)
5589 high_int = INTVAL (XEXP (x, 1)) - low_int;
5590 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
5591 GEN_INT (high_int)), 0);
5592 return plus_constant (sum, low_int);
5594 else if (GET_CODE (x) == PLUS
5595 && GET_CODE (XEXP (x, 0)) == REG
5596 && GET_CODE (XEXP (x, 1)) != CONST_INT
5597 && GET_MODE_NUNITS (mode) == 1
5598 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5600 || ((mode != DImode && mode != DFmode && mode != DDmode)
5601 || (TARGET_E500_DOUBLE && mode != DDmode)))
5602 && (TARGET_POWERPC64 || mode != DImode)
5603 && !avoiding_indexed_address_p (mode)
5608 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
5609 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
5611 else if (SPE_VECTOR_MODE (mode)
5612 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5613 || mode == DDmode || mode == TDmode
5614 || mode == DImode)))
5618 /* We accept [reg + reg] and [reg + OFFSET]. */
5620 if (GET_CODE (x) == PLUS)
5622 rtx op1 = XEXP (x, 0);
5623 rtx op2 = XEXP (x, 1);
5626 op1 = force_reg (Pmode, op1);
5628 if (GET_CODE (op2) != REG
5629 && (GET_CODE (op2) != CONST_INT
5630 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
5631 || (GET_MODE_SIZE (mode) > 8
5632 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
5633 op2 = force_reg (Pmode, op2);
5635 /* We can't always do [reg + reg] for these, because [reg +
5636 reg + offset] is not a legitimate addressing mode. */
5637 y = gen_rtx_PLUS (Pmode, op1, op2);
5639 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
5640 return force_reg (Pmode, y);
5645 return force_reg (Pmode, x);
5651 && GET_CODE (x) != CONST_INT
5652 && GET_CODE (x) != CONST_DOUBLE
5654 && GET_MODE_NUNITS (mode) == 1
5655 && (GET_MODE_BITSIZE (mode) <= 32
5656 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5657 && (mode == DFmode || mode == DDmode))))
5659 rtx reg = gen_reg_rtx (Pmode);
5660 emit_insn (gen_elf_high (reg, x));
5661 return gen_rtx_LO_SUM (Pmode, reg, x);
5663 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
5666 && ! MACHO_DYNAMIC_NO_PIC_P
5668 && GET_CODE (x) != CONST_INT
5669 && GET_CODE (x) != CONST_DOUBLE
5671 && GET_MODE_NUNITS (mode) == 1
5672 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5673 || (mode != DFmode && mode != DDmode))
5677 rtx reg = gen_reg_rtx (Pmode);
5678 emit_insn (gen_macho_high (reg, x));
5679 return gen_rtx_LO_SUM (Pmode, reg, x);
5682 && GET_CODE (x) == SYMBOL_REF
5683 && constant_pool_expr_p (x)
5684 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
5686 rtx reg = TARGET_CMODEL != CMODEL_SMALL ? gen_reg_rtx (Pmode) : NULL_RTX;
5687 return create_TOC_reference (x, reg);
5693 /* Debug version of rs6000_legitimize_address. */
5695 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
5701 ret = rs6000_legitimize_address (x, oldx, mode);
5702 insns = get_insns ();
5708 "\nrs6000_legitimize_address: mode %s, old code %s, "
5709 "new code %s, modified\n",
5710 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
5711 GET_RTX_NAME (GET_CODE (ret)));
5713 fprintf (stderr, "Original address:\n");
5716 fprintf (stderr, "oldx:\n");
5719 fprintf (stderr, "New address:\n");
5724 fprintf (stderr, "Insns added:\n");
5725 debug_rtx_list (insns, 20);
5731 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
5732 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
5743 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
5744 We need to emit DTP-relative relocations. */
5747 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
5752 fputs ("\t.long\t", file);
5755 fputs (DOUBLE_INT_ASM_OP, file);
5760 output_addr_const (file, x);
5761 fputs ("@dtprel+0x8000", file);
5764 /* In the name of slightly smaller debug output, and to cater to
5765 general assembler lossage, recognize various UNSPEC sequences
5766 and turn them back into a direct symbol reference. */
5769 rs6000_delegitimize_address (rtx orig_x)
5773 orig_x = delegitimize_mem_from_attrs (orig_x);
5778 if (GET_CODE (x) == (TARGET_CMODEL != CMODEL_SMALL ? LO_SUM : PLUS)
5779 && GET_CODE (XEXP (x, 1)) == CONST)
5781 rtx offset = NULL_RTX;
5783 y = XEXP (XEXP (x, 1), 0);
5784 if (GET_CODE (y) == PLUS
5785 && GET_MODE (y) == Pmode
5786 && CONST_INT_P (XEXP (y, 1)))
5788 offset = XEXP (y, 1);
5791 if (GET_CODE (y) == UNSPEC
5792 && XINT (y, 1) == UNSPEC_TOCREL
5793 && ((GET_CODE (XEXP (x, 0)) == REG
5794 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5795 || TARGET_MINIMAL_TOC
5796 || TARGET_CMODEL != CMODEL_SMALL))
5797 || (TARGET_CMODEL != CMODEL_SMALL
5798 && GET_CODE (XEXP (x, 0)) == CONST
5799 && GET_CODE (XEXP (XEXP (x, 0), 0)) == PLUS
5800 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == REG
5801 && REGNO (XEXP (XEXP (XEXP (x, 0), 0), 0)) == TOC_REGISTER
5802 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == HIGH
5803 && rtx_equal_p (XEXP (x, 1),
5804 XEXP (XEXP (XEXP (XEXP (x, 0), 0), 1), 0)))))
5806 y = XVECEXP (y, 0, 0);
5807 if (offset != NULL_RTX)
5808 y = gen_rtx_PLUS (Pmode, y, offset);
5809 if (!MEM_P (orig_x))
5812 return replace_equiv_address_nv (orig_x, y);
5817 && GET_CODE (orig_x) == LO_SUM
5818 && GET_CODE (XEXP (orig_x, 1)) == CONST)
5820 y = XEXP (XEXP (orig_x, 1), 0);
5821 if (GET_CODE (y) == UNSPEC
5822 && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET)
5823 return XVECEXP (y, 0, 0);
5829 /* Construct the SYMBOL_REF for the tls_get_addr function. */
5831 static GTY(()) rtx rs6000_tls_symbol;
5833 rs6000_tls_get_addr (void)
5835 if (!rs6000_tls_symbol)
5836 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
5838 return rs6000_tls_symbol;
5841 /* Construct the SYMBOL_REF for TLS GOT references. */
5843 static GTY(()) rtx rs6000_got_symbol;
5845 rs6000_got_sym (void)
5847 if (!rs6000_got_symbol)
5849 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
5850 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
5851 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
5854 return rs6000_got_symbol;
5857 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
5858 this (thread-local) address. */
5861 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
5865 dest = gen_reg_rtx (Pmode);
5866 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
5872 tlsreg = gen_rtx_REG (Pmode, 13);
5873 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
5877 tlsreg = gen_rtx_REG (Pmode, 2);
5878 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
5882 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
5886 tmp = gen_reg_rtx (Pmode);
5889 tlsreg = gen_rtx_REG (Pmode, 13);
5890 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
5894 tlsreg = gen_rtx_REG (Pmode, 2);
5895 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
5899 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
5901 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
5906 rtx r3, got, tga, tmp1, tmp2, call_insn;
5908 /* We currently use relocations like @got@tlsgd for tls, which
5909 means the linker will handle allocation of tls entries, placing
5910 them in the .got section. So use a pointer to the .got section,
5911 not one to secondary TOC sections used by 64-bit -mminimal-toc,
5912 or to secondary GOT sections used by 32-bit -fPIC. */
5914 got = gen_rtx_REG (Pmode, 2);
5918 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
5921 rtx gsym = rs6000_got_sym ();
5922 got = gen_reg_rtx (Pmode);
5924 rs6000_emit_move (got, gsym, Pmode);
5929 tmp1 = gen_reg_rtx (Pmode);
5930 tmp2 = gen_reg_rtx (Pmode);
5931 mem = gen_const_mem (Pmode, tmp1);
5932 lab = gen_label_rtx ();
5933 emit_insn (gen_load_toc_v4_PIC_1b (gsym, lab));
5934 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
5935 emit_move_insn (tmp2, mem);
5936 last = emit_insn (gen_addsi3 (got, tmp1, tmp2));
5937 set_unique_reg_note (last, REG_EQUAL, gsym);
5942 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
5944 tga = rs6000_tls_get_addr ();
5945 emit_library_call_value (tga, dest, LCT_CONST, Pmode,
5946 1, const0_rtx, Pmode);
5948 r3 = gen_rtx_REG (Pmode, 3);
5949 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5950 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
5951 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5952 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
5953 else if (DEFAULT_ABI == ABI_V4)
5954 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
5957 call_insn = last_call_insn ();
5958 PATTERN (call_insn) = insn;
5959 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5960 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
5961 pic_offset_table_rtx);
5963 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
5965 tga = rs6000_tls_get_addr ();
5966 tmp1 = gen_reg_rtx (Pmode);
5967 emit_library_call_value (tga, tmp1, LCT_CONST, Pmode,
5968 1, const0_rtx, Pmode);
5970 r3 = gen_rtx_REG (Pmode, 3);
5971 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5972 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
5973 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5974 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
5975 else if (DEFAULT_ABI == ABI_V4)
5976 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
5979 call_insn = last_call_insn ();
5980 PATTERN (call_insn) = insn;
5981 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5982 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
5983 pic_offset_table_rtx);
5985 if (rs6000_tls_size == 16)
5988 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
5990 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
5992 else if (rs6000_tls_size == 32)
5994 tmp2 = gen_reg_rtx (Pmode);
5996 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
5998 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
6001 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
6003 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
6007 tmp2 = gen_reg_rtx (Pmode);
6009 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
6011 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
6013 insn = gen_rtx_SET (Pmode, dest,
6014 gen_rtx_PLUS (Pmode, tmp2, tmp1));
6020 /* IE, or 64-bit offset LE. */
6021 tmp2 = gen_reg_rtx (Pmode);
6023 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
6025 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
6028 insn = gen_tls_tls_64 (dest, tmp2, addr);
6030 insn = gen_tls_tls_32 (dest, tmp2, addr);
6038 /* Return 1 if X contains a thread-local symbol. */
6041 rs6000_tls_referenced_p (rtx x)
6043 if (! TARGET_HAVE_TLS)
6046 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
6049 /* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
6052 rs6000_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
6054 if (GET_CODE (x) == CONST
6055 && GET_CODE (XEXP (x, 0)) == PLUS
6056 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH)
6059 return rs6000_tls_referenced_p (x);
6062 /* Return 1 if *X is a thread-local symbol. This is the same as
6063 rs6000_tls_symbol_ref except for the type of the unused argument. */
6066 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
6068 return RS6000_SYMBOL_REF_TLS_P (*x);
6071 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
6072 replace the input X, or the original X if no replacement is called for.
6073 The output parameter *WIN is 1 if the calling macro should goto WIN,
6076 For RS/6000, we wish to handle large displacements off a base
6077 register by splitting the addend across an addiu/addis and the mem insn.
6078 This cuts number of extra insns needed from 3 to 1.
6080 On Darwin, we use this to generate code for floating point constants.
6081 A movsf_low is generated so we wind up with 2 instructions rather than 3.
6082 The Darwin code is inside #if TARGET_MACHO because only then are the
6083 machopic_* functions defined. */
6085 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
6086 int opnum, int type,
6087 int ind_levels ATTRIBUTE_UNUSED, int *win)
6089 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6091 /* Nasty hack for vsx_splat_V2DF/V2DI load from mem, which takes a
6092 DFmode/DImode MEM. */
6095 && ((mode == DFmode && recog_data.operand_mode[0] == V2DFmode)
6096 || (mode == DImode && recog_data.operand_mode[0] == V2DImode)))
6097 reg_offset_p = false;
6099 /* We must recognize output that we have already generated ourselves. */
6100 if (GET_CODE (x) == PLUS
6101 && GET_CODE (XEXP (x, 0)) == PLUS
6102 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6103 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6104 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6106 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6107 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6108 opnum, (enum reload_type)type);
6113 /* Likewise for (lo_sum (high ...) ...) output we have generated. */
6114 if (GET_CODE (x) == LO_SUM
6115 && GET_CODE (XEXP (x, 0)) == HIGH)
6117 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6118 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6119 opnum, (enum reload_type)type);
6125 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
6126 && GET_CODE (x) == LO_SUM
6127 && GET_CODE (XEXP (x, 0)) == PLUS
6128 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
6129 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6130 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
6131 && machopic_operand_p (XEXP (x, 1)))
6133 /* Result of previous invocation of this function on Darwin
6134 floating point constant. */
6135 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6136 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6137 opnum, (enum reload_type)type);
6143 if (TARGET_CMODEL != CMODEL_SMALL
6144 && GET_CODE (x) == LO_SUM
6145 && GET_CODE (XEXP (x, 0)) == PLUS
6146 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6147 && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER
6148 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST
6149 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 0)) == HIGH
6150 && GET_CODE (XEXP (x, 1)) == CONST
6151 && GET_CODE (XEXP (XEXP (x, 1), 0)) == UNSPEC
6152 && XINT (XEXP (XEXP (x, 1), 0), 1) == UNSPEC_TOCREL
6153 && rtx_equal_p (XEXP (XEXP (XEXP (XEXP (x, 0), 1), 0), 0), XEXP (x, 1)))
6155 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6156 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6157 opnum, (enum reload_type) type);
6162 /* Force ld/std non-word aligned offset into base register by wrapping
6164 if (GET_CODE (x) == PLUS
6165 && GET_CODE (XEXP (x, 0)) == REG
6166 && REGNO (XEXP (x, 0)) < 32
6167 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6168 && GET_CODE (XEXP (x, 1)) == CONST_INT
6170 && (INTVAL (XEXP (x, 1)) & 3) != 0
6171 && VECTOR_MEM_NONE_P (mode)
6172 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
6173 && TARGET_POWERPC64)
6175 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
6176 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6177 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6178 opnum, (enum reload_type) type);
6183 if (GET_CODE (x) == PLUS
6184 && GET_CODE (XEXP (x, 0)) == REG
6185 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
6186 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6187 && GET_CODE (XEXP (x, 1)) == CONST_INT
6189 && !SPE_VECTOR_MODE (mode)
6190 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6191 || mode == DDmode || mode == TDmode
6193 && VECTOR_MEM_NONE_P (mode))
6195 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
6196 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
6198 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
6200 /* Check for 32-bit overflow. */
6201 if (high + low != val)
6207 /* Reload the high part into a base reg; leave the low part
6208 in the mem directly. */
6210 x = gen_rtx_PLUS (GET_MODE (x),
6211 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
6215 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6216 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6217 opnum, (enum reload_type)type);
6222 if (GET_CODE (x) == SYMBOL_REF
6224 && VECTOR_MEM_NONE_P (mode)
6225 && !SPE_VECTOR_MODE (mode)
6227 && DEFAULT_ABI == ABI_DARWIN
6228 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
6230 && DEFAULT_ABI == ABI_V4
6233 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
6234 The same goes for DImode without 64-bit gprs and DFmode and DDmode
6238 && (mode != DImode || TARGET_POWERPC64)
6239 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
6240 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
6245 rtx offset = machopic_gen_offset (x);
6246 x = gen_rtx_LO_SUM (GET_MODE (x),
6247 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
6248 gen_rtx_HIGH (Pmode, offset)), offset);
6252 x = gen_rtx_LO_SUM (GET_MODE (x),
6253 gen_rtx_HIGH (Pmode, x), x);
6255 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6256 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6257 opnum, (enum reload_type)type);
6262 /* Reload an offset address wrapped by an AND that represents the
6263 masking of the lower bits. Strip the outer AND and let reload
6264 convert the offset address into an indirect address. For VSX,
6265 force reload to create the address with an AND in a separate
6266 register, because we can't guarantee an altivec register will
6268 if (VECTOR_MEM_ALTIVEC_P (mode)
6269 && GET_CODE (x) == AND
6270 && GET_CODE (XEXP (x, 0)) == PLUS
6271 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6272 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6273 && GET_CODE (XEXP (x, 1)) == CONST_INT
6274 && INTVAL (XEXP (x, 1)) == -16)
6283 && GET_CODE (x) == SYMBOL_REF
6284 && constant_pool_expr_p (x)
6285 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
6287 x = create_TOC_reference (x, NULL_RTX);
6288 if (TARGET_CMODEL != CMODEL_SMALL)
6289 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6290 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6291 opnum, (enum reload_type) type);
6299 /* Debug version of rs6000_legitimize_reload_address. */
6301 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
6302 int opnum, int type,
6303 int ind_levels, int *win)
6305 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
6308 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
6309 "type = %d, ind_levels = %d, win = %d, original addr:\n",
6310 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
6314 fprintf (stderr, "Same address returned\n");
6316 fprintf (stderr, "NULL returned\n");
6319 fprintf (stderr, "New address:\n");
6326 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
6327 that is a valid memory address for an instruction.
6328 The MODE argument is the machine mode for the MEM expression
6329 that wants to use this address.
6331 On the RS/6000, there are four valid address: a SYMBOL_REF that
6332 refers to a constant pool entry of an address (or the sum of it
6333 plus a constant), a short (16-bit signed) constant plus a register,
6334 the sum of two registers, or a register indirect, possibly with an
6335 auto-increment. For DFmode, DDmode and DImode with a constant plus
6336 register, we must ensure that both words are addressable or PowerPC64
6337 with offset word aligned.
6339 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
6340 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
6341 because adjacent memory cells are accessed by adding word-sized offsets
6342 during assembly output. */
6344 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
6346 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6348 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
6349 if (VECTOR_MEM_ALTIVEC_P (mode)
6350 && GET_CODE (x) == AND
6351 && GET_CODE (XEXP (x, 1)) == CONST_INT
6352 && INTVAL (XEXP (x, 1)) == -16)
6355 if (RS6000_SYMBOL_REF_TLS_P (x))
6357 if (legitimate_indirect_address_p (x, reg_ok_strict))
6359 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
6360 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6361 && !SPE_VECTOR_MODE (mode)
6364 /* Restrict addressing for DI because of our SUBREG hackery. */
6365 && !(TARGET_E500_DOUBLE
6366 && (mode == DFmode || mode == DDmode || mode == DImode))
6368 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
6370 if (virtual_stack_registers_memory_p (x))
6372 if (reg_offset_p && legitimate_small_data_p (mode, x))
6375 && legitimate_constant_pool_address_p (x, mode, reg_ok_strict))
6377 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
6380 && GET_CODE (x) == PLUS
6381 && GET_CODE (XEXP (x, 0)) == REG
6382 && (XEXP (x, 0) == virtual_stack_vars_rtx
6383 || XEXP (x, 0) == arg_pointer_rtx)
6384 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6386 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
6391 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6393 || (mode != DFmode && mode != DDmode)
6394 || (TARGET_E500_DOUBLE && mode != DDmode))
6395 && (TARGET_POWERPC64 || mode != DImode)
6396 && !avoiding_indexed_address_p (mode)
6397 && legitimate_indexed_address_p (x, reg_ok_strict))
6399 if (GET_CODE (x) == PRE_MODIFY
6403 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6405 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
6406 && (TARGET_POWERPC64 || mode != DImode)
6407 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6408 && !SPE_VECTOR_MODE (mode)
6409 /* Restrict addressing for DI because of our SUBREG hackery. */
6410 && !(TARGET_E500_DOUBLE
6411 && (mode == DFmode || mode == DDmode || mode == DImode))
6413 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
6414 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
6415 || (!avoiding_indexed_address_p (mode)
6416 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
6417 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
6419 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
6424 /* Debug version of rs6000_legitimate_address_p. */
6426 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
6429 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
6431 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
6432 "strict = %d, code = %s\n",
6433 ret ? "true" : "false",
6434 GET_MODE_NAME (mode),
6436 GET_RTX_NAME (GET_CODE (x)));
6442 /* Implement TARGET_MODE_DEPENDENT_ADDRESS_P. */
6445 rs6000_mode_dependent_address_p (const_rtx addr)
6447 return rs6000_mode_dependent_address_ptr (addr);
6450 /* Go to LABEL if ADDR (a legitimate address expression)
6451 has an effect that depends on the machine mode it is used for.
6453 On the RS/6000 this is true of all integral offsets (since AltiVec
6454 and VSX modes don't allow them) or is a pre-increment or decrement.
6456 ??? Except that due to conceptual problems in offsettable_address_p
6457 we can't really report the problems of integral offsets. So leave
6458 this assuming that the adjustable offset must be valid for the
6459 sub-words of a TFmode operand, which is what we had before. */
6462 rs6000_mode_dependent_address (const_rtx addr)
6464 switch (GET_CODE (addr))
6467 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
6468 is considered a legitimate address before reload, so there
6469 are no offset restrictions in that case. Note that this
6470 condition is safe in strict mode because any address involving
6471 virtual_stack_vars_rtx or arg_pointer_rtx would already have
6472 been rejected as illegitimate. */
6473 if (XEXP (addr, 0) != virtual_stack_vars_rtx
6474 && XEXP (addr, 0) != arg_pointer_rtx
6475 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
6477 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
6478 return val + 12 + 0x8000 >= 0x10000;
6483 /* Anything in the constant pool is sufficiently aligned that
6484 all bytes have the same high part address. */
6485 return !legitimate_constant_pool_address_p (addr, QImode, false);
6487 /* Auto-increment cases are now treated generically in recog.c. */
6489 return TARGET_UPDATE;
6491 /* AND is only allowed in Altivec loads. */
6502 /* Debug version of rs6000_mode_dependent_address. */
6504 rs6000_debug_mode_dependent_address (const_rtx addr)
6506 bool ret = rs6000_mode_dependent_address (addr);
6508 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
6509 ret ? "true" : "false");
6515 /* Implement FIND_BASE_TERM. */
6518 rs6000_find_base_term (rtx op)
6522 split_const (op, &base, &offset);
6523 if (GET_CODE (base) == UNSPEC)
6524 switch (XINT (base, 1))
6527 case UNSPEC_MACHOPIC_OFFSET:
6528 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
6529 for aliasing purposes. */
6530 return XVECEXP (base, 0, 0);
6536 /* More elaborate version of recog's offsettable_memref_p predicate
6537 that works around the ??? note of rs6000_mode_dependent_address.
6538 In particular it accepts
6540 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
6542 in 32-bit mode, that the recog predicate rejects. */
6545 rs6000_offsettable_memref_p (rtx op)
6550 /* First mimic offsettable_memref_p. */
6551 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
6554 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
6555 the latter predicate knows nothing about the mode of the memory
6556 reference and, therefore, assumes that it is the largest supported
6557 mode (TFmode). As a consequence, legitimate offsettable memory
6558 references are rejected. rs6000_legitimate_offset_address_p contains
6559 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
6560 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
6563 /* Change register usage conditional on target flags. */
6565 rs6000_conditional_register_usage (void)
6569 if (TARGET_DEBUG_TARGET)
6570 fprintf (stderr, "rs6000_conditional_register_usage called\n");
6572 /* Set MQ register fixed (already call_used) if not POWER
6573 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
6578 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
6580 fixed_regs[13] = call_used_regs[13]
6581 = call_really_used_regs[13] = 1;
6583 /* Conditionally disable FPRs. */
6584 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6585 for (i = 32; i < 64; i++)
6586 fixed_regs[i] = call_used_regs[i]
6587 = call_really_used_regs[i] = 1;
6589 /* The TOC register is not killed across calls in a way that is
6590 visible to the compiler. */
6591 if (DEFAULT_ABI == ABI_AIX)
6592 call_really_used_regs[2] = 0;
6594 if (DEFAULT_ABI == ABI_V4
6595 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6597 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6599 if (DEFAULT_ABI == ABI_V4
6600 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6602 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6603 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6604 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6606 if (DEFAULT_ABI == ABI_DARWIN
6607 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
6608 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6609 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6610 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6612 if (TARGET_TOC && TARGET_MINIMAL_TOC)
6613 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6614 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6618 global_regs[SPEFSCR_REGNO] = 1;
6619 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
6620 registers in prologues and epilogues. We no longer use r14
6621 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
6622 pool for link-compatibility with older versions of GCC. Once
6623 "old" code has died out, we can return r14 to the allocation
6626 = call_used_regs[14]
6627 = call_really_used_regs[14] = 1;
6630 if (!TARGET_ALTIVEC && !TARGET_VSX)
6632 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
6633 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6634 call_really_used_regs[VRSAVE_REGNO] = 1;
6637 if (TARGET_ALTIVEC || TARGET_VSX)
6638 global_regs[VSCR_REGNO] = 1;
6640 if (TARGET_ALTIVEC_ABI)
6642 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
6643 call_used_regs[i] = call_really_used_regs[i] = 1;
6645 /* AIX reserves VR20:31 in non-extended ABI mode. */
6647 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
6648 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6652 /* Try to output insns to set TARGET equal to the constant C if it can
6653 be done in less than N insns. Do all computations in MODE.
6654 Returns the place where the output has been placed if it can be
6655 done and the insns have been emitted. If it would take more than N
6656 insns, zero is returned and no insns and emitted. */
6659 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
6660 rtx source, int n ATTRIBUTE_UNUSED)
6662 rtx result, insn, set;
6663 HOST_WIDE_INT c0, c1;
6670 dest = gen_reg_rtx (mode);
6671 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
6675 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
6677 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
6678 GEN_INT (INTVAL (source)
6679 & (~ (HOST_WIDE_INT) 0xffff))));
6680 emit_insn (gen_rtx_SET (VOIDmode, dest,
6681 gen_rtx_IOR (SImode, copy_rtx (result),
6682 GEN_INT (INTVAL (source) & 0xffff))));
6687 switch (GET_CODE (source))
6690 c0 = INTVAL (source);
6695 #if HOST_BITS_PER_WIDE_INT >= 64
6696 c0 = CONST_DOUBLE_LOW (source);
6699 c0 = CONST_DOUBLE_LOW (source);
6700 c1 = CONST_DOUBLE_HIGH (source);
6708 result = rs6000_emit_set_long_const (dest, c0, c1);
6715 insn = get_last_insn ();
6716 set = single_set (insn);
6717 if (! CONSTANT_P (SET_SRC (set)))
6718 set_unique_reg_note (insn, REG_EQUAL, source);
6723 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
6724 fall back to a straight forward decomposition. We do this to avoid
6725 exponential run times encountered when looking for longer sequences
6726 with rs6000_emit_set_const. */
6728 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
6730 if (!TARGET_POWERPC64)
6732 rtx operand1, operand2;
6734 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
6736 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
6738 emit_move_insn (operand1, GEN_INT (c1));
6739 emit_move_insn (operand2, GEN_INT (c2));
6743 HOST_WIDE_INT ud1, ud2, ud3, ud4;
6746 ud2 = (c1 & 0xffff0000) >> 16;
6747 #if HOST_BITS_PER_WIDE_INT >= 64
6751 ud4 = (c2 & 0xffff0000) >> 16;
6753 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
6754 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
6757 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
6759 emit_move_insn (dest, GEN_INT (ud1));
6762 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
6763 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
6766 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6769 emit_move_insn (dest, GEN_INT (ud2 << 16));
6771 emit_move_insn (copy_rtx (dest),
6772 gen_rtx_IOR (DImode, copy_rtx (dest),
6775 else if (ud3 == 0 && ud4 == 0)
6777 gcc_assert (ud2 & 0x8000);
6778 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6781 emit_move_insn (copy_rtx (dest),
6782 gen_rtx_IOR (DImode, copy_rtx (dest),
6784 emit_move_insn (copy_rtx (dest),
6785 gen_rtx_ZERO_EXTEND (DImode,
6786 gen_lowpart (SImode,
6789 else if ((ud4 == 0xffff && (ud3 & 0x8000))
6790 || (ud4 == 0 && ! (ud3 & 0x8000)))
6793 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
6796 emit_move_insn (dest, GEN_INT (ud3 << 16));
6799 emit_move_insn (copy_rtx (dest),
6800 gen_rtx_IOR (DImode, copy_rtx (dest),
6802 emit_move_insn (copy_rtx (dest),
6803 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6806 emit_move_insn (copy_rtx (dest),
6807 gen_rtx_IOR (DImode, copy_rtx (dest),
6813 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
6816 emit_move_insn (dest, GEN_INT (ud4 << 16));
6819 emit_move_insn (copy_rtx (dest),
6820 gen_rtx_IOR (DImode, copy_rtx (dest),
6823 emit_move_insn (copy_rtx (dest),
6824 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6827 emit_move_insn (copy_rtx (dest),
6828 gen_rtx_IOR (DImode, copy_rtx (dest),
6829 GEN_INT (ud2 << 16)));
6831 emit_move_insn (copy_rtx (dest),
6832 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
6838 /* Helper for the following. Get rid of [r+r] memory refs
6839 in cases where it won't work (TImode, TFmode, TDmode). */
6842 rs6000_eliminate_indexed_memrefs (rtx operands[2])
6844 if (reload_in_progress)
6847 if (GET_CODE (operands[0]) == MEM
6848 && GET_CODE (XEXP (operands[0], 0)) != REG
6849 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0),
6850 GET_MODE (operands[0]), false))
6852 = replace_equiv_address (operands[0],
6853 copy_addr_to_reg (XEXP (operands[0], 0)));
6855 if (GET_CODE (operands[1]) == MEM
6856 && GET_CODE (XEXP (operands[1], 0)) != REG
6857 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0),
6858 GET_MODE (operands[1]), false))
6860 = replace_equiv_address (operands[1],
6861 copy_addr_to_reg (XEXP (operands[1], 0)));
6864 /* Emit a move from SOURCE to DEST in mode MODE. */
6866 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
6870 operands[1] = source;
6872 if (TARGET_DEBUG_ADDR)
6875 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
6876 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
6877 GET_MODE_NAME (mode),
6880 can_create_pseudo_p ());
6882 fprintf (stderr, "source:\n");
6886 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
6887 if (GET_CODE (operands[1]) == CONST_DOUBLE
6888 && ! FLOAT_MODE_P (mode)
6889 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
6891 /* FIXME. This should never happen. */
6892 /* Since it seems that it does, do the safe thing and convert
6894 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
6896 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
6897 || FLOAT_MODE_P (mode)
6898 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
6899 || CONST_DOUBLE_LOW (operands[1]) < 0)
6900 && (CONST_DOUBLE_HIGH (operands[1]) != -1
6901 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
6903 /* Check if GCC is setting up a block move that will end up using FP
6904 registers as temporaries. We must make sure this is acceptable. */
6905 if (GET_CODE (operands[0]) == MEM
6906 && GET_CODE (operands[1]) == MEM
6908 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
6909 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
6910 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
6911 ? 32 : MEM_ALIGN (operands[0])))
6912 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
6914 : MEM_ALIGN (operands[1]))))
6915 && ! MEM_VOLATILE_P (operands [0])
6916 && ! MEM_VOLATILE_P (operands [1]))
6918 emit_move_insn (adjust_address (operands[0], SImode, 0),
6919 adjust_address (operands[1], SImode, 0));
6920 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
6921 adjust_address (copy_rtx (operands[1]), SImode, 4));
6925 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
6926 && !gpc_reg_operand (operands[1], mode))
6927 operands[1] = force_reg (mode, operands[1]);
6929 if (mode == SFmode && ! TARGET_POWERPC
6930 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6931 && GET_CODE (operands[0]) == MEM)
6935 if (reload_in_progress || reload_completed)
6936 regnum = true_regnum (operands[1]);
6937 else if (GET_CODE (operands[1]) == REG)
6938 regnum = REGNO (operands[1]);
6942 /* If operands[1] is a register, on POWER it may have
6943 double-precision data in it, so truncate it to single
6945 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
6948 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
6949 : gen_reg_rtx (mode));
6950 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
6951 operands[1] = newreg;
6955 /* Recognize the case where operand[1] is a reference to thread-local
6956 data and load its address to a register. */
6957 if (rs6000_tls_referenced_p (operands[1]))
6959 enum tls_model model;
6960 rtx tmp = operands[1];
6963 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6965 addend = XEXP (XEXP (tmp, 0), 1);
6966 tmp = XEXP (XEXP (tmp, 0), 0);
6969 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6970 model = SYMBOL_REF_TLS_MODEL (tmp);
6971 gcc_assert (model != 0);
6973 tmp = rs6000_legitimize_tls_address (tmp, model);
6976 tmp = gen_rtx_PLUS (mode, tmp, addend);
6977 tmp = force_operand (tmp, operands[0]);
6982 /* Handle the case where reload calls us with an invalid address. */
6983 if (reload_in_progress && mode == Pmode
6984 && (! general_operand (operands[1], mode)
6985 || ! nonimmediate_operand (operands[0], mode)))
6988 /* 128-bit constant floating-point values on Darwin should really be
6989 loaded as two parts. */
6990 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
6991 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
6993 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
6994 know how to get a DFmode SUBREG of a TFmode. */
6995 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
6996 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
6997 simplify_gen_subreg (imode, operands[1], mode, 0),
6999 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
7000 GET_MODE_SIZE (imode)),
7001 simplify_gen_subreg (imode, operands[1], mode,
7002 GET_MODE_SIZE (imode)),
7007 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
7008 cfun->machine->sdmode_stack_slot =
7009 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
7011 if (reload_in_progress
7013 && MEM_P (operands[0])
7014 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
7015 && REG_P (operands[1]))
7017 if (FP_REGNO_P (REGNO (operands[1])))
7019 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
7020 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7021 emit_insn (gen_movsd_store (mem, operands[1]));
7023 else if (INT_REGNO_P (REGNO (operands[1])))
7025 rtx mem = adjust_address_nv (operands[0], mode, 4);
7026 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7027 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
7033 if (reload_in_progress
7035 && REG_P (operands[0])
7036 && MEM_P (operands[1])
7037 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
7039 if (FP_REGNO_P (REGNO (operands[0])))
7041 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
7042 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7043 emit_insn (gen_movsd_load (operands[0], mem));
7045 else if (INT_REGNO_P (REGNO (operands[0])))
7047 rtx mem = adjust_address_nv (operands[1], mode, 4);
7048 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7049 emit_insn (gen_movsd_hardfloat (operands[0], mem));
7056 /* FIXME: In the long term, this switch statement should go away
7057 and be replaced by a sequence of tests based on things like
7063 if (CONSTANT_P (operands[1])
7064 && GET_CODE (operands[1]) != CONST_INT)
7065 operands[1] = force_const_mem (mode, operands[1]);
7070 rs6000_eliminate_indexed_memrefs (operands);
7077 if (CONSTANT_P (operands[1])
7078 && ! easy_fp_constant (operands[1], mode))
7079 operands[1] = force_const_mem (mode, operands[1]);
7092 if (CONSTANT_P (operands[1])
7093 && !easy_vector_constant (operands[1], mode))
7094 operands[1] = force_const_mem (mode, operands[1]);
7099 /* Use default pattern for address of ELF small data */
7102 && DEFAULT_ABI == ABI_V4
7103 && (GET_CODE (operands[1]) == SYMBOL_REF
7104 || GET_CODE (operands[1]) == CONST)
7105 && small_data_operand (operands[1], mode))
7107 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7111 if (DEFAULT_ABI == ABI_V4
7112 && mode == Pmode && mode == SImode
7113 && flag_pic == 1 && got_operand (operands[1], mode))
7115 emit_insn (gen_movsi_got (operands[0], operands[1]));
7119 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
7123 && CONSTANT_P (operands[1])
7124 && GET_CODE (operands[1]) != HIGH
7125 && GET_CODE (operands[1]) != CONST_INT)
7127 rtx target = (!can_create_pseudo_p ()
7129 : gen_reg_rtx (mode));
7131 /* If this is a function address on -mcall-aixdesc,
7132 convert it to the address of the descriptor. */
7133 if (DEFAULT_ABI == ABI_AIX
7134 && GET_CODE (operands[1]) == SYMBOL_REF
7135 && XSTR (operands[1], 0)[0] == '.')
7137 const char *name = XSTR (operands[1], 0);
7139 while (*name == '.')
7141 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
7142 CONSTANT_POOL_ADDRESS_P (new_ref)
7143 = CONSTANT_POOL_ADDRESS_P (operands[1]);
7144 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
7145 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
7146 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
7147 operands[1] = new_ref;
7150 if (DEFAULT_ABI == ABI_DARWIN)
7153 if (MACHO_DYNAMIC_NO_PIC_P)
7155 /* Take care of any required data indirection. */
7156 operands[1] = rs6000_machopic_legitimize_pic_address (
7157 operands[1], mode, operands[0]);
7158 if (operands[0] != operands[1])
7159 emit_insn (gen_rtx_SET (VOIDmode,
7160 operands[0], operands[1]));
7164 emit_insn (gen_macho_high (target, operands[1]));
7165 emit_insn (gen_macho_low (operands[0], target, operands[1]));
7169 emit_insn (gen_elf_high (target, operands[1]));
7170 emit_insn (gen_elf_low (operands[0], target, operands[1]));
7174 /* If this is a SYMBOL_REF that refers to a constant pool entry,
7175 and we have put it in the TOC, we just need to make a TOC-relative
7178 && GET_CODE (operands[1]) == SYMBOL_REF
7179 && constant_pool_expr_p (operands[1])
7180 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
7181 get_pool_mode (operands[1])))
7182 || (TARGET_CMODEL == CMODEL_MEDIUM
7183 && GET_CODE (operands[1]) == SYMBOL_REF
7184 && !CONSTANT_POOL_ADDRESS_P (operands[1])
7185 && SYMBOL_REF_LOCAL_P (operands[1])))
7188 if (TARGET_CMODEL != CMODEL_SMALL)
7190 if (can_create_pseudo_p ())
7191 reg = gen_reg_rtx (Pmode);
7195 operands[1] = create_TOC_reference (operands[1], reg);
7197 else if (mode == Pmode
7198 && CONSTANT_P (operands[1])
7199 && GET_CODE (operands[1]) != HIGH
7200 && !(TARGET_CMODEL != CMODEL_SMALL
7201 && GET_CODE (operands[1]) == CONST
7202 && GET_CODE (XEXP (operands[1], 0)) == PLUS
7203 && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == HIGH)
7204 && ((GET_CODE (operands[1]) != CONST_INT
7205 && ! easy_fp_constant (operands[1], mode))
7206 || (GET_CODE (operands[1]) == CONST_INT
7207 && (num_insns_constant (operands[1], mode)
7208 > (TARGET_CMODEL != CMODEL_SMALL ? 3 : 2)))
7209 || (GET_CODE (operands[0]) == REG
7210 && FP_REGNO_P (REGNO (operands[0]))))
7211 && ! legitimate_constant_pool_address_p (operands[1], mode,
7213 && ! toc_relative_expr_p (operands[1])
7214 && (TARGET_CMODEL == CMODEL_SMALL
7215 || can_create_pseudo_p ()
7216 || (REG_P (operands[0])
7217 && INT_REG_OK_FOR_BASE_P (operands[0], true))))
7221 /* Darwin uses a special PIC legitimizer. */
7222 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
7225 rs6000_machopic_legitimize_pic_address (operands[1], mode,
7227 if (operands[0] != operands[1])
7228 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7233 /* If we are to limit the number of things we put in the TOC and
7234 this is a symbol plus a constant we can add in one insn,
7235 just put the symbol in the TOC and add the constant. Don't do
7236 this if reload is in progress. */
7237 if (GET_CODE (operands[1]) == CONST
7238 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
7239 && GET_CODE (XEXP (operands[1], 0)) == PLUS
7240 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
7241 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
7242 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
7243 && ! side_effects_p (operands[0]))
7246 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
7247 rtx other = XEXP (XEXP (operands[1], 0), 1);
7249 sym = force_reg (mode, sym);
7250 emit_insn (gen_add3_insn (operands[0], sym, other));
7254 operands[1] = force_const_mem (mode, operands[1]);
7257 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7258 && constant_pool_expr_p (XEXP (operands[1], 0))
7259 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
7260 get_pool_constant (XEXP (operands[1], 0)),
7261 get_pool_mode (XEXP (operands[1], 0))))
7265 if (TARGET_CMODEL != CMODEL_SMALL)
7267 if (can_create_pseudo_p ())
7268 reg = gen_reg_rtx (Pmode);
7272 tocref = create_TOC_reference (XEXP (operands[1], 0), reg);
7273 operands[1] = gen_const_mem (mode, tocref);
7274 set_mem_alias_set (operands[1], get_TOC_alias_set ());
7280 rs6000_eliminate_indexed_memrefs (operands);
7284 emit_insn (gen_rtx_PARALLEL (VOIDmode,
7286 gen_rtx_SET (VOIDmode,
7287 operands[0], operands[1]),
7288 gen_rtx_CLOBBER (VOIDmode,
7289 gen_rtx_SCRATCH (SImode)))));
7295 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
7298 /* Above, we may have called force_const_mem which may have returned
7299 an invalid address. If we can, fix this up; otherwise, reload will
7300 have to deal with it. */
7301 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
7302 operands[1] = validize_mem (operands[1]);
7305 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7308 /* Nonzero if we can use a floating-point register to pass this arg. */
7309 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
7310 (SCALAR_FLOAT_MODE_P (MODE) \
7311 && (CUM)->fregno <= FP_ARG_MAX_REG \
7312 && TARGET_HARD_FLOAT && TARGET_FPRS)
7314 /* Nonzero if we can use an AltiVec register to pass this arg. */
7315 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
7316 (ALTIVEC_OR_VSX_VECTOR_MODE (MODE) \
7317 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
7318 && TARGET_ALTIVEC_ABI \
7321 /* Return a nonzero value to say to return the function value in
7322 memory, just as large structures are always returned. TYPE will be
7323 the data type of the value, and FNTYPE will be the type of the
7324 function doing the returning, or @code{NULL} for libcalls.
7326 The AIX ABI for the RS/6000 specifies that all structures are
7327 returned in memory. The Darwin ABI does the same.
7329 For the Darwin 64 Bit ABI, a function result can be returned in
7330 registers or in memory, depending on the size of the return data
7331 type. If it is returned in registers, the value occupies the same
7332 registers as it would if it were the first and only function
7333 argument. Otherwise, the function places its result in memory at
7334 the location pointed to by GPR3.
7336 The SVR4 ABI specifies that structures <= 8 bytes are returned in r3/r4,
7337 but a draft put them in memory, and GCC used to implement the draft
7338 instead of the final standard. Therefore, aix_struct_return
7339 controls this instead of DEFAULT_ABI; V.4 targets needing backward
7340 compatibility can change DRAFT_V4_STRUCT_RET to override the
7341 default, and -m switches get the final word. See
7342 rs6000_option_override_internal for more details.
7344 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
7345 long double support is enabled. These values are returned in memory.
7347 int_size_in_bytes returns -1 for variable size objects, which go in
7348 memory always. The cast to unsigned makes -1 > 8. */
7351 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
7353 /* For the Darwin64 ABI, test if we can fit the return value in regs. */
7355 && rs6000_darwin64_abi
7356 && TREE_CODE (type) == RECORD_TYPE
7357 && int_size_in_bytes (type) > 0)
7359 CUMULATIVE_ARGS valcum;
7363 valcum.fregno = FP_ARG_MIN_REG;
7364 valcum.vregno = ALTIVEC_ARG_MIN_REG;
7365 /* Do a trial code generation as if this were going to be passed
7366 as an argument; if any part goes in memory, we return NULL. */
7367 valret = rs6000_darwin64_record_arg (&valcum, type, true, true);
7370 /* Otherwise fall through to more conventional ABI rules. */
7373 if (AGGREGATE_TYPE_P (type)
7374 && (aix_struct_return
7375 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
7378 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7379 modes only exist for GCC vector types if -maltivec. */
7380 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
7381 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
7384 /* Return synthetic vectors in memory. */
7385 if (TREE_CODE (type) == VECTOR_TYPE
7386 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
7388 static bool warned_for_return_big_vectors = false;
7389 if (!warned_for_return_big_vectors)
7391 warning (0, "GCC vector returned by reference: "
7392 "non-standard ABI extension with no compatibility guarantee");
7393 warned_for_return_big_vectors = true;
7398 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
7404 #ifdef HAVE_AS_GNU_ATTRIBUTE
7405 /* Return TRUE if a call to function FNDECL may be one that
7406 potentially affects the function calling ABI of the object file. */
7409 call_ABI_of_interest (tree fndecl)
7411 if (cgraph_state == CGRAPH_STATE_EXPANSION)
7413 struct cgraph_node *c_node;
7415 /* Libcalls are always interesting. */
7416 if (fndecl == NULL_TREE)
7419 /* Any call to an external function is interesting. */
7420 if (DECL_EXTERNAL (fndecl))
7423 /* Interesting functions that we are emitting in this object file. */
7424 c_node = cgraph_get_node (fndecl);
7425 c_node = cgraph_function_or_thunk_node (c_node, NULL);
7426 return !cgraph_only_called_directly_p (c_node);
7432 /* Initialize a variable CUM of type CUMULATIVE_ARGS
7433 for a call to a function whose data type is FNTYPE.
7434 For a library call, FNTYPE is 0 and RETURN_MODE the return value mode.
7436 For incoming args we set the number of arguments in the prototype large
7437 so we never return a PARALLEL. */
7440 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
7441 rtx libname ATTRIBUTE_UNUSED, int incoming,
7442 int libcall, int n_named_args,
7443 tree fndecl ATTRIBUTE_UNUSED,
7444 enum machine_mode return_mode ATTRIBUTE_UNUSED)
7446 static CUMULATIVE_ARGS zero_cumulative;
7448 *cum = zero_cumulative;
7450 cum->fregno = FP_ARG_MIN_REG;
7451 cum->vregno = ALTIVEC_ARG_MIN_REG;
7452 cum->prototype = (fntype && prototype_p (fntype));
7453 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
7454 ? CALL_LIBCALL : CALL_NORMAL);
7455 cum->sysv_gregno = GP_ARG_MIN_REG;
7456 cum->stdarg = stdarg_p (fntype);
7458 cum->nargs_prototype = 0;
7459 if (incoming || cum->prototype)
7460 cum->nargs_prototype = n_named_args;
7462 /* Check for a longcall attribute. */
7463 if ((!fntype && rs6000_default_long_calls)
7465 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
7466 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
7467 cum->call_cookie |= CALL_LONG;
7469 if (TARGET_DEBUG_ARG)
7471 fprintf (stderr, "\ninit_cumulative_args:");
7474 tree ret_type = TREE_TYPE (fntype);
7475 fprintf (stderr, " ret code = %s,",
7476 tree_code_name[ (int)TREE_CODE (ret_type) ]);
7479 if (cum->call_cookie & CALL_LONG)
7480 fprintf (stderr, " longcall,");
7482 fprintf (stderr, " proto = %d, nargs = %d\n",
7483 cum->prototype, cum->nargs_prototype);
7486 #ifdef HAVE_AS_GNU_ATTRIBUTE
7487 if (DEFAULT_ABI == ABI_V4)
7489 cum->escapes = call_ABI_of_interest (fndecl);
7496 return_type = TREE_TYPE (fntype);
7497 return_mode = TYPE_MODE (return_type);
7500 return_type = lang_hooks.types.type_for_mode (return_mode, 0);
7502 if (return_type != NULL)
7504 if (TREE_CODE (return_type) == RECORD_TYPE
7505 && TYPE_TRANSPARENT_AGGR (return_type))
7507 return_type = TREE_TYPE (first_field (return_type));
7508 return_mode = TYPE_MODE (return_type);
7510 if (AGGREGATE_TYPE_P (return_type)
7511 && ((unsigned HOST_WIDE_INT) int_size_in_bytes (return_type)
7513 rs6000_returns_struct = true;
7515 if (SCALAR_FLOAT_MODE_P (return_mode))
7516 rs6000_passes_float = true;
7517 else if (ALTIVEC_OR_VSX_VECTOR_MODE (return_mode)
7518 || SPE_VECTOR_MODE (return_mode))
7519 rs6000_passes_vector = true;
7526 && TARGET_ALTIVEC_ABI
7527 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
7529 error ("cannot return value in vector register because"
7530 " altivec instructions are disabled, use -maltivec"
7535 /* Return true if TYPE must be passed on the stack and not in registers. */
7538 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
7540 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
7541 return must_pass_in_stack_var_size (mode, type);
7543 return must_pass_in_stack_var_size_or_pad (mode, type);
7546 /* If defined, a C expression which determines whether, and in which
7547 direction, to pad out an argument with extra space. The value
7548 should be of type `enum direction': either `upward' to pad above
7549 the argument, `downward' to pad below, or `none' to inhibit
7552 For the AIX ABI structs are always stored left shifted in their
7556 function_arg_padding (enum machine_mode mode, const_tree type)
7558 #ifndef AGGREGATE_PADDING_FIXED
7559 #define AGGREGATE_PADDING_FIXED 0
7561 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
7562 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
7565 if (!AGGREGATE_PADDING_FIXED)
7567 /* GCC used to pass structures of the same size as integer types as
7568 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
7569 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
7570 passed padded downward, except that -mstrict-align further
7571 muddied the water in that multi-component structures of 2 and 4
7572 bytes in size were passed padded upward.
7574 The following arranges for best compatibility with previous
7575 versions of gcc, but removes the -mstrict-align dependency. */
7576 if (BYTES_BIG_ENDIAN)
7578 HOST_WIDE_INT size = 0;
7580 if (mode == BLKmode)
7582 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
7583 size = int_size_in_bytes (type);
7586 size = GET_MODE_SIZE (mode);
7588 if (size == 1 || size == 2 || size == 4)
7594 if (AGGREGATES_PAD_UPWARD_ALWAYS)
7596 if (type != 0 && AGGREGATE_TYPE_P (type))
7600 /* Fall back to the default. */
7601 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
7604 /* If defined, a C expression that gives the alignment boundary, in bits,
7605 of an argument with the specified mode and type. If it is not defined,
7606 PARM_BOUNDARY is used for all arguments.
7608 V.4 wants long longs and doubles to be double word aligned. Just
7609 testing the mode size is a boneheaded way to do this as it means
7610 that other types such as complex int are also double word aligned.
7611 However, we're stuck with this because changing the ABI might break
7612 existing library interfaces.
7614 Doubleword align SPE vectors.
7615 Quadword align Altivec/VSX vectors.
7616 Quadword align large synthetic vector types. */
7619 rs6000_function_arg_boundary (enum machine_mode mode, const_tree type)
7621 if (DEFAULT_ABI == ABI_V4
7622 && (GET_MODE_SIZE (mode) == 8
7623 || (TARGET_HARD_FLOAT
7625 && (mode == TFmode || mode == TDmode))))
7627 else if (SPE_VECTOR_MODE (mode)
7628 || (type && TREE_CODE (type) == VECTOR_TYPE
7629 && int_size_in_bytes (type) >= 8
7630 && int_size_in_bytes (type) < 16))
7632 else if (ALTIVEC_OR_VSX_VECTOR_MODE (mode)
7633 || (type && TREE_CODE (type) == VECTOR_TYPE
7634 && int_size_in_bytes (type) >= 16))
7636 else if (TARGET_MACHO
7637 && rs6000_darwin64_abi
7639 && type && TYPE_ALIGN (type) > 64)
7642 return PARM_BOUNDARY;
7645 /* For a function parm of MODE and TYPE, return the starting word in
7646 the parameter area. NWORDS of the parameter area are already used. */
7649 rs6000_parm_start (enum machine_mode mode, const_tree type,
7650 unsigned int nwords)
7653 unsigned int parm_offset;
7655 align = rs6000_function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
7656 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
7657 return nwords + (-(parm_offset + nwords) & align);
7660 /* Compute the size (in words) of a function argument. */
7662 static unsigned long
7663 rs6000_arg_size (enum machine_mode mode, const_tree type)
7667 if (mode != BLKmode)
7668 size = GET_MODE_SIZE (mode);
7670 size = int_size_in_bytes (type);
7673 return (size + 3) >> 2;
7675 return (size + 7) >> 3;
7678 /* Use this to flush pending int fields. */
7681 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
7682 HOST_WIDE_INT bitpos, int final)
7684 unsigned int startbit, endbit;
7685 int intregs, intoffset;
7686 enum machine_mode mode;
7688 /* Handle the situations where a float is taking up the first half
7689 of the GPR, and the other half is empty (typically due to
7690 alignment restrictions). We can detect this by a 8-byte-aligned
7691 int field, or by seeing that this is the final flush for this
7692 argument. Count the word and continue on. */
7693 if (cum->floats_in_gpr == 1
7694 && (cum->intoffset % 64 == 0
7695 || (cum->intoffset == -1 && final)))
7698 cum->floats_in_gpr = 0;
7701 if (cum->intoffset == -1)
7704 intoffset = cum->intoffset;
7705 cum->intoffset = -1;
7706 cum->floats_in_gpr = 0;
7708 if (intoffset % BITS_PER_WORD != 0)
7710 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7712 if (mode == BLKmode)
7714 /* We couldn't find an appropriate mode, which happens,
7715 e.g., in packed structs when there are 3 bytes to load.
7716 Back intoffset back to the beginning of the word in this
7718 intoffset = intoffset & -BITS_PER_WORD;
7722 startbit = intoffset & -BITS_PER_WORD;
7723 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7724 intregs = (endbit - startbit) / BITS_PER_WORD;
7725 cum->words += intregs;
7726 /* words should be unsigned. */
7727 if ((unsigned)cum->words < (endbit/BITS_PER_WORD))
7729 int pad = (endbit/BITS_PER_WORD) - cum->words;
7734 /* The darwin64 ABI calls for us to recurse down through structs,
7735 looking for elements passed in registers. Unfortunately, we have
7736 to track int register count here also because of misalignments
7737 in powerpc alignment mode. */
7740 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
7742 HOST_WIDE_INT startbitpos)
7746 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
7747 if (TREE_CODE (f) == FIELD_DECL)
7749 HOST_WIDE_INT bitpos = startbitpos;
7750 tree ftype = TREE_TYPE (f);
7751 enum machine_mode mode;
7752 if (ftype == error_mark_node)
7754 mode = TYPE_MODE (ftype);
7756 if (DECL_SIZE (f) != 0
7757 && host_integerp (bit_position (f), 1))
7758 bitpos += int_bit_position (f);
7760 /* ??? FIXME: else assume zero offset. */
7762 if (TREE_CODE (ftype) == RECORD_TYPE)
7763 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
7764 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
7766 unsigned n_fpregs = (GET_MODE_SIZE (mode) + 7) >> 3;
7767 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
7768 cum->fregno += n_fpregs;
7769 /* Single-precision floats present a special problem for
7770 us, because they are smaller than an 8-byte GPR, and so
7771 the structure-packing rules combined with the standard
7772 varargs behavior mean that we want to pack float/float
7773 and float/int combinations into a single register's
7774 space. This is complicated by the arg advance flushing,
7775 which works on arbitrarily large groups of int-type
7779 if (cum->floats_in_gpr == 1)
7781 /* Two floats in a word; count the word and reset
7784 cum->floats_in_gpr = 0;
7786 else if (bitpos % 64 == 0)
7788 /* A float at the beginning of an 8-byte word;
7789 count it and put off adjusting cum->words until
7790 we see if a arg advance flush is going to do it
7792 cum->floats_in_gpr++;
7796 /* The float is at the end of a word, preceded
7797 by integer fields, so the arg advance flush
7798 just above has already set cum->words and
7799 everything is taken care of. */
7803 cum->words += n_fpregs;
7805 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
7807 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
7811 else if (cum->intoffset == -1)
7812 cum->intoffset = bitpos;
7816 /* Check for an item that needs to be considered specially under the darwin 64
7817 bit ABI. These are record types where the mode is BLK or the structure is
7820 rs6000_darwin64_struct_check_p (enum machine_mode mode, const_tree type)
7822 return rs6000_darwin64_abi
7823 && ((mode == BLKmode
7824 && TREE_CODE (type) == RECORD_TYPE
7825 && int_size_in_bytes (type) > 0)
7826 || (type && TREE_CODE (type) == RECORD_TYPE
7827 && int_size_in_bytes (type) == 8)) ? 1 : 0;
7830 /* Update the data in CUM to advance over an argument
7831 of mode MODE and data type TYPE.
7832 (TYPE is null for libcalls where that information may not be available.)
7834 Note that for args passed by reference, function_arg will be called
7835 with MODE and TYPE set to that of the pointer to the arg, not the arg
7839 rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7840 const_tree type, bool named, int depth)
7842 /* Only tick off an argument if we're not recursing. */
7844 cum->nargs_prototype--;
7846 #ifdef HAVE_AS_GNU_ATTRIBUTE
7847 if (DEFAULT_ABI == ABI_V4
7850 if (SCALAR_FLOAT_MODE_P (mode))
7851 rs6000_passes_float = true;
7852 else if (named && ALTIVEC_OR_VSX_VECTOR_MODE (mode))
7853 rs6000_passes_vector = true;
7854 else if (SPE_VECTOR_MODE (mode)
7856 && cum->sysv_gregno <= GP_ARG_MAX_REG)
7857 rs6000_passes_vector = true;
7861 if (TARGET_ALTIVEC_ABI
7862 && (ALTIVEC_OR_VSX_VECTOR_MODE (mode)
7863 || (type && TREE_CODE (type) == VECTOR_TYPE
7864 && int_size_in_bytes (type) == 16)))
7868 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
7871 if (!TARGET_ALTIVEC)
7872 error ("cannot pass argument in vector register because"
7873 " altivec instructions are disabled, use -maltivec"
7876 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
7877 even if it is going to be passed in a vector register.
7878 Darwin does the same for variable-argument functions. */
7879 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
7880 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
7890 /* Vector parameters must be 16-byte aligned. This places
7891 them at 2 mod 4 in terms of words in 32-bit mode, since
7892 the parameter save area starts at offset 24 from the
7893 stack. In 64-bit mode, they just have to start on an
7894 even word, since the parameter save area is 16-byte
7895 aligned. Space for GPRs is reserved even if the argument
7896 will be passed in memory. */
7898 align = (2 - cum->words) & 3;
7900 align = cum->words & 1;
7901 cum->words += align + rs6000_arg_size (mode, type);
7903 if (TARGET_DEBUG_ARG)
7905 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
7907 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
7908 cum->nargs_prototype, cum->prototype,
7909 GET_MODE_NAME (mode));
7913 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
7915 && cum->sysv_gregno <= GP_ARG_MAX_REG)
7918 else if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
7920 int size = int_size_in_bytes (type);
7921 /* Variable sized types have size == -1 and are
7922 treated as if consisting entirely of ints.
7923 Pad to 16 byte boundary if needed. */
7924 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7925 && (cum->words % 2) != 0)
7927 /* For varargs, we can just go up by the size of the struct. */
7929 cum->words += (size + 7) / 8;
7932 /* It is tempting to say int register count just goes up by
7933 sizeof(type)/8, but this is wrong in a case such as
7934 { int; double; int; } [powerpc alignment]. We have to
7935 grovel through the fields for these too. */
7937 cum->floats_in_gpr = 0;
7938 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
7939 rs6000_darwin64_record_arg_advance_flush (cum,
7940 size * BITS_PER_UNIT, 1);
7942 if (TARGET_DEBUG_ARG)
7944 fprintf (stderr, "function_adv: words = %2d, align=%d, size=%d",
7945 cum->words, TYPE_ALIGN (type), size);
7947 "nargs = %4d, proto = %d, mode = %4s (darwin64 abi)\n",
7948 cum->nargs_prototype, cum->prototype,
7949 GET_MODE_NAME (mode));
7952 else if (DEFAULT_ABI == ABI_V4)
7954 if (TARGET_HARD_FLOAT && TARGET_FPRS
7955 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
7956 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
7957 || (mode == TFmode && !TARGET_IEEEQUAD)
7958 || mode == SDmode || mode == DDmode || mode == TDmode))
7960 /* _Decimal128 must use an even/odd register pair. This assumes
7961 that the register number is odd when fregno is odd. */
7962 if (mode == TDmode && (cum->fregno % 2) == 1)
7965 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7966 <= FP_ARG_V4_MAX_REG)
7967 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7970 cum->fregno = FP_ARG_V4_MAX_REG + 1;
7971 if (mode == DFmode || mode == TFmode
7972 || mode == DDmode || mode == TDmode)
7973 cum->words += cum->words & 1;
7974 cum->words += rs6000_arg_size (mode, type);
7979 int n_words = rs6000_arg_size (mode, type);
7980 int gregno = cum->sysv_gregno;
7982 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7983 (r7,r8) or (r9,r10). As does any other 2 word item such
7984 as complex int due to a historical mistake. */
7986 gregno += (1 - gregno) & 1;
7988 /* Multi-reg args are not split between registers and stack. */
7989 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7991 /* Long long and SPE vectors are aligned on the stack.
7992 So are other 2 word items such as complex int due to
7993 a historical mistake. */
7995 cum->words += cum->words & 1;
7996 cum->words += n_words;
7999 /* Note: continuing to accumulate gregno past when we've started
8000 spilling to the stack indicates the fact that we've started
8001 spilling to the stack to expand_builtin_saveregs. */
8002 cum->sysv_gregno = gregno + n_words;
8005 if (TARGET_DEBUG_ARG)
8007 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8008 cum->words, cum->fregno);
8009 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
8010 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
8011 fprintf (stderr, "mode = %4s, named = %d\n",
8012 GET_MODE_NAME (mode), named);
8017 int n_words = rs6000_arg_size (mode, type);
8018 int start_words = cum->words;
8019 int align_words = rs6000_parm_start (mode, type, start_words);
8021 cum->words = align_words + n_words;
8023 if (SCALAR_FLOAT_MODE_P (mode)
8024 && TARGET_HARD_FLOAT && TARGET_FPRS)
8026 /* _Decimal128 must be passed in an even/odd float register pair.
8027 This assumes that the register number is odd when fregno is
8029 if (mode == TDmode && (cum->fregno % 2) == 1)
8031 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8034 if (TARGET_DEBUG_ARG)
8036 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8037 cum->words, cum->fregno);
8038 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
8039 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
8040 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
8041 named, align_words - start_words, depth);
8047 rs6000_function_arg_advance (cumulative_args_t cum, enum machine_mode mode,
8048 const_tree type, bool named)
8050 rs6000_function_arg_advance_1 (get_cumulative_args (cum), mode, type, named,
8055 spe_build_register_parallel (enum machine_mode mode, int gregno)
8062 r1 = gen_rtx_REG (DImode, gregno);
8063 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8064 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
8068 r1 = gen_rtx_REG (DImode, gregno);
8069 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8070 r3 = gen_rtx_REG (DImode, gregno + 2);
8071 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8072 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
8075 r1 = gen_rtx_REG (DImode, gregno);
8076 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8077 r3 = gen_rtx_REG (DImode, gregno + 2);
8078 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8079 r5 = gen_rtx_REG (DImode, gregno + 4);
8080 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
8081 r7 = gen_rtx_REG (DImode, gregno + 6);
8082 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
8083 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
8090 /* Determine where to put a SIMD argument on the SPE. */
8092 rs6000_spe_function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
8095 int gregno = cum->sysv_gregno;
8097 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
8098 are passed and returned in a pair of GPRs for ABI compatibility. */
8099 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
8100 || mode == DCmode || mode == TCmode))
8102 int n_words = rs6000_arg_size (mode, type);
8104 /* Doubles go in an odd/even register pair (r5/r6, etc). */
8106 gregno += (1 - gregno) & 1;
8108 /* Multi-reg args are not split between registers and stack. */
8109 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8112 return spe_build_register_parallel (mode, gregno);
8116 int n_words = rs6000_arg_size (mode, type);
8118 /* SPE vectors are put in odd registers. */
8119 if (n_words == 2 && (gregno & 1) == 0)
8122 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
8125 enum machine_mode m = SImode;
8127 r1 = gen_rtx_REG (m, gregno);
8128 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
8129 r2 = gen_rtx_REG (m, gregno + 1);
8130 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
8131 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
8138 if (gregno <= GP_ARG_MAX_REG)
8139 return gen_rtx_REG (mode, gregno);
8145 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
8146 structure between cum->intoffset and bitpos to integer registers. */
8149 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
8150 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
8152 enum machine_mode mode;
8154 unsigned int startbit, endbit;
8155 int this_regno, intregs, intoffset;
8158 if (cum->intoffset == -1)
8161 intoffset = cum->intoffset;
8162 cum->intoffset = -1;
8164 /* If this is the trailing part of a word, try to only load that
8165 much into the register. Otherwise load the whole register. Note
8166 that in the latter case we may pick up unwanted bits. It's not a
8167 problem at the moment but may wish to revisit. */
8169 if (intoffset % BITS_PER_WORD != 0)
8171 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
8173 if (mode == BLKmode)
8175 /* We couldn't find an appropriate mode, which happens,
8176 e.g., in packed structs when there are 3 bytes to load.
8177 Back intoffset back to the beginning of the word in this
8179 intoffset = intoffset & -BITS_PER_WORD;
8186 startbit = intoffset & -BITS_PER_WORD;
8187 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
8188 intregs = (endbit - startbit) / BITS_PER_WORD;
8189 this_regno = cum->words + intoffset / BITS_PER_WORD;
8191 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
8194 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
8198 intoffset /= BITS_PER_UNIT;
8201 regno = GP_ARG_MIN_REG + this_regno;
8202 reg = gen_rtx_REG (mode, regno);
8204 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
8207 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
8211 while (intregs > 0);
8214 /* Recursive workhorse for the following. */
8217 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
8218 HOST_WIDE_INT startbitpos, rtx rvec[],
8223 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
8224 if (TREE_CODE (f) == FIELD_DECL)
8226 HOST_WIDE_INT bitpos = startbitpos;
8227 tree ftype = TREE_TYPE (f);
8228 enum machine_mode mode;
8229 if (ftype == error_mark_node)
8231 mode = TYPE_MODE (ftype);
8233 if (DECL_SIZE (f) != 0
8234 && host_integerp (bit_position (f), 1))
8235 bitpos += int_bit_position (f);
8237 /* ??? FIXME: else assume zero offset. */
8239 if (TREE_CODE (ftype) == RECORD_TYPE)
8240 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
8241 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
8243 unsigned n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
8247 case SCmode: mode = SFmode; break;
8248 case DCmode: mode = DFmode; break;
8249 case TCmode: mode = TFmode; break;
8253 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8254 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
8256 gcc_assert (cum->fregno == FP_ARG_MAX_REG
8257 && (mode == TFmode || mode == TDmode));
8258 /* Long double or _Decimal128 split over regs and memory. */
8259 mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : DFmode;
8263 = gen_rtx_EXPR_LIST (VOIDmode,
8264 gen_rtx_REG (mode, cum->fregno++),
8265 GEN_INT (bitpos / BITS_PER_UNIT));
8266 if (mode == TFmode || mode == TDmode)
8269 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
8271 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8273 = gen_rtx_EXPR_LIST (VOIDmode,
8274 gen_rtx_REG (mode, cum->vregno++),
8275 GEN_INT (bitpos / BITS_PER_UNIT));
8277 else if (cum->intoffset == -1)
8278 cum->intoffset = bitpos;
8282 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
8283 the register(s) to be used for each field and subfield of a struct
8284 being passed by value, along with the offset of where the
8285 register's value may be found in the block. FP fields go in FP
8286 register, vector fields go in vector registers, and everything
8287 else goes in int registers, packed as in memory.
8289 This code is also used for function return values. RETVAL indicates
8290 whether this is the case.
8292 Much of this is taken from the SPARC V9 port, which has a similar
8293 calling convention. */
8296 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
8297 bool named, bool retval)
8299 rtx rvec[FIRST_PSEUDO_REGISTER];
8300 int k = 1, kbase = 1;
8301 HOST_WIDE_INT typesize = int_size_in_bytes (type);
8302 /* This is a copy; modifications are not visible to our caller. */
8303 CUMULATIVE_ARGS copy_cum = *orig_cum;
8304 CUMULATIVE_ARGS *cum = ©_cum;
8306 /* Pad to 16 byte boundary if needed. */
8307 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8308 && (cum->words % 2) != 0)
8315 /* Put entries into rvec[] for individual FP and vector fields, and
8316 for the chunks of memory that go in int regs. Note we start at
8317 element 1; 0 is reserved for an indication of using memory, and
8318 may or may not be filled in below. */
8319 rs6000_darwin64_record_arg_recurse (cum, type, /* startbit pos= */ 0, rvec, &k);
8320 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
8322 /* If any part of the struct went on the stack put all of it there.
8323 This hack is because the generic code for
8324 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
8325 parts of the struct are not at the beginning. */
8329 return NULL_RTX; /* doesn't go in registers at all */
8331 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8333 if (k > 1 || cum->use_stack)
8334 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
8339 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
8342 rs6000_mixed_function_arg (enum machine_mode mode, const_tree type,
8347 rtx rvec[GP_ARG_NUM_REG + 1];
8349 if (align_words >= GP_ARG_NUM_REG)
8352 n_units = rs6000_arg_size (mode, type);
8354 /* Optimize the simple case where the arg fits in one gpr, except in
8355 the case of BLKmode due to assign_parms assuming that registers are
8356 BITS_PER_WORD wide. */
8358 || (n_units == 1 && mode != BLKmode))
8359 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8362 if (align_words + n_units > GP_ARG_NUM_REG)
8363 /* Not all of the arg fits in gprs. Say that it goes in memory too,
8364 using a magic NULL_RTX component.
8365 This is not strictly correct. Only some of the arg belongs in
8366 memory, not all of it. However, the normal scheme using
8367 function_arg_partial_nregs can result in unusual subregs, eg.
8368 (subreg:SI (reg:DF) 4), which are not handled well. The code to
8369 store the whole arg to memory is often more efficient than code
8370 to store pieces, and we know that space is available in the right
8371 place for the whole arg. */
8372 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8377 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
8378 rtx off = GEN_INT (i++ * 4);
8379 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8381 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
8383 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8386 /* Determine where to put an argument to a function.
8387 Value is zero to push the argument on the stack,
8388 or a hard register in which to store the argument.
8390 MODE is the argument's machine mode.
8391 TYPE is the data type of the argument (as a tree).
8392 This is null for libcalls where that information may
8394 CUM is a variable of type CUMULATIVE_ARGS which gives info about
8395 the preceding args and about the function being called. It is
8396 not modified in this routine.
8397 NAMED is nonzero if this argument is a named parameter
8398 (otherwise it is an extra parameter matching an ellipsis).
8400 On RS/6000 the first eight words of non-FP are normally in registers
8401 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
8402 Under V.4, the first 8 FP args are in registers.
8404 If this is floating-point and no prototype is specified, we use
8405 both an FP and integer register (or possibly FP reg and stack). Library
8406 functions (when CALL_LIBCALL is set) always have the proper types for args,
8407 so we can pass the FP value just in one register. emit_library_function
8408 doesn't support PARALLEL anyway.
8410 Note that for args passed by reference, function_arg will be called
8411 with MODE and TYPE set to that of the pointer to the arg, not the arg
8415 rs6000_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
8416 const_tree type, bool named)
8418 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
8419 enum rs6000_abi abi = DEFAULT_ABI;
8421 /* Return a marker to indicate whether CR1 needs to set or clear the
8422 bit that V.4 uses to say fp args were passed in registers.
8423 Assume that we don't need the marker for software floating point,
8424 or compiler generated library calls. */
8425 if (mode == VOIDmode)
8428 && (cum->call_cookie & CALL_LIBCALL) == 0
8430 || (cum->nargs_prototype < 0
8431 && (cum->prototype || TARGET_NO_PROTOTYPE))))
8433 /* For the SPE, we need to crxor CR6 always. */
8435 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
8436 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
8437 return GEN_INT (cum->call_cookie
8438 | ((cum->fregno == FP_ARG_MIN_REG)
8439 ? CALL_V4_SET_FP_ARGS
8440 : CALL_V4_CLEAR_FP_ARGS));
8443 return GEN_INT (cum->call_cookie & ~CALL_LIBCALL);
8446 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8448 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, /*retval= */false);
8449 if (rslt != NULL_RTX)
8451 /* Else fall through to usual handling. */
8454 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
8455 if (TARGET_64BIT && ! cum->prototype)
8457 /* Vector parameters get passed in vector register
8458 and also in GPRs or memory, in absence of prototype. */
8461 align_words = (cum->words + 1) & ~1;
8463 if (align_words >= GP_ARG_NUM_REG)
8469 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8471 return gen_rtx_PARALLEL (mode,
8473 gen_rtx_EXPR_LIST (VOIDmode,
8475 gen_rtx_EXPR_LIST (VOIDmode,
8476 gen_rtx_REG (mode, cum->vregno),
8480 return gen_rtx_REG (mode, cum->vregno);
8481 else if (TARGET_ALTIVEC_ABI
8482 && (ALTIVEC_OR_VSX_VECTOR_MODE (mode)
8483 || (type && TREE_CODE (type) == VECTOR_TYPE
8484 && int_size_in_bytes (type) == 16)))
8486 if (named || abi == ABI_V4)
8490 /* Vector parameters to varargs functions under AIX or Darwin
8491 get passed in memory and possibly also in GPRs. */
8492 int align, align_words, n_words;
8493 enum machine_mode part_mode;
8495 /* Vector parameters must be 16-byte aligned. This places them at
8496 2 mod 4 in terms of words in 32-bit mode, since the parameter
8497 save area starts at offset 24 from the stack. In 64-bit mode,
8498 they just have to start on an even word, since the parameter
8499 save area is 16-byte aligned. */
8501 align = (2 - cum->words) & 3;
8503 align = cum->words & 1;
8504 align_words = cum->words + align;
8506 /* Out of registers? Memory, then. */
8507 if (align_words >= GP_ARG_NUM_REG)
8510 if (TARGET_32BIT && TARGET_POWERPC64)
8511 return rs6000_mixed_function_arg (mode, type, align_words);
8513 /* The vector value goes in GPRs. Only the part of the
8514 value in GPRs is reported here. */
8516 n_words = rs6000_arg_size (mode, type);
8517 if (align_words + n_words > GP_ARG_NUM_REG)
8518 /* Fortunately, there are only two possibilities, the value
8519 is either wholly in GPRs or half in GPRs and half not. */
8522 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
8525 else if (TARGET_SPE_ABI && TARGET_SPE
8526 && (SPE_VECTOR_MODE (mode)
8527 || (TARGET_E500_DOUBLE && (mode == DFmode
8530 || mode == TCmode))))
8531 return rs6000_spe_function_arg (cum, mode, type);
8533 else if (abi == ABI_V4)
8535 if (TARGET_HARD_FLOAT && TARGET_FPRS
8536 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8537 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8538 || (mode == TFmode && !TARGET_IEEEQUAD)
8539 || mode == SDmode || mode == DDmode || mode == TDmode))
8541 /* _Decimal128 must use an even/odd register pair. This assumes
8542 that the register number is odd when fregno is odd. */
8543 if (mode == TDmode && (cum->fregno % 2) == 1)
8546 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8547 <= FP_ARG_V4_MAX_REG)
8548 return gen_rtx_REG (mode, cum->fregno);
8554 int n_words = rs6000_arg_size (mode, type);
8555 int gregno = cum->sysv_gregno;
8557 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8558 (r7,r8) or (r9,r10). As does any other 2 word item such
8559 as complex int due to a historical mistake. */
8561 gregno += (1 - gregno) & 1;
8563 /* Multi-reg args are not split between registers and stack. */
8564 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8567 if (TARGET_32BIT && TARGET_POWERPC64)
8568 return rs6000_mixed_function_arg (mode, type,
8569 gregno - GP_ARG_MIN_REG);
8570 return gen_rtx_REG (mode, gregno);
8575 int align_words = rs6000_parm_start (mode, type, cum->words);
8577 /* _Decimal128 must be passed in an even/odd float register pair.
8578 This assumes that the register number is odd when fregno is odd. */
8579 if (mode == TDmode && (cum->fregno % 2) == 1)
8582 if (USE_FP_FOR_ARG_P (cum, mode, type))
8584 rtx rvec[GP_ARG_NUM_REG + 1];
8588 enum machine_mode fmode = mode;
8589 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
8591 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
8593 /* Currently, we only ever need one reg here because complex
8594 doubles are split. */
8595 gcc_assert (cum->fregno == FP_ARG_MAX_REG
8596 && (fmode == TFmode || fmode == TDmode));
8598 /* Long double or _Decimal128 split over regs and memory. */
8599 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
8602 /* Do we also need to pass this arg in the parameter save
8605 && (cum->nargs_prototype <= 0
8606 || (DEFAULT_ABI == ABI_AIX
8608 && align_words >= GP_ARG_NUM_REG)));
8610 if (!needs_psave && mode == fmode)
8611 return gen_rtx_REG (fmode, cum->fregno);
8616 /* Describe the part that goes in gprs or the stack.
8617 This piece must come first, before the fprs. */
8618 if (align_words < GP_ARG_NUM_REG)
8620 unsigned long n_words = rs6000_arg_size (mode, type);
8622 if (align_words + n_words > GP_ARG_NUM_REG
8623 || (TARGET_32BIT && TARGET_POWERPC64))
8625 /* If this is partially on the stack, then we only
8626 include the portion actually in registers here. */
8627 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
8630 if (align_words + n_words > GP_ARG_NUM_REG)
8631 /* Not all of the arg fits in gprs. Say that it
8632 goes in memory too, using a magic NULL_RTX
8633 component. Also see comment in
8634 rs6000_mixed_function_arg for why the normal
8635 function_arg_partial_nregs scheme doesn't work
8637 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
8641 r = gen_rtx_REG (rmode,
8642 GP_ARG_MIN_REG + align_words);
8643 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
8644 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8646 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
8650 /* The whole arg fits in gprs. */
8651 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8652 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8656 /* It's entirely in memory. */
8657 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8660 /* Describe where this piece goes in the fprs. */
8661 r = gen_rtx_REG (fmode, cum->fregno);
8662 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8664 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8666 else if (align_words < GP_ARG_NUM_REG)
8668 if (TARGET_32BIT && TARGET_POWERPC64)
8669 return rs6000_mixed_function_arg (mode, type, align_words);
8671 if (mode == BLKmode)
8674 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8681 /* For an arg passed partly in registers and partly in memory, this is
8682 the number of bytes passed in registers. For args passed entirely in
8683 registers or entirely in memory, zero. When an arg is described by a
8684 PARALLEL, perhaps using more than one register type, this function
8685 returns the number of bytes used by the first element of the PARALLEL. */
8688 rs6000_arg_partial_bytes (cumulative_args_t cum_v, enum machine_mode mode,
8689 tree type, bool named)
8691 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
8695 if (DEFAULT_ABI == ABI_V4)
8698 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
8699 && cum->nargs_prototype >= 0)
8702 /* In this complicated case we just disable the partial_nregs code. */
8703 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8706 align_words = rs6000_parm_start (mode, type, cum->words);
8708 if (USE_FP_FOR_ARG_P (cum, mode, type))
8710 /* If we are passing this arg in the fixed parameter save area
8711 (gprs or memory) as well as fprs, then this function should
8712 return the number of partial bytes passed in the parameter
8713 save area rather than partial bytes passed in fprs. */
8715 && (cum->nargs_prototype <= 0
8716 || (DEFAULT_ABI == ABI_AIX
8718 && align_words >= GP_ARG_NUM_REG)))
8720 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
8721 > FP_ARG_MAX_REG + 1)
8722 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
8723 else if (cum->nargs_prototype >= 0)
8727 if (align_words < GP_ARG_NUM_REG
8728 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
8729 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
8731 if (ret != 0 && TARGET_DEBUG_ARG)
8732 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
8737 /* A C expression that indicates when an argument must be passed by
8738 reference. If nonzero for an argument, a copy of that argument is
8739 made in memory and a pointer to the argument is passed instead of
8740 the argument itself. The pointer is passed in whatever way is
8741 appropriate for passing a pointer to that type.
8743 Under V.4, aggregates and long double are passed by reference.
8745 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
8746 reference unless the AltiVec vector extension ABI is in force.
8748 As an extension to all ABIs, variable sized types are passed by
8752 rs6000_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED,
8753 enum machine_mode mode, const_tree type,
8754 bool named ATTRIBUTE_UNUSED)
8756 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
8758 if (TARGET_DEBUG_ARG)
8759 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
8766 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
8768 if (TARGET_DEBUG_ARG)
8769 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
8773 if (int_size_in_bytes (type) < 0)
8775 if (TARGET_DEBUG_ARG)
8776 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
8780 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
8781 modes only exist for GCC vector types if -maltivec. */
8782 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
8784 if (TARGET_DEBUG_ARG)
8785 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
8789 /* Pass synthetic vectors in memory. */
8790 if (TREE_CODE (type) == VECTOR_TYPE
8791 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
8793 static bool warned_for_pass_big_vectors = false;
8794 if (TARGET_DEBUG_ARG)
8795 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
8796 if (!warned_for_pass_big_vectors)
8798 warning (0, "GCC vector passed by reference: "
8799 "non-standard ABI extension with no compatibility guarantee");
8800 warned_for_pass_big_vectors = true;
8809 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
8812 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
8817 for (i = 0; i < nregs; i++)
8819 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
8820 if (reload_completed)
8822 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
8825 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
8826 i * GET_MODE_SIZE (reg_mode));
8829 tem = replace_equiv_address (tem, XEXP (tem, 0));
8833 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
8837 /* Perform any needed actions needed for a function that is receiving a
8838 variable number of arguments.
8842 MODE and TYPE are the mode and type of the current parameter.
8844 PRETEND_SIZE is a variable that should be set to the amount of stack
8845 that must be pushed by the prolog to pretend that our caller pushed
8848 Normally, this macro will push all remaining incoming registers on the
8849 stack and set PRETEND_SIZE to the length of the registers pushed. */
8852 setup_incoming_varargs (cumulative_args_t cum, enum machine_mode mode,
8853 tree type, int *pretend_size ATTRIBUTE_UNUSED,
8856 CUMULATIVE_ARGS next_cum;
8857 int reg_size = TARGET_32BIT ? 4 : 8;
8858 rtx save_area = NULL_RTX, mem;
8859 int first_reg_offset;
8862 /* Skip the last named argument. */
8863 next_cum = *get_cumulative_args (cum);
8864 rs6000_function_arg_advance_1 (&next_cum, mode, type, true, 0);
8866 if (DEFAULT_ABI == ABI_V4)
8868 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
8872 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
8873 HOST_WIDE_INT offset = 0;
8875 /* Try to optimize the size of the varargs save area.
8876 The ABI requires that ap.reg_save_area is doubleword
8877 aligned, but we don't need to allocate space for all
8878 the bytes, only those to which we actually will save
8880 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
8881 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
8882 if (TARGET_HARD_FLOAT && TARGET_FPRS
8883 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8884 && cfun->va_list_fpr_size)
8887 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
8888 * UNITS_PER_FP_WORD;
8889 if (cfun->va_list_fpr_size
8890 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8891 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
8893 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8894 * UNITS_PER_FP_WORD;
8898 offset = -((first_reg_offset * reg_size) & ~7);
8899 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
8901 gpr_reg_num = cfun->va_list_gpr_size;
8902 if (reg_size == 4 && (first_reg_offset & 1))
8905 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
8908 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
8910 - (int) (GP_ARG_NUM_REG * reg_size);
8912 if (gpr_size + fpr_size)
8915 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
8916 gcc_assert (GET_CODE (reg_save_area) == MEM);
8917 reg_save_area = XEXP (reg_save_area, 0);
8918 if (GET_CODE (reg_save_area) == PLUS)
8920 gcc_assert (XEXP (reg_save_area, 0)
8921 == virtual_stack_vars_rtx);
8922 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
8923 offset += INTVAL (XEXP (reg_save_area, 1));
8926 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
8929 cfun->machine->varargs_save_offset = offset;
8930 save_area = plus_constant (virtual_stack_vars_rtx, offset);
8935 first_reg_offset = next_cum.words;
8936 save_area = virtual_incoming_args_rtx;
8938 if (targetm.calls.must_pass_in_stack (mode, type))
8939 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
8942 set = get_varargs_alias_set ();
8943 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
8944 && cfun->va_list_gpr_size)
8946 int nregs = GP_ARG_NUM_REG - first_reg_offset;
8948 if (va_list_gpr_counter_field)
8950 /* V4 va_list_gpr_size counts number of registers needed. */
8951 if (nregs > cfun->va_list_gpr_size)
8952 nregs = cfun->va_list_gpr_size;
8956 /* char * va_list instead counts number of bytes needed. */
8957 if (nregs > cfun->va_list_gpr_size / reg_size)
8958 nregs = cfun->va_list_gpr_size / reg_size;
8961 mem = gen_rtx_MEM (BLKmode,
8962 plus_constant (save_area,
8963 first_reg_offset * reg_size));
8964 MEM_NOTRAP_P (mem) = 1;
8965 set_mem_alias_set (mem, set);
8966 set_mem_align (mem, BITS_PER_WORD);
8968 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
8972 /* Save FP registers if needed. */
8973 if (DEFAULT_ABI == ABI_V4
8974 && TARGET_HARD_FLOAT && TARGET_FPRS
8976 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8977 && cfun->va_list_fpr_size)
8979 int fregno = next_cum.fregno, nregs;
8980 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
8981 rtx lab = gen_label_rtx ();
8982 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
8983 * UNITS_PER_FP_WORD);
8986 (gen_rtx_SET (VOIDmode,
8988 gen_rtx_IF_THEN_ELSE (VOIDmode,
8989 gen_rtx_NE (VOIDmode, cr1,
8991 gen_rtx_LABEL_REF (VOIDmode, lab),
8995 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
8996 fregno++, off += UNITS_PER_FP_WORD, nregs++)
8998 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9000 plus_constant (save_area, off));
9001 MEM_NOTRAP_P (mem) = 1;
9002 set_mem_alias_set (mem, set);
9003 set_mem_align (mem, GET_MODE_ALIGNMENT (
9004 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9005 ? DFmode : SFmode));
9006 emit_move_insn (mem, gen_rtx_REG (
9007 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9008 ? DFmode : SFmode, fregno));
9015 /* Create the va_list data type. */
9018 rs6000_build_builtin_va_list (void)
9020 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
9022 /* For AIX, prefer 'char *' because that's what the system
9023 header files like. */
9024 if (DEFAULT_ABI != ABI_V4)
9025 return build_pointer_type (char_type_node);
9027 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
9028 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
9029 get_identifier ("__va_list_tag"), record);
9031 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
9032 unsigned_char_type_node);
9033 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
9034 unsigned_char_type_node);
9035 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
9037 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9038 get_identifier ("reserved"), short_unsigned_type_node);
9039 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9040 get_identifier ("overflow_arg_area"),
9042 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9043 get_identifier ("reg_save_area"),
9046 va_list_gpr_counter_field = f_gpr;
9047 va_list_fpr_counter_field = f_fpr;
9049 DECL_FIELD_CONTEXT (f_gpr) = record;
9050 DECL_FIELD_CONTEXT (f_fpr) = record;
9051 DECL_FIELD_CONTEXT (f_res) = record;
9052 DECL_FIELD_CONTEXT (f_ovf) = record;
9053 DECL_FIELD_CONTEXT (f_sav) = record;
9055 TYPE_STUB_DECL (record) = type_decl;
9056 TYPE_NAME (record) = type_decl;
9057 TYPE_FIELDS (record) = f_gpr;
9058 DECL_CHAIN (f_gpr) = f_fpr;
9059 DECL_CHAIN (f_fpr) = f_res;
9060 DECL_CHAIN (f_res) = f_ovf;
9061 DECL_CHAIN (f_ovf) = f_sav;
9063 layout_type (record);
9065 /* The correct type is an array type of one element. */
9066 return build_array_type (record, build_index_type (size_zero_node));
9069 /* Implement va_start. */
9072 rs6000_va_start (tree valist, rtx nextarg)
9074 HOST_WIDE_INT words, n_gpr, n_fpr;
9075 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9076 tree gpr, fpr, ovf, sav, t;
9078 /* Only SVR4 needs something special. */
9079 if (DEFAULT_ABI != ABI_V4)
9081 std_expand_builtin_va_start (valist, nextarg);
9085 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9086 f_fpr = DECL_CHAIN (f_gpr);
9087 f_res = DECL_CHAIN (f_fpr);
9088 f_ovf = DECL_CHAIN (f_res);
9089 f_sav = DECL_CHAIN (f_ovf);
9091 valist = build_simple_mem_ref (valist);
9092 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9093 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9095 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9097 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9100 /* Count number of gp and fp argument registers used. */
9101 words = crtl->args.info.words;
9102 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
9104 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
9107 if (TARGET_DEBUG_ARG)
9108 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
9109 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
9110 words, n_gpr, n_fpr);
9112 if (cfun->va_list_gpr_size)
9114 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
9115 build_int_cst (NULL_TREE, n_gpr));
9116 TREE_SIDE_EFFECTS (t) = 1;
9117 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9120 if (cfun->va_list_fpr_size)
9122 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
9123 build_int_cst (NULL_TREE, n_fpr));
9124 TREE_SIDE_EFFECTS (t) = 1;
9125 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9127 #ifdef HAVE_AS_GNU_ATTRIBUTE
9128 if (call_ABI_of_interest (cfun->decl))
9129 rs6000_passes_float = true;
9133 /* Find the overflow area. */
9134 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
9136 t = fold_build_pointer_plus_hwi (t, words * UNITS_PER_WORD);
9137 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
9138 TREE_SIDE_EFFECTS (t) = 1;
9139 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9141 /* If there were no va_arg invocations, don't set up the register
9143 if (!cfun->va_list_gpr_size
9144 && !cfun->va_list_fpr_size
9145 && n_gpr < GP_ARG_NUM_REG
9146 && n_fpr < FP_ARG_V4_MAX_REG)
9149 /* Find the register save area. */
9150 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
9151 if (cfun->machine->varargs_save_offset)
9152 t = fold_build_pointer_plus_hwi (t, cfun->machine->varargs_save_offset);
9153 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
9154 TREE_SIDE_EFFECTS (t) = 1;
9155 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9158 /* Implement va_arg. */
9161 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
9164 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9165 tree gpr, fpr, ovf, sav, reg, t, u;
9166 int size, rsize, n_reg, sav_ofs, sav_scale;
9167 tree lab_false, lab_over, addr;
9169 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
9173 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
9175 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
9176 return build_va_arg_indirect_ref (t);
9179 /* We need to deal with the fact that the darwin ppc64 ABI is defined by an
9180 earlier version of gcc, with the property that it always applied alignment
9181 adjustments to the va-args (even for zero-sized types). The cheapest way
9182 to deal with this is to replicate the effect of the part of
9183 std_gimplify_va_arg_expr that carries out the align adjust, for the case
9185 We don't need to check for pass-by-reference because of the test above.
9186 We can return a simplifed answer, since we know there's no offset to add. */
9189 && rs6000_darwin64_abi
9190 && integer_zerop (TYPE_SIZE (type)))
9192 unsigned HOST_WIDE_INT align, boundary;
9193 tree valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
9194 align = PARM_BOUNDARY / BITS_PER_UNIT;
9195 boundary = rs6000_function_arg_boundary (TYPE_MODE (type), type);
9196 if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
9197 boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
9198 boundary /= BITS_PER_UNIT;
9199 if (boundary > align)
9202 /* This updates arg ptr by the amount that would be necessary
9203 to align the zero-sized (but not zero-alignment) item. */
9204 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9205 fold_build_pointer_plus_hwi (valist_tmp, boundary - 1));
9206 gimplify_and_add (t, pre_p);
9208 t = fold_convert (sizetype, valist_tmp);
9209 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9210 fold_convert (TREE_TYPE (valist),
9211 fold_build2 (BIT_AND_EXPR, sizetype, t,
9212 size_int (-boundary))));
9213 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
9214 gimplify_and_add (t, pre_p);
9216 /* Since it is zero-sized there's no increment for the item itself. */
9217 valist_tmp = fold_convert (build_pointer_type (type), valist_tmp);
9218 return build_va_arg_indirect_ref (valist_tmp);
9221 if (DEFAULT_ABI != ABI_V4)
9223 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
9225 tree elem_type = TREE_TYPE (type);
9226 enum machine_mode elem_mode = TYPE_MODE (elem_type);
9227 int elem_size = GET_MODE_SIZE (elem_mode);
9229 if (elem_size < UNITS_PER_WORD)
9231 tree real_part, imag_part;
9232 gimple_seq post = NULL;
9234 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9236 /* Copy the value into a temporary, lest the formal temporary
9237 be reused out from under us. */
9238 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
9239 gimple_seq_add_seq (pre_p, post);
9241 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9244 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
9248 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
9251 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9252 f_fpr = DECL_CHAIN (f_gpr);
9253 f_res = DECL_CHAIN (f_fpr);
9254 f_ovf = DECL_CHAIN (f_res);
9255 f_sav = DECL_CHAIN (f_ovf);
9257 valist = build_va_arg_indirect_ref (valist);
9258 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9259 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9261 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9263 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9266 size = int_size_in_bytes (type);
9267 rsize = (size + 3) / 4;
9270 if (TARGET_HARD_FLOAT && TARGET_FPRS
9271 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
9272 || (TARGET_DOUBLE_FLOAT
9273 && (TYPE_MODE (type) == DFmode
9274 || TYPE_MODE (type) == TFmode
9275 || TYPE_MODE (type) == SDmode
9276 || TYPE_MODE (type) == DDmode
9277 || TYPE_MODE (type) == TDmode))))
9279 /* FP args go in FP registers, if present. */
9281 n_reg = (size + 7) / 8;
9282 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
9283 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
9284 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
9289 /* Otherwise into GP registers. */
9298 /* Pull the value out of the saved registers.... */
9301 addr = create_tmp_var (ptr_type_node, "addr");
9303 /* AltiVec vectors never go in registers when -mabi=altivec. */
9304 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
9308 lab_false = create_artificial_label (input_location);
9309 lab_over = create_artificial_label (input_location);
9311 /* Long long and SPE vectors are aligned in the registers.
9312 As are any other 2 gpr item such as complex int due to a
9313 historical mistake. */
9315 if (n_reg == 2 && reg == gpr)
9318 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9319 build_int_cst (TREE_TYPE (reg), n_reg - 1));
9320 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
9321 unshare_expr (reg), u);
9323 /* _Decimal128 is passed in even/odd fpr pairs; the stored
9324 reg number is 0 for f1, so we want to make it odd. */
9325 else if (reg == fpr && TYPE_MODE (type) == TDmode)
9327 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9328 build_int_cst (TREE_TYPE (reg), 1));
9329 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
9332 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
9333 t = build2 (GE_EXPR, boolean_type_node, u, t);
9334 u = build1 (GOTO_EXPR, void_type_node, lab_false);
9335 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
9336 gimplify_and_add (t, pre_p);
9340 t = fold_build_pointer_plus_hwi (sav, sav_ofs);
9342 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9343 build_int_cst (TREE_TYPE (reg), n_reg));
9344 u = fold_convert (sizetype, u);
9345 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
9346 t = fold_build_pointer_plus (t, u);
9348 /* _Decimal32 varargs are located in the second word of the 64-bit
9349 FP register for 32-bit binaries. */
9350 if (!TARGET_POWERPC64
9351 && TARGET_HARD_FLOAT && TARGET_FPRS
9352 && TYPE_MODE (type) == SDmode)
9353 t = fold_build_pointer_plus_hwi (t, size);
9355 gimplify_assign (addr, t, pre_p);
9357 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
9359 stmt = gimple_build_label (lab_false);
9360 gimple_seq_add_stmt (pre_p, stmt);
9362 if ((n_reg == 2 && !regalign) || n_reg > 2)
9364 /* Ensure that we don't find any more args in regs.
9365 Alignment has taken care of for special cases. */
9366 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
9370 /* ... otherwise out of the overflow area. */
9372 /* Care for on-stack alignment if needed. */
9376 t = fold_build_pointer_plus_hwi (t, align - 1);
9377 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
9378 build_int_cst (TREE_TYPE (t), -align));
9380 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
9382 gimplify_assign (unshare_expr (addr), t, pre_p);
9384 t = fold_build_pointer_plus_hwi (t, size);
9385 gimplify_assign (unshare_expr (ovf), t, pre_p);
9389 stmt = gimple_build_label (lab_over);
9390 gimple_seq_add_stmt (pre_p, stmt);
9393 if (STRICT_ALIGNMENT
9394 && (TYPE_ALIGN (type)
9395 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
9397 /* The value (of type complex double, for example) may not be
9398 aligned in memory in the saved registers, so copy via a
9399 temporary. (This is the same code as used for SPARC.) */
9400 tree tmp = create_tmp_var (type, "va_arg_tmp");
9401 tree dest_addr = build_fold_addr_expr (tmp);
9403 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
9404 3, dest_addr, addr, size_int (rsize * 4));
9406 gimplify_and_add (copy, pre_p);
9410 addr = fold_convert (ptrtype, addr);
9411 return build_va_arg_indirect_ref (addr);
9417 def_builtin (int mask, const char *name, tree type, int code)
9419 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
9422 if (rs6000_builtin_decls[code])
9423 fatal_error ("internal error: builtin function to %s already processed",
9426 rs6000_builtin_decls[code] = t =
9427 add_builtin_function (name, type, code, BUILT_IN_MD,
9430 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT);
9431 switch (builtin_classify[code])
9436 /* assume builtin can do anything. */
9437 case RS6000_BTC_MISC:
9440 /* const function, function only depends on the inputs. */
9441 case RS6000_BTC_CONST:
9442 TREE_READONLY (t) = 1;
9443 TREE_NOTHROW (t) = 1;
9446 /* pure function, function can read global memory. */
9447 case RS6000_BTC_PURE:
9448 DECL_PURE_P (t) = 1;
9449 TREE_NOTHROW (t) = 1;
9452 /* Function is a math function. If rounding mode is on, then treat
9453 the function as not reading global memory, but it can have
9454 arbitrary side effects. If it is off, then assume the function is
9455 a const function. This mimics the ATTR_MATHFN_FPROUNDING
9456 attribute in builtin-attribute.def that is used for the math
9458 case RS6000_BTC_FP_PURE:
9459 TREE_NOTHROW (t) = 1;
9460 if (flag_rounding_math)
9462 DECL_PURE_P (t) = 1;
9463 DECL_IS_NOVOPS (t) = 1;
9466 TREE_READONLY (t) = 1;
9472 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
9474 static const struct builtin_description bdesc_3arg[] =
9476 { MASK_ALTIVEC, CODE_FOR_fmav4sf4, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
9477 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
9478 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
9479 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
9480 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
9481 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
9482 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
9483 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
9484 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
9485 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
9486 { MASK_ALTIVEC, CODE_FOR_nfmsv4sf4, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
9487 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
9488 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
9489 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
9490 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
9491 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
9492 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
9493 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
9494 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
9495 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
9496 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
9497 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
9498 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
9499 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
9500 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
9501 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
9502 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
9503 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
9504 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
9505 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
9506 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
9507 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
9508 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
9509 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
9510 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
9512 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
9513 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
9514 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
9515 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
9516 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
9517 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
9518 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
9519 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
9520 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
9521 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
9522 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
9523 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
9524 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
9525 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
9526 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
9528 { MASK_VSX, CODE_FOR_fmav2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
9529 { MASK_VSX, CODE_FOR_fmsv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
9530 { MASK_VSX, CODE_FOR_nfmav2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
9531 { MASK_VSX, CODE_FOR_nfmsv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
9533 { MASK_VSX, CODE_FOR_fmav4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
9534 { MASK_VSX, CODE_FOR_fmsv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
9535 { MASK_VSX, CODE_FOR_nfmav4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
9536 { MASK_VSX, CODE_FOR_nfmsv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
9538 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
9539 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
9541 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
9542 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
9543 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
9544 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
9545 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
9546 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
9547 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
9548 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
9549 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
9550 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
9552 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
9553 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
9554 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
9555 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
9556 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
9557 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
9558 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
9559 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
9560 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
9561 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
9563 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
9564 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
9565 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
9566 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
9567 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
9568 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
9569 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
9570 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
9571 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
9573 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
9574 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
9575 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
9576 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
9577 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
9578 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
9579 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
9581 { 0, CODE_FOR_fmsv2sf4, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
9582 { 0, CODE_FOR_fmav2sf4, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
9583 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
9584 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
9585 { 0, CODE_FOR_nfmsv2sf4, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
9586 { 0, CODE_FOR_nfmav2sf4, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
9587 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
9588 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
9589 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
9592 /* DST operations: void foo (void *, const int, const char). */
9594 static const struct builtin_description bdesc_dst[] =
9596 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
9597 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
9598 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
9599 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
9601 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
9602 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
9603 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
9604 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
9607 /* Simple binary operations: VECc = foo (VECa, VECb). */
9609 static struct builtin_description bdesc_2arg[] =
9611 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
9612 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
9613 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
9614 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
9615 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
9616 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
9617 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
9618 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
9619 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
9620 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
9621 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
9622 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
9623 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
9624 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
9625 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
9626 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
9627 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
9628 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
9629 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
9630 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
9631 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
9632 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
9633 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
9634 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
9635 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
9636 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
9637 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
9638 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
9639 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
9640 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
9641 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
9642 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
9643 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
9644 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
9645 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
9646 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
9647 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
9648 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
9649 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
9650 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
9651 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
9652 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
9653 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
9654 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
9655 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
9656 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
9657 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
9658 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
9659 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
9660 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
9661 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
9662 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
9663 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
9664 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
9665 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
9666 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
9667 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
9668 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
9669 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
9670 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
9671 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
9672 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
9673 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
9674 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
9675 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
9676 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
9677 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
9678 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
9679 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
9680 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
9681 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
9682 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
9683 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
9684 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
9685 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
9686 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
9687 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
9688 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
9689 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
9690 { MASK_ALTIVEC, CODE_FOR_recipv4sf3, "__builtin_altivec_vrecipdivfp", ALTIVEC_BUILTIN_VRECIPFP },
9691 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
9692 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
9693 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
9694 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
9695 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
9696 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
9697 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
9698 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
9699 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
9700 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
9701 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
9702 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
9703 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
9704 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
9705 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
9706 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
9707 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
9708 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
9709 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
9710 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
9711 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
9712 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
9713 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
9714 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
9715 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
9716 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
9717 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
9718 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
9719 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
9720 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
9721 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
9722 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
9723 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
9724 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
9725 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
9726 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
9727 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
9729 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
9730 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
9731 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
9732 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
9733 { MASK_VSX, CODE_FOR_recipv2df3, "__builtin_vsx_xvrecipdivdp", VSX_BUILTIN_RECIP_V2DF },
9734 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
9735 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
9736 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
9737 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
9738 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
9739 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
9740 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
9742 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
9743 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
9744 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
9745 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
9746 { MASK_VSX, CODE_FOR_recipv4sf3, "__builtin_vsx_xvrecipdivsp", VSX_BUILTIN_RECIP_V4SF },
9747 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
9748 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
9749 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
9750 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
9751 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
9752 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
9753 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
9755 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
9756 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
9757 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
9758 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
9759 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
9760 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
9762 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
9763 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
9764 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
9765 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
9766 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
9767 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
9768 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
9769 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
9770 { MASK_VSX, CODE_FOR_vec_interleave_lowv2df, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF },
9771 { MASK_VSX, CODE_FOR_vec_interleave_lowv2di, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI },
9772 { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF },
9773 { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI },
9775 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
9776 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
9777 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
9778 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
9779 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
9780 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
9781 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
9782 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
9783 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
9784 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
9785 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
9786 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
9787 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
9788 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
9789 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
9790 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
9791 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
9792 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
9793 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
9794 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
9795 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
9796 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
9797 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
9798 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
9799 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
9800 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
9801 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
9802 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
9803 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
9804 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
9805 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
9806 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
9807 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
9808 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
9809 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
9810 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
9811 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
9812 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
9813 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
9814 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
9815 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
9816 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
9817 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
9818 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
9819 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
9820 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
9821 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
9822 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
9823 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
9824 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
9825 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
9826 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
9827 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
9828 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
9829 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
9830 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
9831 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
9832 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
9833 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
9834 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
9835 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
9836 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
9837 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
9838 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
9839 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
9840 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
9841 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
9842 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
9843 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
9844 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
9845 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
9846 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
9847 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
9848 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
9849 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
9850 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
9851 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
9852 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
9853 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
9854 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
9855 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
9856 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
9857 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
9858 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
9859 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
9860 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
9861 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
9862 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
9863 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_recipdiv", ALTIVEC_BUILTIN_VEC_RECIP },
9864 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
9865 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
9866 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
9867 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
9868 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
9869 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
9870 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
9871 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
9872 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
9873 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
9874 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
9875 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
9876 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
9877 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
9878 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
9879 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
9880 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
9881 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
9882 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
9883 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
9884 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
9885 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
9886 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
9887 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
9888 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
9889 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
9890 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
9891 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
9892 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
9893 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
9894 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
9895 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
9896 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
9897 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
9898 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
9899 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
9900 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
9901 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
9902 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
9903 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
9905 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
9906 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
9908 { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
9909 { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
9910 { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
9911 { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
9912 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
9913 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
9914 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
9915 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
9916 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
9917 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
9919 /* Place holder, leave as first spe builtin. */
9920 { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
9921 { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
9922 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
9923 { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
9924 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
9925 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
9926 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
9927 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
9928 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
9929 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
9930 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
9931 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
9932 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
9933 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
9934 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
9935 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
9936 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
9937 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
9938 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
9939 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
9940 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
9941 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
9942 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
9943 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
9944 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
9945 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
9946 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
9947 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
9948 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
9949 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
9950 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
9951 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
9952 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
9953 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
9954 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
9955 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
9956 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
9957 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
9958 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
9959 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
9960 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
9961 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
9962 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
9963 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
9964 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
9965 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
9966 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
9967 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
9968 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
9969 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
9970 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
9971 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
9972 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
9973 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
9974 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
9975 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
9976 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
9977 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
9978 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
9979 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
9980 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
9981 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
9982 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
9983 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
9984 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
9985 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
9986 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
9987 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
9988 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
9989 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
9990 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
9991 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
9992 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
9993 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
9994 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
9995 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
9996 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
9997 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
9998 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
9999 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
10000 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
10001 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
10002 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
10003 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
10004 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
10005 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
10006 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
10007 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
10008 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
10009 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
10010 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
10011 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
10012 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
10013 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
10014 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
10015 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
10016 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
10017 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
10018 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
10019 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
10020 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
10021 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
10022 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
10023 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
10024 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
10025 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
10026 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
10027 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
10028 { 0, CODE_FOR_subv2si3, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
10030 /* SPE binary operations expecting a 5-bit unsigned literal. */
10031 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
10033 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
10034 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
10035 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
10036 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
10037 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
10038 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
10039 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
10040 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
10041 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
10042 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
10043 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
10044 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
10045 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
10046 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
10047 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
10048 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
10049 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
10050 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
10051 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
10052 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
10053 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
10054 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
10055 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
10056 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
10057 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
10058 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
10060 /* Place-holder. Leave as last binary SPE builtin. */
10061 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
10064 /* AltiVec predicates. */
10066 struct builtin_description_predicates
10068 const unsigned int mask;
10069 const enum insn_code icode;
10070 const char *const name;
10071 const enum rs6000_builtins code;
10074 static const struct builtin_description_predicates bdesc_altivec_preds[] =
10076 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
10077 ALTIVEC_BUILTIN_VCMPBFP_P },
10078 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
10079 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
10080 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
10081 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
10082 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
10083 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
10084 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
10085 ALTIVEC_BUILTIN_VCMPEQUW_P },
10086 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
10087 ALTIVEC_BUILTIN_VCMPGTSW_P },
10088 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
10089 ALTIVEC_BUILTIN_VCMPGTUW_P },
10090 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
10091 ALTIVEC_BUILTIN_VCMPEQUH_P },
10092 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
10093 ALTIVEC_BUILTIN_VCMPGTSH_P },
10094 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
10095 ALTIVEC_BUILTIN_VCMPGTUH_P },
10096 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
10097 ALTIVEC_BUILTIN_VCMPEQUB_P },
10098 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
10099 ALTIVEC_BUILTIN_VCMPGTSB_P },
10100 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
10101 ALTIVEC_BUILTIN_VCMPGTUB_P },
10103 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
10104 VSX_BUILTIN_XVCMPEQSP_P },
10105 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
10106 VSX_BUILTIN_XVCMPGESP_P },
10107 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
10108 VSX_BUILTIN_XVCMPGTSP_P },
10109 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
10110 VSX_BUILTIN_XVCMPEQDP_P },
10111 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
10112 VSX_BUILTIN_XVCMPGEDP_P },
10113 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
10114 VSX_BUILTIN_XVCMPGTDP_P },
10116 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
10117 ALTIVEC_BUILTIN_VCMPEQ_P },
10118 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
10119 ALTIVEC_BUILTIN_VCMPGT_P },
10120 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
10121 ALTIVEC_BUILTIN_VCMPGE_P }
10124 /* SPE predicates. */
10125 static struct builtin_description bdesc_spe_predicates[] =
10127 /* Place-holder. Leave as first. */
10128 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
10129 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
10130 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
10131 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
10132 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
10133 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
10134 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
10135 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
10136 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
10137 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
10138 /* Place-holder. Leave as last. */
10139 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
10142 /* SPE evsel predicates. */
10143 static struct builtin_description bdesc_spe_evsel[] =
10145 /* Place-holder. Leave as first. */
10146 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
10147 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
10148 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
10149 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
10150 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
10151 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
10152 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
10153 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
10154 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
10155 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
10156 /* Place-holder. Leave as last. */
10157 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
10160 /* PAIRED predicates. */
10161 static const struct builtin_description bdesc_paired_preds[] =
10163 /* Place-holder. Leave as first. */
10164 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
10165 /* Place-holder. Leave as last. */
10166 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
10169 /* ABS* operations. */
10171 static const struct builtin_description bdesc_abs[] =
10173 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
10174 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
10175 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
10176 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
10177 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
10178 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
10179 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
10180 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
10181 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
10182 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
10183 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
10186 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
10189 static struct builtin_description bdesc_1arg[] =
10191 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
10192 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
10193 { MASK_ALTIVEC, CODE_FOR_rev4sf2, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
10194 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
10195 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
10196 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
10197 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
10198 { MASK_ALTIVEC, CODE_FOR_rsqrtv4sf2, "__builtin_altivec_vrsqrtfp", ALTIVEC_BUILTIN_VRSQRTFP },
10199 { MASK_ALTIVEC, CODE_FOR_rsqrtev4sf2, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
10200 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
10201 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
10202 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
10203 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
10204 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
10205 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
10206 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
10207 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
10208 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
10210 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
10211 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
10212 { MASK_VSX, CODE_FOR_rsqrtv2df2, "__builtin_vsx_xvrsqrtdp", VSX_BUILTIN_VEC_RSQRT_V2DF },
10213 { MASK_VSX, CODE_FOR_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
10214 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
10215 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
10216 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
10218 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
10219 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
10220 { MASK_VSX, CODE_FOR_rsqrtv4sf2, "__builtin_vsx_xvrsqrtsp", VSX_BUILTIN_VEC_RSQRT_V4SF },
10221 { MASK_VSX, CODE_FOR_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
10222 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
10223 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
10224 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
10226 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
10227 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
10228 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
10229 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
10230 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
10231 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
10233 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
10234 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
10235 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
10236 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
10237 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
10238 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
10240 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
10241 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
10242 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
10243 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
10245 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
10246 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
10247 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
10248 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
10249 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
10250 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
10251 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
10252 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
10253 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
10255 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
10256 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
10257 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
10258 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
10259 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
10260 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
10261 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
10262 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
10263 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
10265 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
10266 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
10267 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
10268 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
10269 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
10271 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
10272 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
10273 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
10274 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
10275 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
10276 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
10277 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
10278 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
10279 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
10280 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrt", ALTIVEC_BUILTIN_VEC_RSQRT },
10281 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
10282 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
10283 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
10284 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
10285 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
10286 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
10287 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
10288 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
10289 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
10290 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
10292 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
10293 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
10294 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
10296 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
10297 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
10298 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
10299 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
10301 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
10302 end with SPE_BUILTIN_EVSUBFUSIAAW. */
10303 { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
10304 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
10305 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
10306 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
10307 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
10308 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
10309 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
10310 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
10311 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
10312 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
10313 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
10314 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
10315 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
10316 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
10317 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
10318 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
10319 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
10320 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
10321 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
10322 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
10323 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
10324 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
10325 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
10326 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
10327 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
10328 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
10329 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
10330 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
10332 /* Place-holder. Leave as last unary SPE builtin. */
10333 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
10335 { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
10336 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
10337 { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
10338 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
10339 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
10343 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
10346 tree arg0 = CALL_EXPR_ARG (exp, 0);
10347 rtx op0 = expand_normal (arg0);
10348 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10349 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10351 if (icode == CODE_FOR_nothing)
10352 /* Builtin not supported on this processor. */
10355 /* If we got invalid arguments bail out before generating bad rtl. */
10356 if (arg0 == error_mark_node)
10359 if (icode == CODE_FOR_altivec_vspltisb
10360 || icode == CODE_FOR_altivec_vspltish
10361 || icode == CODE_FOR_altivec_vspltisw
10362 || icode == CODE_FOR_spe_evsplatfi
10363 || icode == CODE_FOR_spe_evsplati)
10365 /* Only allow 5-bit *signed* literals. */
10366 if (GET_CODE (op0) != CONST_INT
10367 || INTVAL (op0) > 15
10368 || INTVAL (op0) < -16)
10370 error ("argument 1 must be a 5-bit signed literal");
10376 || GET_MODE (target) != tmode
10377 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10378 target = gen_reg_rtx (tmode);
10380 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10381 op0 = copy_to_mode_reg (mode0, op0);
10383 pat = GEN_FCN (icode) (target, op0);
10392 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
10394 rtx pat, scratch1, scratch2;
10395 tree arg0 = CALL_EXPR_ARG (exp, 0);
10396 rtx op0 = expand_normal (arg0);
10397 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10398 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10400 /* If we have invalid arguments, bail out before generating bad rtl. */
10401 if (arg0 == error_mark_node)
10405 || GET_MODE (target) != tmode
10406 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10407 target = gen_reg_rtx (tmode);
10409 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10410 op0 = copy_to_mode_reg (mode0, op0);
10412 scratch1 = gen_reg_rtx (mode0);
10413 scratch2 = gen_reg_rtx (mode0);
10415 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
10424 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
10427 tree arg0 = CALL_EXPR_ARG (exp, 0);
10428 tree arg1 = CALL_EXPR_ARG (exp, 1);
10429 rtx op0 = expand_normal (arg0);
10430 rtx op1 = expand_normal (arg1);
10431 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10432 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10433 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10435 if (icode == CODE_FOR_nothing)
10436 /* Builtin not supported on this processor. */
10439 /* If we got invalid arguments bail out before generating bad rtl. */
10440 if (arg0 == error_mark_node || arg1 == error_mark_node)
10443 if (icode == CODE_FOR_altivec_vcfux
10444 || icode == CODE_FOR_altivec_vcfsx
10445 || icode == CODE_FOR_altivec_vctsxs
10446 || icode == CODE_FOR_altivec_vctuxs
10447 || icode == CODE_FOR_altivec_vspltb
10448 || icode == CODE_FOR_altivec_vsplth
10449 || icode == CODE_FOR_altivec_vspltw
10450 || icode == CODE_FOR_spe_evaddiw
10451 || icode == CODE_FOR_spe_evldd
10452 || icode == CODE_FOR_spe_evldh
10453 || icode == CODE_FOR_spe_evldw
10454 || icode == CODE_FOR_spe_evlhhesplat
10455 || icode == CODE_FOR_spe_evlhhossplat
10456 || icode == CODE_FOR_spe_evlhhousplat
10457 || icode == CODE_FOR_spe_evlwhe
10458 || icode == CODE_FOR_spe_evlwhos
10459 || icode == CODE_FOR_spe_evlwhou
10460 || icode == CODE_FOR_spe_evlwhsplat
10461 || icode == CODE_FOR_spe_evlwwsplat
10462 || icode == CODE_FOR_spe_evrlwi
10463 || icode == CODE_FOR_spe_evslwi
10464 || icode == CODE_FOR_spe_evsrwis
10465 || icode == CODE_FOR_spe_evsubifw
10466 || icode == CODE_FOR_spe_evsrwiu)
10468 /* Only allow 5-bit unsigned literals. */
10470 if (TREE_CODE (arg1) != INTEGER_CST
10471 || TREE_INT_CST_LOW (arg1) & ~0x1f)
10473 error ("argument 2 must be a 5-bit unsigned literal");
10479 || GET_MODE (target) != tmode
10480 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10481 target = gen_reg_rtx (tmode);
10483 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10484 op0 = copy_to_mode_reg (mode0, op0);
10485 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10486 op1 = copy_to_mode_reg (mode1, op1);
10488 pat = GEN_FCN (icode) (target, op0, op1);
10497 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10500 tree cr6_form = CALL_EXPR_ARG (exp, 0);
10501 tree arg0 = CALL_EXPR_ARG (exp, 1);
10502 tree arg1 = CALL_EXPR_ARG (exp, 2);
10503 rtx op0 = expand_normal (arg0);
10504 rtx op1 = expand_normal (arg1);
10505 enum machine_mode tmode = SImode;
10506 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10507 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10510 if (TREE_CODE (cr6_form) != INTEGER_CST)
10512 error ("argument 1 of __builtin_altivec_predicate must be a constant");
10516 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
10518 gcc_assert (mode0 == mode1);
10520 /* If we have invalid arguments, bail out before generating bad rtl. */
10521 if (arg0 == error_mark_node || arg1 == error_mark_node)
10525 || GET_MODE (target) != tmode
10526 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10527 target = gen_reg_rtx (tmode);
10529 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10530 op0 = copy_to_mode_reg (mode0, op0);
10531 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10532 op1 = copy_to_mode_reg (mode1, op1);
10534 scratch = gen_reg_rtx (mode0);
10536 pat = GEN_FCN (icode) (scratch, op0, op1);
10541 /* The vec_any* and vec_all* predicates use the same opcodes for two
10542 different operations, but the bits in CR6 will be different
10543 depending on what information we want. So we have to play tricks
10544 with CR6 to get the right bits out.
10546 If you think this is disgusting, look at the specs for the
10547 AltiVec predicates. */
10549 switch (cr6_form_int)
10552 emit_insn (gen_cr6_test_for_zero (target));
10555 emit_insn (gen_cr6_test_for_zero_reverse (target));
10558 emit_insn (gen_cr6_test_for_lt (target));
10561 emit_insn (gen_cr6_test_for_lt_reverse (target));
10564 error ("argument 1 of __builtin_altivec_predicate is out of range");
10572 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
10575 tree arg0 = CALL_EXPR_ARG (exp, 0);
10576 tree arg1 = CALL_EXPR_ARG (exp, 1);
10577 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10578 enum machine_mode mode0 = Pmode;
10579 enum machine_mode mode1 = Pmode;
10580 rtx op0 = expand_normal (arg0);
10581 rtx op1 = expand_normal (arg1);
10583 if (icode == CODE_FOR_nothing)
10584 /* Builtin not supported on this processor. */
10587 /* If we got invalid arguments bail out before generating bad rtl. */
10588 if (arg0 == error_mark_node || arg1 == error_mark_node)
10592 || GET_MODE (target) != tmode
10593 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10594 target = gen_reg_rtx (tmode);
10596 op1 = copy_to_mode_reg (mode1, op1);
10598 if (op0 == const0_rtx)
10600 addr = gen_rtx_MEM (tmode, op1);
10604 op0 = copy_to_mode_reg (mode0, op0);
10605 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
10608 pat = GEN_FCN (icode) (target, addr);
10618 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
10621 tree arg0 = CALL_EXPR_ARG (exp, 0);
10622 tree arg1 = CALL_EXPR_ARG (exp, 1);
10623 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10624 enum machine_mode mode0 = Pmode;
10625 enum machine_mode mode1 = Pmode;
10626 rtx op0 = expand_normal (arg0);
10627 rtx op1 = expand_normal (arg1);
10629 if (icode == CODE_FOR_nothing)
10630 /* Builtin not supported on this processor. */
10633 /* If we got invalid arguments bail out before generating bad rtl. */
10634 if (arg0 == error_mark_node || arg1 == error_mark_node)
10638 || GET_MODE (target) != tmode
10639 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10640 target = gen_reg_rtx (tmode);
10642 op1 = copy_to_mode_reg (mode1, op1);
10644 if (op0 == const0_rtx)
10646 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
10650 op0 = copy_to_mode_reg (mode0, op0);
10651 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
10654 pat = GEN_FCN (icode) (target, addr);
10664 spe_expand_stv_builtin (enum insn_code icode, tree exp)
10666 tree arg0 = CALL_EXPR_ARG (exp, 0);
10667 tree arg1 = CALL_EXPR_ARG (exp, 1);
10668 tree arg2 = CALL_EXPR_ARG (exp, 2);
10669 rtx op0 = expand_normal (arg0);
10670 rtx op1 = expand_normal (arg1);
10671 rtx op2 = expand_normal (arg2);
10673 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
10674 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
10675 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
10677 /* Invalid arguments. Bail before doing anything stoopid! */
10678 if (arg0 == error_mark_node
10679 || arg1 == error_mark_node
10680 || arg2 == error_mark_node)
10683 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
10684 op0 = copy_to_mode_reg (mode2, op0);
10685 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
10686 op1 = copy_to_mode_reg (mode0, op1);
10687 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
10688 op2 = copy_to_mode_reg (mode1, op2);
10690 pat = GEN_FCN (icode) (op1, op2, op0);
10697 paired_expand_stv_builtin (enum insn_code icode, tree exp)
10699 tree arg0 = CALL_EXPR_ARG (exp, 0);
10700 tree arg1 = CALL_EXPR_ARG (exp, 1);
10701 tree arg2 = CALL_EXPR_ARG (exp, 2);
10702 rtx op0 = expand_normal (arg0);
10703 rtx op1 = expand_normal (arg1);
10704 rtx op2 = expand_normal (arg2);
10706 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10707 enum machine_mode mode1 = Pmode;
10708 enum machine_mode mode2 = Pmode;
10710 /* Invalid arguments. Bail before doing anything stoopid! */
10711 if (arg0 == error_mark_node
10712 || arg1 == error_mark_node
10713 || arg2 == error_mark_node)
10716 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
10717 op0 = copy_to_mode_reg (tmode, op0);
10719 op2 = copy_to_mode_reg (mode2, op2);
10721 if (op1 == const0_rtx)
10723 addr = gen_rtx_MEM (tmode, op2);
10727 op1 = copy_to_mode_reg (mode1, op1);
10728 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
10731 pat = GEN_FCN (icode) (addr, op0);
10738 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
10740 tree arg0 = CALL_EXPR_ARG (exp, 0);
10741 tree arg1 = CALL_EXPR_ARG (exp, 1);
10742 tree arg2 = CALL_EXPR_ARG (exp, 2);
10743 rtx op0 = expand_normal (arg0);
10744 rtx op1 = expand_normal (arg1);
10745 rtx op2 = expand_normal (arg2);
10747 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10748 enum machine_mode smode = insn_data[icode].operand[1].mode;
10749 enum machine_mode mode1 = Pmode;
10750 enum machine_mode mode2 = Pmode;
10752 /* Invalid arguments. Bail before doing anything stoopid! */
10753 if (arg0 == error_mark_node
10754 || arg1 == error_mark_node
10755 || arg2 == error_mark_node)
10758 if (! (*insn_data[icode].operand[1].predicate) (op0, smode))
10759 op0 = copy_to_mode_reg (smode, op0);
10761 op2 = copy_to_mode_reg (mode2, op2);
10763 if (op1 == const0_rtx)
10765 addr = gen_rtx_MEM (tmode, op2);
10769 op1 = copy_to_mode_reg (mode1, op1);
10770 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
10773 pat = GEN_FCN (icode) (addr, op0);
10780 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
10783 tree arg0 = CALL_EXPR_ARG (exp, 0);
10784 tree arg1 = CALL_EXPR_ARG (exp, 1);
10785 tree arg2 = CALL_EXPR_ARG (exp, 2);
10786 rtx op0 = expand_normal (arg0);
10787 rtx op1 = expand_normal (arg1);
10788 rtx op2 = expand_normal (arg2);
10789 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10790 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10791 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10792 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
10794 if (icode == CODE_FOR_nothing)
10795 /* Builtin not supported on this processor. */
10798 /* If we got invalid arguments bail out before generating bad rtl. */
10799 if (arg0 == error_mark_node
10800 || arg1 == error_mark_node
10801 || arg2 == error_mark_node)
10804 /* Check and prepare argument depending on the instruction code.
10806 Note that a switch statement instead of the sequence of tests
10807 would be incorrect as many of the CODE_FOR values could be
10808 CODE_FOR_nothing and that would yield multiple alternatives
10809 with identical values. We'd never reach here at runtime in
10811 if (icode == CODE_FOR_altivec_vsldoi_v4sf
10812 || icode == CODE_FOR_altivec_vsldoi_v4si
10813 || icode == CODE_FOR_altivec_vsldoi_v8hi
10814 || icode == CODE_FOR_altivec_vsldoi_v16qi)
10816 /* Only allow 4-bit unsigned literals. */
10818 if (TREE_CODE (arg2) != INTEGER_CST
10819 || TREE_INT_CST_LOW (arg2) & ~0xf)
10821 error ("argument 3 must be a 4-bit unsigned literal");
10825 else if (icode == CODE_FOR_vsx_xxpermdi_v2df
10826 || icode == CODE_FOR_vsx_xxpermdi_v2di
10827 || icode == CODE_FOR_vsx_xxsldwi_v16qi
10828 || icode == CODE_FOR_vsx_xxsldwi_v8hi
10829 || icode == CODE_FOR_vsx_xxsldwi_v4si
10830 || icode == CODE_FOR_vsx_xxsldwi_v4sf
10831 || icode == CODE_FOR_vsx_xxsldwi_v2di
10832 || icode == CODE_FOR_vsx_xxsldwi_v2df)
10834 /* Only allow 2-bit unsigned literals. */
10836 if (TREE_CODE (arg2) != INTEGER_CST
10837 || TREE_INT_CST_LOW (arg2) & ~0x3)
10839 error ("argument 3 must be a 2-bit unsigned literal");
10843 else if (icode == CODE_FOR_vsx_set_v2df
10844 || icode == CODE_FOR_vsx_set_v2di)
10846 /* Only allow 1-bit unsigned literals. */
10848 if (TREE_CODE (arg2) != INTEGER_CST
10849 || TREE_INT_CST_LOW (arg2) & ~0x1)
10851 error ("argument 3 must be a 1-bit unsigned literal");
10857 || GET_MODE (target) != tmode
10858 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10859 target = gen_reg_rtx (tmode);
10861 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10862 op0 = copy_to_mode_reg (mode0, op0);
10863 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10864 op1 = copy_to_mode_reg (mode1, op1);
10865 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
10866 op2 = copy_to_mode_reg (mode2, op2);
10868 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
10869 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
10871 pat = GEN_FCN (icode) (target, op0, op1, op2);
10879 /* Expand the lvx builtins. */
10881 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
10883 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10884 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10886 enum machine_mode tmode, mode0;
10888 enum insn_code icode;
10892 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
10893 icode = CODE_FOR_vector_altivec_load_v16qi;
10895 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
10896 icode = CODE_FOR_vector_altivec_load_v8hi;
10898 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
10899 icode = CODE_FOR_vector_altivec_load_v4si;
10901 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
10902 icode = CODE_FOR_vector_altivec_load_v4sf;
10904 case ALTIVEC_BUILTIN_LD_INTERNAL_2df:
10905 icode = CODE_FOR_vector_altivec_load_v2df;
10907 case ALTIVEC_BUILTIN_LD_INTERNAL_2di:
10908 icode = CODE_FOR_vector_altivec_load_v2di;
10911 *expandedp = false;
10917 arg0 = CALL_EXPR_ARG (exp, 0);
10918 op0 = expand_normal (arg0);
10919 tmode = insn_data[icode].operand[0].mode;
10920 mode0 = insn_data[icode].operand[1].mode;
10923 || GET_MODE (target) != tmode
10924 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10925 target = gen_reg_rtx (tmode);
10927 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10928 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10930 pat = GEN_FCN (icode) (target, op0);
10937 /* Expand the stvx builtins. */
10939 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10942 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10943 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10945 enum machine_mode mode0, mode1;
10947 enum insn_code icode;
10951 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
10952 icode = CODE_FOR_vector_altivec_store_v16qi;
10954 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
10955 icode = CODE_FOR_vector_altivec_store_v8hi;
10957 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
10958 icode = CODE_FOR_vector_altivec_store_v4si;
10960 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
10961 icode = CODE_FOR_vector_altivec_store_v4sf;
10963 case ALTIVEC_BUILTIN_ST_INTERNAL_2df:
10964 icode = CODE_FOR_vector_altivec_store_v2df;
10966 case ALTIVEC_BUILTIN_ST_INTERNAL_2di:
10967 icode = CODE_FOR_vector_altivec_store_v2di;
10970 *expandedp = false;
10974 arg0 = CALL_EXPR_ARG (exp, 0);
10975 arg1 = CALL_EXPR_ARG (exp, 1);
10976 op0 = expand_normal (arg0);
10977 op1 = expand_normal (arg1);
10978 mode0 = insn_data[icode].operand[0].mode;
10979 mode1 = insn_data[icode].operand[1].mode;
10981 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10982 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10983 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
10984 op1 = copy_to_mode_reg (mode1, op1);
10986 pat = GEN_FCN (icode) (op0, op1);
10994 /* Expand the dst builtins. */
10996 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10999 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11000 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11001 tree arg0, arg1, arg2;
11002 enum machine_mode mode0, mode1;
11003 rtx pat, op0, op1, op2;
11004 const struct builtin_description *d;
11007 *expandedp = false;
11009 /* Handle DST variants. */
11011 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
11012 if (d->code == fcode)
11014 arg0 = CALL_EXPR_ARG (exp, 0);
11015 arg1 = CALL_EXPR_ARG (exp, 1);
11016 arg2 = CALL_EXPR_ARG (exp, 2);
11017 op0 = expand_normal (arg0);
11018 op1 = expand_normal (arg1);
11019 op2 = expand_normal (arg2);
11020 mode0 = insn_data[d->icode].operand[0].mode;
11021 mode1 = insn_data[d->icode].operand[1].mode;
11023 /* Invalid arguments, bail out before generating bad rtl. */
11024 if (arg0 == error_mark_node
11025 || arg1 == error_mark_node
11026 || arg2 == error_mark_node)
11031 if (TREE_CODE (arg2) != INTEGER_CST
11032 || TREE_INT_CST_LOW (arg2) & ~0x3)
11034 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
11038 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
11039 op0 = copy_to_mode_reg (Pmode, op0);
11040 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
11041 op1 = copy_to_mode_reg (mode1, op1);
11043 pat = GEN_FCN (d->icode) (op0, op1, op2);
11053 /* Expand vec_init builtin. */
11055 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
11057 enum machine_mode tmode = TYPE_MODE (type);
11058 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
11059 int i, n_elt = GET_MODE_NUNITS (tmode);
11060 rtvec v = rtvec_alloc (n_elt);
11062 gcc_assert (VECTOR_MODE_P (tmode));
11063 gcc_assert (n_elt == call_expr_nargs (exp));
11065 for (i = 0; i < n_elt; ++i)
11067 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
11068 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
11071 if (!target || !register_operand (target, tmode))
11072 target = gen_reg_rtx (tmode);
11074 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
11078 /* Return the integer constant in ARG. Constrain it to be in the range
11079 of the subparts of VEC_TYPE; issue an error if not. */
11082 get_element_number (tree vec_type, tree arg)
11084 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
11086 if (!host_integerp (arg, 1)
11087 || (elt = tree_low_cst (arg, 1), elt > max))
11089 error ("selector must be an integer constant in the range 0..%wi", max);
11096 /* Expand vec_set builtin. */
11098 altivec_expand_vec_set_builtin (tree exp)
11100 enum machine_mode tmode, mode1;
11101 tree arg0, arg1, arg2;
11105 arg0 = CALL_EXPR_ARG (exp, 0);
11106 arg1 = CALL_EXPR_ARG (exp, 1);
11107 arg2 = CALL_EXPR_ARG (exp, 2);
11109 tmode = TYPE_MODE (TREE_TYPE (arg0));
11110 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11111 gcc_assert (VECTOR_MODE_P (tmode));
11113 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
11114 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
11115 elt = get_element_number (TREE_TYPE (arg0), arg2);
11117 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
11118 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
11120 op0 = force_reg (tmode, op0);
11121 op1 = force_reg (mode1, op1);
11123 rs6000_expand_vector_set (op0, op1, elt);
11128 /* Expand vec_ext builtin. */
11130 altivec_expand_vec_ext_builtin (tree exp, rtx target)
11132 enum machine_mode tmode, mode0;
11137 arg0 = CALL_EXPR_ARG (exp, 0);
11138 arg1 = CALL_EXPR_ARG (exp, 1);
11140 op0 = expand_normal (arg0);
11141 elt = get_element_number (TREE_TYPE (arg0), arg1);
11143 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11144 mode0 = TYPE_MODE (TREE_TYPE (arg0));
11145 gcc_assert (VECTOR_MODE_P (mode0));
11147 op0 = force_reg (mode0, op0);
11149 if (optimize || !target || !register_operand (target, tmode))
11150 target = gen_reg_rtx (tmode);
11152 rs6000_expand_vector_extract (target, op0, elt);
11157 /* Expand the builtin in EXP and store the result in TARGET. Store
11158 true in *EXPANDEDP if we found a builtin to expand. */
11160 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
11162 const struct builtin_description *d;
11163 const struct builtin_description_predicates *dp;
11165 enum insn_code icode;
11166 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11169 enum machine_mode tmode, mode0;
11170 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11172 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11173 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11174 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
11175 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
11178 error ("unresolved overload for Altivec builtin %qF", fndecl);
11182 target = altivec_expand_ld_builtin (exp, target, expandedp);
11186 target = altivec_expand_st_builtin (exp, target, expandedp);
11190 target = altivec_expand_dst_builtin (exp, target, expandedp);
11198 case ALTIVEC_BUILTIN_STVX:
11199 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v4si, exp);
11200 case ALTIVEC_BUILTIN_STVEBX:
11201 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
11202 case ALTIVEC_BUILTIN_STVEHX:
11203 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
11204 case ALTIVEC_BUILTIN_STVEWX:
11205 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
11206 case ALTIVEC_BUILTIN_STVXL:
11207 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
11209 case ALTIVEC_BUILTIN_STVLX:
11210 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
11211 case ALTIVEC_BUILTIN_STVLXL:
11212 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
11213 case ALTIVEC_BUILTIN_STVRX:
11214 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
11215 case ALTIVEC_BUILTIN_STVRXL:
11216 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
11218 case VSX_BUILTIN_STXVD2X_V2DF:
11219 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2df, exp);
11220 case VSX_BUILTIN_STXVD2X_V2DI:
11221 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2di, exp);
11222 case VSX_BUILTIN_STXVW4X_V4SF:
11223 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4sf, exp);
11224 case VSX_BUILTIN_STXVW4X_V4SI:
11225 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4si, exp);
11226 case VSX_BUILTIN_STXVW4X_V8HI:
11227 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v8hi, exp);
11228 case VSX_BUILTIN_STXVW4X_V16QI:
11229 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v16qi, exp);
11231 case ALTIVEC_BUILTIN_MFVSCR:
11232 icode = CODE_FOR_altivec_mfvscr;
11233 tmode = insn_data[icode].operand[0].mode;
11236 || GET_MODE (target) != tmode
11237 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11238 target = gen_reg_rtx (tmode);
11240 pat = GEN_FCN (icode) (target);
11246 case ALTIVEC_BUILTIN_MTVSCR:
11247 icode = CODE_FOR_altivec_mtvscr;
11248 arg0 = CALL_EXPR_ARG (exp, 0);
11249 op0 = expand_normal (arg0);
11250 mode0 = insn_data[icode].operand[0].mode;
11252 /* If we got invalid arguments bail out before generating bad rtl. */
11253 if (arg0 == error_mark_node)
11256 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11257 op0 = copy_to_mode_reg (mode0, op0);
11259 pat = GEN_FCN (icode) (op0);
11264 case ALTIVEC_BUILTIN_DSSALL:
11265 emit_insn (gen_altivec_dssall ());
11268 case ALTIVEC_BUILTIN_DSS:
11269 icode = CODE_FOR_altivec_dss;
11270 arg0 = CALL_EXPR_ARG (exp, 0);
11272 op0 = expand_normal (arg0);
11273 mode0 = insn_data[icode].operand[0].mode;
11275 /* If we got invalid arguments bail out before generating bad rtl. */
11276 if (arg0 == error_mark_node)
11279 if (TREE_CODE (arg0) != INTEGER_CST
11280 || TREE_INT_CST_LOW (arg0) & ~0x3)
11282 error ("argument to dss must be a 2-bit unsigned literal");
11286 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11287 op0 = copy_to_mode_reg (mode0, op0);
11289 emit_insn (gen_altivec_dss (op0));
11292 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
11293 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
11294 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
11295 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
11296 case VSX_BUILTIN_VEC_INIT_V2DF:
11297 case VSX_BUILTIN_VEC_INIT_V2DI:
11298 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
11300 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
11301 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
11302 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
11303 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
11304 case VSX_BUILTIN_VEC_SET_V2DF:
11305 case VSX_BUILTIN_VEC_SET_V2DI:
11306 return altivec_expand_vec_set_builtin (exp);
11308 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
11309 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
11310 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
11311 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
11312 case VSX_BUILTIN_VEC_EXT_V2DF:
11313 case VSX_BUILTIN_VEC_EXT_V2DI:
11314 return altivec_expand_vec_ext_builtin (exp, target);
11318 /* Fall through. */
11321 /* Expand abs* operations. */
11323 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11324 if (d->code == fcode)
11325 return altivec_expand_abs_builtin (d->icode, exp, target);
11327 /* Expand the AltiVec predicates. */
11328 dp = bdesc_altivec_preds;
11329 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11330 if (dp->code == fcode)
11331 return altivec_expand_predicate_builtin (dp->icode, exp, target);
11333 /* LV* are funky. We initialized them differently. */
11336 case ALTIVEC_BUILTIN_LVSL:
11337 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
11338 exp, target, false);
11339 case ALTIVEC_BUILTIN_LVSR:
11340 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
11341 exp, target, false);
11342 case ALTIVEC_BUILTIN_LVEBX:
11343 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
11344 exp, target, false);
11345 case ALTIVEC_BUILTIN_LVEHX:
11346 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
11347 exp, target, false);
11348 case ALTIVEC_BUILTIN_LVEWX:
11349 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
11350 exp, target, false);
11351 case ALTIVEC_BUILTIN_LVXL:
11352 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
11353 exp, target, false);
11354 case ALTIVEC_BUILTIN_LVX:
11355 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v4si,
11356 exp, target, false);
11357 case ALTIVEC_BUILTIN_LVLX:
11358 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
11359 exp, target, true);
11360 case ALTIVEC_BUILTIN_LVLXL:
11361 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
11362 exp, target, true);
11363 case ALTIVEC_BUILTIN_LVRX:
11364 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
11365 exp, target, true);
11366 case ALTIVEC_BUILTIN_LVRXL:
11367 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
11368 exp, target, true);
11369 case VSX_BUILTIN_LXVD2X_V2DF:
11370 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2df,
11371 exp, target, false);
11372 case VSX_BUILTIN_LXVD2X_V2DI:
11373 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2di,
11374 exp, target, false);
11375 case VSX_BUILTIN_LXVW4X_V4SF:
11376 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4sf,
11377 exp, target, false);
11378 case VSX_BUILTIN_LXVW4X_V4SI:
11379 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4si,
11380 exp, target, false);
11381 case VSX_BUILTIN_LXVW4X_V8HI:
11382 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v8hi,
11383 exp, target, false);
11384 case VSX_BUILTIN_LXVW4X_V16QI:
11385 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v16qi,
11386 exp, target, false);
11390 /* Fall through. */
11393 *expandedp = false;
11397 /* Expand the builtin in EXP and store the result in TARGET. Store
11398 true in *EXPANDEDP if we found a builtin to expand. */
11400 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
11402 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11403 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11404 const struct builtin_description *d;
11411 case PAIRED_BUILTIN_STX:
11412 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
11413 case PAIRED_BUILTIN_LX:
11414 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
11417 /* Fall through. */
11420 /* Expand the paired predicates. */
11421 d = bdesc_paired_preds;
11422 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
11423 if (d->code == fcode)
11424 return paired_expand_predicate_builtin (d->icode, exp, target);
11426 *expandedp = false;
11430 /* Binops that need to be initialized manually, but can be expanded
11431 automagically by rs6000_expand_binop_builtin. */
11432 static struct builtin_description bdesc_2arg_spe[] =
11434 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
11435 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
11436 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
11437 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
11438 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
11439 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
11440 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
11441 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
11442 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
11443 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
11444 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
11445 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
11446 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
11447 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
11448 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
11449 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
11450 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
11451 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
11452 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
11453 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
11454 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
11455 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
11458 /* Expand the builtin in EXP and store the result in TARGET. Store
11459 true in *EXPANDEDP if we found a builtin to expand.
11461 This expands the SPE builtins that are not simple unary and binary
11464 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
11466 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11468 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11469 enum insn_code icode;
11470 enum machine_mode tmode, mode0;
11472 struct builtin_description *d;
11477 /* Syntax check for a 5-bit unsigned immediate. */
11480 case SPE_BUILTIN_EVSTDD:
11481 case SPE_BUILTIN_EVSTDH:
11482 case SPE_BUILTIN_EVSTDW:
11483 case SPE_BUILTIN_EVSTWHE:
11484 case SPE_BUILTIN_EVSTWHO:
11485 case SPE_BUILTIN_EVSTWWE:
11486 case SPE_BUILTIN_EVSTWWO:
11487 arg1 = CALL_EXPR_ARG (exp, 2);
11488 if (TREE_CODE (arg1) != INTEGER_CST
11489 || TREE_INT_CST_LOW (arg1) & ~0x1f)
11491 error ("argument 2 must be a 5-bit unsigned literal");
11499 /* The evsplat*i instructions are not quite generic. */
11502 case SPE_BUILTIN_EVSPLATFI:
11503 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
11505 case SPE_BUILTIN_EVSPLATI:
11506 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
11512 d = (struct builtin_description *) bdesc_2arg_spe;
11513 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
11514 if (d->code == fcode)
11515 return rs6000_expand_binop_builtin (d->icode, exp, target);
11517 d = (struct builtin_description *) bdesc_spe_predicates;
11518 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
11519 if (d->code == fcode)
11520 return spe_expand_predicate_builtin (d->icode, exp, target);
11522 d = (struct builtin_description *) bdesc_spe_evsel;
11523 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
11524 if (d->code == fcode)
11525 return spe_expand_evsel_builtin (d->icode, exp, target);
11529 case SPE_BUILTIN_EVSTDDX:
11530 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
11531 case SPE_BUILTIN_EVSTDHX:
11532 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
11533 case SPE_BUILTIN_EVSTDWX:
11534 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
11535 case SPE_BUILTIN_EVSTWHEX:
11536 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
11537 case SPE_BUILTIN_EVSTWHOX:
11538 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
11539 case SPE_BUILTIN_EVSTWWEX:
11540 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
11541 case SPE_BUILTIN_EVSTWWOX:
11542 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
11543 case SPE_BUILTIN_EVSTDD:
11544 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
11545 case SPE_BUILTIN_EVSTDH:
11546 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
11547 case SPE_BUILTIN_EVSTDW:
11548 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
11549 case SPE_BUILTIN_EVSTWHE:
11550 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
11551 case SPE_BUILTIN_EVSTWHO:
11552 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
11553 case SPE_BUILTIN_EVSTWWE:
11554 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
11555 case SPE_BUILTIN_EVSTWWO:
11556 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
11557 case SPE_BUILTIN_MFSPEFSCR:
11558 icode = CODE_FOR_spe_mfspefscr;
11559 tmode = insn_data[icode].operand[0].mode;
11562 || GET_MODE (target) != tmode
11563 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11564 target = gen_reg_rtx (tmode);
11566 pat = GEN_FCN (icode) (target);
11571 case SPE_BUILTIN_MTSPEFSCR:
11572 icode = CODE_FOR_spe_mtspefscr;
11573 arg0 = CALL_EXPR_ARG (exp, 0);
11574 op0 = expand_normal (arg0);
11575 mode0 = insn_data[icode].operand[0].mode;
11577 if (arg0 == error_mark_node)
11580 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11581 op0 = copy_to_mode_reg (mode0, op0);
11583 pat = GEN_FCN (icode) (op0);
11591 *expandedp = false;
11596 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11598 rtx pat, scratch, tmp;
11599 tree form = CALL_EXPR_ARG (exp, 0);
11600 tree arg0 = CALL_EXPR_ARG (exp, 1);
11601 tree arg1 = CALL_EXPR_ARG (exp, 2);
11602 rtx op0 = expand_normal (arg0);
11603 rtx op1 = expand_normal (arg1);
11604 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11605 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11607 enum rtx_code code;
11609 if (TREE_CODE (form) != INTEGER_CST)
11611 error ("argument 1 of __builtin_paired_predicate must be a constant");
11615 form_int = TREE_INT_CST_LOW (form);
11617 gcc_assert (mode0 == mode1);
11619 if (arg0 == error_mark_node || arg1 == error_mark_node)
11623 || GET_MODE (target) != SImode
11624 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
11625 target = gen_reg_rtx (SImode);
11626 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
11627 op0 = copy_to_mode_reg (mode0, op0);
11628 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
11629 op1 = copy_to_mode_reg (mode1, op1);
11631 scratch = gen_reg_rtx (CCFPmode);
11633 pat = GEN_FCN (icode) (scratch, op0, op1);
11655 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11658 error ("argument 1 of __builtin_paired_predicate is out of range");
11662 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11663 emit_move_insn (target, tmp);
11668 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11670 rtx pat, scratch, tmp;
11671 tree form = CALL_EXPR_ARG (exp, 0);
11672 tree arg0 = CALL_EXPR_ARG (exp, 1);
11673 tree arg1 = CALL_EXPR_ARG (exp, 2);
11674 rtx op0 = expand_normal (arg0);
11675 rtx op1 = expand_normal (arg1);
11676 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11677 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11679 enum rtx_code code;
11681 if (TREE_CODE (form) != INTEGER_CST)
11683 error ("argument 1 of __builtin_spe_predicate must be a constant");
11687 form_int = TREE_INT_CST_LOW (form);
11689 gcc_assert (mode0 == mode1);
11691 if (arg0 == error_mark_node || arg1 == error_mark_node)
11695 || GET_MODE (target) != SImode
11696 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
11697 target = gen_reg_rtx (SImode);
11699 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11700 op0 = copy_to_mode_reg (mode0, op0);
11701 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11702 op1 = copy_to_mode_reg (mode1, op1);
11704 scratch = gen_reg_rtx (CCmode);
11706 pat = GEN_FCN (icode) (scratch, op0, op1);
11711 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
11712 _lower_. We use one compare, but look in different bits of the
11713 CR for each variant.
11715 There are 2 elements in each SPE simd type (upper/lower). The CR
11716 bits are set as follows:
11718 BIT0 | BIT 1 | BIT 2 | BIT 3
11719 U | L | (U | L) | (U & L)
11721 So, for an "all" relationship, BIT 3 would be set.
11722 For an "any" relationship, BIT 2 would be set. Etc.
11724 Following traditional nomenclature, these bits map to:
11726 BIT0 | BIT 1 | BIT 2 | BIT 3
11729 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
11734 /* All variant. OV bit. */
11736 /* We need to get to the OV bit, which is the ORDERED bit. We
11737 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
11738 that's ugly and will make validate_condition_mode die.
11739 So let's just use another pattern. */
11740 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11742 /* Any variant. EQ bit. */
11746 /* Upper variant. LT bit. */
11750 /* Lower variant. GT bit. */
11755 error ("argument 1 of __builtin_spe_predicate is out of range");
11759 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11760 emit_move_insn (target, tmp);
11765 /* The evsel builtins look like this:
11767 e = __builtin_spe_evsel_OP (a, b, c, d);
11769 and work like this:
11771 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
11772 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
11776 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
11779 tree arg0 = CALL_EXPR_ARG (exp, 0);
11780 tree arg1 = CALL_EXPR_ARG (exp, 1);
11781 tree arg2 = CALL_EXPR_ARG (exp, 2);
11782 tree arg3 = CALL_EXPR_ARG (exp, 3);
11783 rtx op0 = expand_normal (arg0);
11784 rtx op1 = expand_normal (arg1);
11785 rtx op2 = expand_normal (arg2);
11786 rtx op3 = expand_normal (arg3);
11787 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11788 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11790 gcc_assert (mode0 == mode1);
11792 if (arg0 == error_mark_node || arg1 == error_mark_node
11793 || arg2 == error_mark_node || arg3 == error_mark_node)
11797 || GET_MODE (target) != mode0
11798 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
11799 target = gen_reg_rtx (mode0);
11801 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11802 op0 = copy_to_mode_reg (mode0, op0);
11803 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11804 op1 = copy_to_mode_reg (mode0, op1);
11805 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
11806 op2 = copy_to_mode_reg (mode0, op2);
11807 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
11808 op3 = copy_to_mode_reg (mode0, op3);
11810 /* Generate the compare. */
11811 scratch = gen_reg_rtx (CCmode);
11812 pat = GEN_FCN (icode) (scratch, op0, op1);
11817 if (mode0 == V2SImode)
11818 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
11820 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
11825 /* Expand an expression EXP that calls a built-in function,
11826 with result going to TARGET if that's convenient
11827 (and in mode MODE if that's convenient).
11828 SUBTARGET may be used as the target for computing one of EXP's operands.
11829 IGNORE is nonzero if the value is to be ignored. */
11832 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
11833 enum machine_mode mode ATTRIBUTE_UNUSED,
11834 int ignore ATTRIBUTE_UNUSED)
11836 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11837 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11838 const struct builtin_description *d;
11845 case RS6000_BUILTIN_RECIP:
11846 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
11848 case RS6000_BUILTIN_RECIPF:
11849 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
11851 case RS6000_BUILTIN_RSQRTF:
11852 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
11854 case RS6000_BUILTIN_RSQRT:
11855 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2, exp, target);
11857 case RS6000_BUILTIN_BSWAP_HI:
11858 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
11860 case POWER7_BUILTIN_BPERMD:
11861 return rs6000_expand_binop_builtin (((TARGET_64BIT)
11862 ? CODE_FOR_bpermd_di
11863 : CODE_FOR_bpermd_si), exp, target);
11865 case ALTIVEC_BUILTIN_MASK_FOR_LOAD:
11866 case ALTIVEC_BUILTIN_MASK_FOR_STORE:
11868 int icode = (int) CODE_FOR_altivec_lvsr;
11869 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11870 enum machine_mode mode = insn_data[icode].operand[1].mode;
11874 gcc_assert (TARGET_ALTIVEC);
11876 arg = CALL_EXPR_ARG (exp, 0);
11877 gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg)));
11878 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
11879 addr = memory_address (mode, op);
11880 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
11884 /* For the load case need to negate the address. */
11885 op = gen_reg_rtx (GET_MODE (addr));
11886 emit_insn (gen_rtx_SET (VOIDmode, op,
11887 gen_rtx_NEG (GET_MODE (addr), addr)));
11889 op = gen_rtx_MEM (mode, op);
11892 || GET_MODE (target) != tmode
11893 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11894 target = gen_reg_rtx (tmode);
11896 /*pat = gen_altivec_lvsr (target, op);*/
11897 pat = GEN_FCN (icode) (target, op);
11905 case ALTIVEC_BUILTIN_VCFUX:
11906 case ALTIVEC_BUILTIN_VCFSX:
11907 case ALTIVEC_BUILTIN_VCTUXS:
11908 case ALTIVEC_BUILTIN_VCTSXS:
11909 /* FIXME: There's got to be a nicer way to handle this case than
11910 constructing a new CALL_EXPR. */
11911 if (call_expr_nargs (exp) == 1)
11913 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
11914 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
11922 if (TARGET_ALTIVEC)
11924 ret = altivec_expand_builtin (exp, target, &success);
11931 ret = spe_expand_builtin (exp, target, &success);
11936 if (TARGET_PAIRED_FLOAT)
11938 ret = paired_expand_builtin (exp, target, &success);
11944 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
11946 /* Handle simple unary operations. */
11947 d = (struct builtin_description *) bdesc_1arg;
11948 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
11949 if (d->code == fcode)
11950 return rs6000_expand_unop_builtin (d->icode, exp, target);
11952 /* Handle simple binary operations. */
11953 d = (struct builtin_description *) bdesc_2arg;
11954 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
11955 if (d->code == fcode)
11956 return rs6000_expand_binop_builtin (d->icode, exp, target);
11958 /* Handle simple ternary operations. */
11960 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
11961 if (d->code == fcode)
11962 return rs6000_expand_ternop_builtin (d->icode, exp, target);
11964 gcc_unreachable ();
11968 rs6000_init_builtins (void)
11973 V2SI_type_node = build_vector_type (intSI_type_node, 2);
11974 V2SF_type_node = build_vector_type (float_type_node, 2);
11975 V2DI_type_node = build_vector_type (intDI_type_node, 2);
11976 V2DF_type_node = build_vector_type (double_type_node, 2);
11977 V4HI_type_node = build_vector_type (intHI_type_node, 4);
11978 V4SI_type_node = build_vector_type (intSI_type_node, 4);
11979 V4SF_type_node = build_vector_type (float_type_node, 4);
11980 V8HI_type_node = build_vector_type (intHI_type_node, 8);
11981 V16QI_type_node = build_vector_type (intQI_type_node, 16);
11983 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
11984 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
11985 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
11986 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
11988 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
11989 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
11990 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
11991 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
11993 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
11994 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
11995 'vector unsigned short'. */
11997 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
11998 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
11999 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
12000 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
12001 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12003 long_integer_type_internal_node = long_integer_type_node;
12004 long_unsigned_type_internal_node = long_unsigned_type_node;
12005 long_long_integer_type_internal_node = long_long_integer_type_node;
12006 long_long_unsigned_type_internal_node = long_long_unsigned_type_node;
12007 intQI_type_internal_node = intQI_type_node;
12008 uintQI_type_internal_node = unsigned_intQI_type_node;
12009 intHI_type_internal_node = intHI_type_node;
12010 uintHI_type_internal_node = unsigned_intHI_type_node;
12011 intSI_type_internal_node = intSI_type_node;
12012 uintSI_type_internal_node = unsigned_intSI_type_node;
12013 intDI_type_internal_node = intDI_type_node;
12014 uintDI_type_internal_node = unsigned_intDI_type_node;
12015 float_type_internal_node = float_type_node;
12016 double_type_internal_node = double_type_node;
12017 void_type_internal_node = void_type_node;
12019 /* Initialize the modes for builtin_function_type, mapping a machine mode to
12021 builtin_mode_to_type[QImode][0] = integer_type_node;
12022 builtin_mode_to_type[HImode][0] = integer_type_node;
12023 builtin_mode_to_type[SImode][0] = intSI_type_node;
12024 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
12025 builtin_mode_to_type[DImode][0] = intDI_type_node;
12026 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
12027 builtin_mode_to_type[SFmode][0] = float_type_node;
12028 builtin_mode_to_type[DFmode][0] = double_type_node;
12029 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
12030 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
12031 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
12032 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
12033 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
12034 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
12035 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
12036 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
12037 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
12038 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
12039 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
12040 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
12041 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
12043 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12044 get_identifier ("__bool char"),
12045 bool_char_type_node);
12046 TYPE_NAME (bool_char_type_node) = tdecl;
12047 (*lang_hooks.decls.pushdecl) (tdecl);
12048 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12049 get_identifier ("__bool short"),
12050 bool_short_type_node);
12051 TYPE_NAME (bool_short_type_node) = tdecl;
12052 (*lang_hooks.decls.pushdecl) (tdecl);
12053 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12054 get_identifier ("__bool int"),
12055 bool_int_type_node);
12056 TYPE_NAME (bool_int_type_node) = tdecl;
12057 (*lang_hooks.decls.pushdecl) (tdecl);
12058 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
12060 TYPE_NAME (pixel_type_node) = tdecl;
12061 (*lang_hooks.decls.pushdecl) (tdecl);
12063 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
12064 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
12065 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
12066 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
12067 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
12069 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12070 get_identifier ("__vector unsigned char"),
12071 unsigned_V16QI_type_node);
12072 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
12073 (*lang_hooks.decls.pushdecl) (tdecl);
12074 tdecl = build_decl (BUILTINS_LOCATION,
12075 TYPE_DECL, get_identifier ("__vector signed char"),
12077 TYPE_NAME (V16QI_type_node) = tdecl;
12078 (*lang_hooks.decls.pushdecl) (tdecl);
12079 tdecl = build_decl (BUILTINS_LOCATION,
12080 TYPE_DECL, get_identifier ("__vector __bool char"),
12081 bool_V16QI_type_node);
12082 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
12083 (*lang_hooks.decls.pushdecl) (tdecl);
12085 tdecl = build_decl (BUILTINS_LOCATION,
12086 TYPE_DECL, get_identifier ("__vector unsigned short"),
12087 unsigned_V8HI_type_node);
12088 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
12089 (*lang_hooks.decls.pushdecl) (tdecl);
12090 tdecl = build_decl (BUILTINS_LOCATION,
12091 TYPE_DECL, get_identifier ("__vector signed short"),
12093 TYPE_NAME (V8HI_type_node) = tdecl;
12094 (*lang_hooks.decls.pushdecl) (tdecl);
12095 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12096 get_identifier ("__vector __bool short"),
12097 bool_V8HI_type_node);
12098 TYPE_NAME (bool_V8HI_type_node) = tdecl;
12099 (*lang_hooks.decls.pushdecl) (tdecl);
12101 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12102 get_identifier ("__vector unsigned int"),
12103 unsigned_V4SI_type_node);
12104 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
12105 (*lang_hooks.decls.pushdecl) (tdecl);
12106 tdecl = build_decl (BUILTINS_LOCATION,
12107 TYPE_DECL, get_identifier ("__vector signed int"),
12109 TYPE_NAME (V4SI_type_node) = tdecl;
12110 (*lang_hooks.decls.pushdecl) (tdecl);
12111 tdecl = build_decl (BUILTINS_LOCATION,
12112 TYPE_DECL, get_identifier ("__vector __bool int"),
12113 bool_V4SI_type_node);
12114 TYPE_NAME (bool_V4SI_type_node) = tdecl;
12115 (*lang_hooks.decls.pushdecl) (tdecl);
12117 tdecl = build_decl (BUILTINS_LOCATION,
12118 TYPE_DECL, get_identifier ("__vector float"),
12120 TYPE_NAME (V4SF_type_node) = tdecl;
12121 (*lang_hooks.decls.pushdecl) (tdecl);
12122 tdecl = build_decl (BUILTINS_LOCATION,
12123 TYPE_DECL, get_identifier ("__vector __pixel"),
12124 pixel_V8HI_type_node);
12125 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
12126 (*lang_hooks.decls.pushdecl) (tdecl);
12130 tdecl = build_decl (BUILTINS_LOCATION,
12131 TYPE_DECL, get_identifier ("__vector double"),
12133 TYPE_NAME (V2DF_type_node) = tdecl;
12134 (*lang_hooks.decls.pushdecl) (tdecl);
12136 tdecl = build_decl (BUILTINS_LOCATION,
12137 TYPE_DECL, get_identifier ("__vector long"),
12139 TYPE_NAME (V2DI_type_node) = tdecl;
12140 (*lang_hooks.decls.pushdecl) (tdecl);
12142 tdecl = build_decl (BUILTINS_LOCATION,
12143 TYPE_DECL, get_identifier ("__vector unsigned long"),
12144 unsigned_V2DI_type_node);
12145 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
12146 (*lang_hooks.decls.pushdecl) (tdecl);
12148 tdecl = build_decl (BUILTINS_LOCATION,
12149 TYPE_DECL, get_identifier ("__vector __bool long"),
12150 bool_V2DI_type_node);
12151 TYPE_NAME (bool_V2DI_type_node) = tdecl;
12152 (*lang_hooks.decls.pushdecl) (tdecl);
12155 if (TARGET_PAIRED_FLOAT)
12156 paired_init_builtins ();
12158 spe_init_builtins ();
12159 if (TARGET_ALTIVEC)
12160 altivec_init_builtins ();
12161 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
12162 rs6000_common_init_builtins ();
12165 ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
12166 RS6000_BUILTIN_RECIP,
12167 "__builtin_recipdiv");
12168 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
12169 RS6000_BUILTIN_RECIP);
12173 ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
12174 RS6000_BUILTIN_RECIPF,
12175 "__builtin_recipdivf");
12176 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
12177 RS6000_BUILTIN_RECIPF);
12179 if (TARGET_FRSQRTE)
12181 ftype = builtin_function_type (DFmode, DFmode, VOIDmode, VOIDmode,
12182 RS6000_BUILTIN_RSQRT,
12183 "__builtin_rsqrt");
12184 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrt", ftype,
12185 RS6000_BUILTIN_RSQRT);
12187 if (TARGET_FRSQRTES)
12189 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
12190 RS6000_BUILTIN_RSQRTF,
12191 "__builtin_rsqrtf");
12192 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
12193 RS6000_BUILTIN_RSQRTF);
12195 if (TARGET_POPCNTD)
12197 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
12198 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
12199 POWER7_BUILTIN_BPERMD,
12200 "__builtin_bpermd");
12201 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
12202 POWER7_BUILTIN_BPERMD);
12204 if (TARGET_POWERPC)
12206 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
12207 tree ftype = build_function_type_list (unsigned_intHI_type_node,
12208 unsigned_intHI_type_node,
12210 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
12211 RS6000_BUILTIN_BSWAP_HI);
12215 /* AIX libm provides clog as __clog. */
12216 if (built_in_decls [BUILT_IN_CLOG])
12217 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
12220 #ifdef SUBTARGET_INIT_BUILTINS
12221 SUBTARGET_INIT_BUILTINS;
12225 /* Returns the rs6000 builtin decl for CODE. */
12228 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
12230 if (code >= RS6000_BUILTIN_COUNT)
12231 return error_mark_node;
12233 return rs6000_builtin_decls[code];
12236 /* Search through a set of builtins and enable the mask bits.
12237 DESC is an array of builtins.
12238 SIZE is the total number of builtins.
12239 START is the builtin enum at which to start.
12240 END is the builtin enum at which to end. */
12242 enable_mask_for_builtins (struct builtin_description *desc, int size,
12243 enum rs6000_builtins start,
12244 enum rs6000_builtins end)
12248 for (i = 0; i < size; ++i)
12249 if (desc[i].code == start)
12255 for (; i < size; ++i)
12257 /* Flip all the bits on. */
12258 desc[i].mask = target_flags;
12259 if (desc[i].code == end)
12265 spe_init_builtins (void)
12267 tree puint_type_node = build_pointer_type (unsigned_type_node);
12268 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
12269 struct builtin_description *d;
12272 tree v2si_ftype_4_v2si
12273 = build_function_type_list (opaque_V2SI_type_node,
12274 opaque_V2SI_type_node,
12275 opaque_V2SI_type_node,
12276 opaque_V2SI_type_node,
12277 opaque_V2SI_type_node,
12280 tree v2sf_ftype_4_v2sf
12281 = build_function_type_list (opaque_V2SF_type_node,
12282 opaque_V2SF_type_node,
12283 opaque_V2SF_type_node,
12284 opaque_V2SF_type_node,
12285 opaque_V2SF_type_node,
12288 tree int_ftype_int_v2si_v2si
12289 = build_function_type_list (integer_type_node,
12291 opaque_V2SI_type_node,
12292 opaque_V2SI_type_node,
12295 tree int_ftype_int_v2sf_v2sf
12296 = build_function_type_list (integer_type_node,
12298 opaque_V2SF_type_node,
12299 opaque_V2SF_type_node,
12302 tree void_ftype_v2si_puint_int
12303 = build_function_type_list (void_type_node,
12304 opaque_V2SI_type_node,
12309 tree void_ftype_v2si_puint_char
12310 = build_function_type_list (void_type_node,
12311 opaque_V2SI_type_node,
12316 tree void_ftype_v2si_pv2si_int
12317 = build_function_type_list (void_type_node,
12318 opaque_V2SI_type_node,
12319 opaque_p_V2SI_type_node,
12323 tree void_ftype_v2si_pv2si_char
12324 = build_function_type_list (void_type_node,
12325 opaque_V2SI_type_node,
12326 opaque_p_V2SI_type_node,
12330 tree void_ftype_int
12331 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
12333 tree int_ftype_void
12334 = build_function_type_list (integer_type_node, NULL_TREE);
12336 tree v2si_ftype_pv2si_int
12337 = build_function_type_list (opaque_V2SI_type_node,
12338 opaque_p_V2SI_type_node,
12342 tree v2si_ftype_puint_int
12343 = build_function_type_list (opaque_V2SI_type_node,
12348 tree v2si_ftype_pushort_int
12349 = build_function_type_list (opaque_V2SI_type_node,
12354 tree v2si_ftype_signed_char
12355 = build_function_type_list (opaque_V2SI_type_node,
12356 signed_char_type_node,
12359 /* The initialization of the simple binary and unary builtins is
12360 done in rs6000_common_init_builtins, but we have to enable the
12361 mask bits here manually because we have run out of `target_flags'
12362 bits. We really need to redesign this mask business. */
12364 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
12365 ARRAY_SIZE (bdesc_2arg),
12366 SPE_BUILTIN_EVADDW,
12367 SPE_BUILTIN_EVXOR);
12368 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
12369 ARRAY_SIZE (bdesc_1arg),
12371 SPE_BUILTIN_EVSUBFUSIAAW);
12372 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
12373 ARRAY_SIZE (bdesc_spe_predicates),
12374 SPE_BUILTIN_EVCMPEQ,
12375 SPE_BUILTIN_EVFSTSTLT);
12376 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
12377 ARRAY_SIZE (bdesc_spe_evsel),
12378 SPE_BUILTIN_EVSEL_CMPGTS,
12379 SPE_BUILTIN_EVSEL_FSTSTEQ);
12381 (*lang_hooks.decls.pushdecl)
12382 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
12383 get_identifier ("__ev64_opaque__"),
12384 opaque_V2SI_type_node));
12386 /* Initialize irregular SPE builtins. */
12388 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
12389 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
12390 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
12391 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
12392 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
12393 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
12394 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
12395 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
12396 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
12397 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
12398 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
12399 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
12400 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
12401 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
12402 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
12403 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
12404 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
12405 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
12408 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
12409 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
12410 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
12411 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
12412 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
12413 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
12414 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
12415 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
12416 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
12417 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
12418 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
12419 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
12420 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
12421 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
12422 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
12423 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
12424 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
12425 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
12426 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
12427 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
12428 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
12429 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
12432 d = (struct builtin_description *) bdesc_spe_predicates;
12433 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
12437 switch (insn_data[d->icode].operand[1].mode)
12440 type = int_ftype_int_v2si_v2si;
12443 type = int_ftype_int_v2sf_v2sf;
12446 gcc_unreachable ();
12449 def_builtin (d->mask, d->name, type, d->code);
12452 /* Evsel predicates. */
12453 d = (struct builtin_description *) bdesc_spe_evsel;
12454 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
12458 switch (insn_data[d->icode].operand[1].mode)
12461 type = v2si_ftype_4_v2si;
12464 type = v2sf_ftype_4_v2sf;
12467 gcc_unreachable ();
12470 def_builtin (d->mask, d->name, type, d->code);
12475 paired_init_builtins (void)
12477 const struct builtin_description *d;
12480 tree int_ftype_int_v2sf_v2sf
12481 = build_function_type_list (integer_type_node,
12486 tree pcfloat_type_node =
12487 build_pointer_type (build_qualified_type
12488 (float_type_node, TYPE_QUAL_CONST));
12490 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
12491 long_integer_type_node,
12494 tree void_ftype_v2sf_long_pcfloat =
12495 build_function_type_list (void_type_node,
12497 long_integer_type_node,
12502 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
12503 PAIRED_BUILTIN_LX);
12506 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
12507 PAIRED_BUILTIN_STX);
12510 d = bdesc_paired_preds;
12511 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
12515 switch (insn_data[d->icode].operand[1].mode)
12518 type = int_ftype_int_v2sf_v2sf;
12521 gcc_unreachable ();
12524 def_builtin (d->mask, d->name, type, d->code);
12529 altivec_init_builtins (void)
12531 const struct builtin_description *d;
12532 const struct builtin_description_predicates *dp;
12536 tree pvoid_type_node = build_pointer_type (void_type_node);
12538 tree pcvoid_type_node
12539 = build_pointer_type (build_qualified_type (void_type_node,
12542 tree int_ftype_opaque
12543 = build_function_type_list (integer_type_node,
12544 opaque_V4SI_type_node, NULL_TREE);
12545 tree opaque_ftype_opaque
12546 = build_function_type_list (integer_type_node, NULL_TREE);
12547 tree opaque_ftype_opaque_int
12548 = build_function_type_list (opaque_V4SI_type_node,
12549 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
12550 tree opaque_ftype_opaque_opaque_int
12551 = build_function_type_list (opaque_V4SI_type_node,
12552 opaque_V4SI_type_node, opaque_V4SI_type_node,
12553 integer_type_node, NULL_TREE);
12554 tree int_ftype_int_opaque_opaque
12555 = build_function_type_list (integer_type_node,
12556 integer_type_node, opaque_V4SI_type_node,
12557 opaque_V4SI_type_node, NULL_TREE);
12558 tree int_ftype_int_v4si_v4si
12559 = build_function_type_list (integer_type_node,
12560 integer_type_node, V4SI_type_node,
12561 V4SI_type_node, NULL_TREE);
12562 tree void_ftype_v4si
12563 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
12564 tree v8hi_ftype_void
12565 = build_function_type_list (V8HI_type_node, NULL_TREE);
12566 tree void_ftype_void
12567 = build_function_type_list (void_type_node, NULL_TREE);
12568 tree void_ftype_int
12569 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
12571 tree opaque_ftype_long_pcvoid
12572 = build_function_type_list (opaque_V4SI_type_node,
12573 long_integer_type_node, pcvoid_type_node,
12575 tree v16qi_ftype_long_pcvoid
12576 = build_function_type_list (V16QI_type_node,
12577 long_integer_type_node, pcvoid_type_node,
12579 tree v8hi_ftype_long_pcvoid
12580 = build_function_type_list (V8HI_type_node,
12581 long_integer_type_node, pcvoid_type_node,
12583 tree v4si_ftype_long_pcvoid
12584 = build_function_type_list (V4SI_type_node,
12585 long_integer_type_node, pcvoid_type_node,
12587 tree v4sf_ftype_long_pcvoid
12588 = build_function_type_list (V4SF_type_node,
12589 long_integer_type_node, pcvoid_type_node,
12591 tree v2df_ftype_long_pcvoid
12592 = build_function_type_list (V2DF_type_node,
12593 long_integer_type_node, pcvoid_type_node,
12595 tree v2di_ftype_long_pcvoid
12596 = build_function_type_list (V2DI_type_node,
12597 long_integer_type_node, pcvoid_type_node,
12600 tree void_ftype_opaque_long_pvoid
12601 = build_function_type_list (void_type_node,
12602 opaque_V4SI_type_node, long_integer_type_node,
12603 pvoid_type_node, NULL_TREE);
12604 tree void_ftype_v4si_long_pvoid
12605 = build_function_type_list (void_type_node,
12606 V4SI_type_node, long_integer_type_node,
12607 pvoid_type_node, NULL_TREE);
12608 tree void_ftype_v16qi_long_pvoid
12609 = build_function_type_list (void_type_node,
12610 V16QI_type_node, long_integer_type_node,
12611 pvoid_type_node, NULL_TREE);
12612 tree void_ftype_v8hi_long_pvoid
12613 = build_function_type_list (void_type_node,
12614 V8HI_type_node, long_integer_type_node,
12615 pvoid_type_node, NULL_TREE);
12616 tree void_ftype_v4sf_long_pvoid
12617 = build_function_type_list (void_type_node,
12618 V4SF_type_node, long_integer_type_node,
12619 pvoid_type_node, NULL_TREE);
12620 tree void_ftype_v2df_long_pvoid
12621 = build_function_type_list (void_type_node,
12622 V2DF_type_node, long_integer_type_node,
12623 pvoid_type_node, NULL_TREE);
12624 tree void_ftype_v2di_long_pvoid
12625 = build_function_type_list (void_type_node,
12626 V2DI_type_node, long_integer_type_node,
12627 pvoid_type_node, NULL_TREE);
12628 tree int_ftype_int_v8hi_v8hi
12629 = build_function_type_list (integer_type_node,
12630 integer_type_node, V8HI_type_node,
12631 V8HI_type_node, NULL_TREE);
12632 tree int_ftype_int_v16qi_v16qi
12633 = build_function_type_list (integer_type_node,
12634 integer_type_node, V16QI_type_node,
12635 V16QI_type_node, NULL_TREE);
12636 tree int_ftype_int_v4sf_v4sf
12637 = build_function_type_list (integer_type_node,
12638 integer_type_node, V4SF_type_node,
12639 V4SF_type_node, NULL_TREE);
12640 tree int_ftype_int_v2df_v2df
12641 = build_function_type_list (integer_type_node,
12642 integer_type_node, V2DF_type_node,
12643 V2DF_type_node, NULL_TREE);
12644 tree v4si_ftype_v4si
12645 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
12646 tree v8hi_ftype_v8hi
12647 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
12648 tree v16qi_ftype_v16qi
12649 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
12650 tree v4sf_ftype_v4sf
12651 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
12652 tree v2df_ftype_v2df
12653 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
12654 tree void_ftype_pcvoid_int_int
12655 = build_function_type_list (void_type_node,
12656 pcvoid_type_node, integer_type_node,
12657 integer_type_node, NULL_TREE);
12659 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
12660 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
12661 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
12662 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
12663 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
12664 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
12665 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
12666 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
12667 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
12668 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
12669 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
12670 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
12671 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
12672 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
12673 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
12674 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
12675 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
12676 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
12677 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
12678 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
12679 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
12680 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
12681 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
12682 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
12683 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
12684 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
12685 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
12686 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
12687 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
12688 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
12690 def_builtin (MASK_VSX, "__builtin_vsx_lxvd2x_v2df", v2df_ftype_long_pcvoid,
12691 VSX_BUILTIN_LXVD2X_V2DF);
12692 def_builtin (MASK_VSX, "__builtin_vsx_lxvd2x_v2di", v2di_ftype_long_pcvoid,
12693 VSX_BUILTIN_LXVD2X_V2DI);
12694 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v4sf", v4sf_ftype_long_pcvoid,
12695 VSX_BUILTIN_LXVW4X_V4SF);
12696 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v4si", v4si_ftype_long_pcvoid,
12697 VSX_BUILTIN_LXVW4X_V4SI);
12698 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v8hi",
12699 v8hi_ftype_long_pcvoid, VSX_BUILTIN_LXVW4X_V8HI);
12700 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v16qi",
12701 v16qi_ftype_long_pcvoid, VSX_BUILTIN_LXVW4X_V16QI);
12702 def_builtin (MASK_VSX, "__builtin_vsx_stxvd2x_v2df",
12703 void_ftype_v2df_long_pvoid, VSX_BUILTIN_STXVD2X_V2DF);
12704 def_builtin (MASK_VSX, "__builtin_vsx_stxvd2x_v2di",
12705 void_ftype_v2di_long_pvoid, VSX_BUILTIN_STXVD2X_V2DI);
12706 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v4sf",
12707 void_ftype_v4sf_long_pvoid, VSX_BUILTIN_STXVW4X_V4SF);
12708 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v4si",
12709 void_ftype_v4si_long_pvoid, VSX_BUILTIN_STXVW4X_V4SI);
12710 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v8hi",
12711 void_ftype_v8hi_long_pvoid, VSX_BUILTIN_STXVW4X_V8HI);
12712 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v16qi",
12713 void_ftype_v16qi_long_pvoid, VSX_BUILTIN_STXVW4X_V16QI);
12714 def_builtin (MASK_VSX, "__builtin_vec_vsx_ld", opaque_ftype_long_pcvoid,
12715 VSX_BUILTIN_VEC_LD);
12716 def_builtin (MASK_VSX, "__builtin_vec_vsx_st", void_ftype_opaque_long_pvoid,
12717 VSX_BUILTIN_VEC_ST);
12719 if (rs6000_cpu == PROCESSOR_CELL)
12721 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
12722 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
12723 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
12724 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
12726 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
12727 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
12728 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
12729 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
12731 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
12732 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
12733 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
12734 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
12736 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
12737 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
12738 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
12739 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
12741 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
12742 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
12743 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
12745 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
12746 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
12747 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
12748 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
12749 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
12750 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
12751 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
12752 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
12753 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
12754 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
12755 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
12756 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
12758 /* Add the DST variants. */
12760 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
12761 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
12763 /* Initialize the predicates. */
12764 dp = bdesc_altivec_preds;
12765 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
12767 enum machine_mode mode1;
12769 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12770 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12771 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
12772 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
12777 mode1 = insn_data[dp->icode].operand[1].mode;
12782 type = int_ftype_int_opaque_opaque;
12785 type = int_ftype_int_v4si_v4si;
12788 type = int_ftype_int_v8hi_v8hi;
12791 type = int_ftype_int_v16qi_v16qi;
12794 type = int_ftype_int_v4sf_v4sf;
12797 type = int_ftype_int_v2df_v2df;
12800 gcc_unreachable ();
12803 def_builtin (dp->mask, dp->name, type, dp->code);
12806 /* Initialize the abs* operators. */
12808 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
12810 enum machine_mode mode0;
12813 mode0 = insn_data[d->icode].operand[0].mode;
12818 type = v4si_ftype_v4si;
12821 type = v8hi_ftype_v8hi;
12824 type = v16qi_ftype_v16qi;
12827 type = v4sf_ftype_v4sf;
12830 type = v2df_ftype_v2df;
12833 gcc_unreachable ();
12836 def_builtin (d->mask, d->name, type, d->code);
12839 if (TARGET_ALTIVEC)
12843 /* Initialize target builtin that implements
12844 targetm.vectorize.builtin_mask_for_load. */
12846 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
12847 v16qi_ftype_long_pcvoid,
12848 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
12849 BUILT_IN_MD, NULL, NULL_TREE);
12850 TREE_READONLY (decl) = 1;
12851 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
12852 altivec_builtin_mask_for_load = decl;
12855 /* Access to the vec_init patterns. */
12856 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
12857 integer_type_node, integer_type_node,
12858 integer_type_node, NULL_TREE);
12859 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
12860 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
12862 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
12863 short_integer_type_node,
12864 short_integer_type_node,
12865 short_integer_type_node,
12866 short_integer_type_node,
12867 short_integer_type_node,
12868 short_integer_type_node,
12869 short_integer_type_node, NULL_TREE);
12870 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
12871 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
12873 ftype = build_function_type_list (V16QI_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, char_type_node,
12878 char_type_node, char_type_node,
12879 char_type_node, char_type_node,
12880 char_type_node, char_type_node,
12881 char_type_node, NULL_TREE);
12882 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
12883 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
12885 ftype = build_function_type_list (V4SF_type_node, float_type_node,
12886 float_type_node, float_type_node,
12887 float_type_node, NULL_TREE);
12888 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
12889 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
12893 ftype = build_function_type_list (V2DF_type_node, double_type_node,
12894 double_type_node, NULL_TREE);
12895 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
12896 VSX_BUILTIN_VEC_INIT_V2DF);
12898 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
12899 intDI_type_node, NULL_TREE);
12900 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
12901 VSX_BUILTIN_VEC_INIT_V2DI);
12904 /* Access to the vec_set patterns. */
12905 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
12907 integer_type_node, NULL_TREE);
12908 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
12909 ALTIVEC_BUILTIN_VEC_SET_V4SI);
12911 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
12913 integer_type_node, NULL_TREE);
12914 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
12915 ALTIVEC_BUILTIN_VEC_SET_V8HI);
12917 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
12919 integer_type_node, NULL_TREE);
12920 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
12921 ALTIVEC_BUILTIN_VEC_SET_V16QI);
12923 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
12925 integer_type_node, NULL_TREE);
12926 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
12927 ALTIVEC_BUILTIN_VEC_SET_V4SF);
12931 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
12933 integer_type_node, NULL_TREE);
12934 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
12935 VSX_BUILTIN_VEC_SET_V2DF);
12937 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
12939 integer_type_node, NULL_TREE);
12940 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
12941 VSX_BUILTIN_VEC_SET_V2DI);
12944 /* Access to the vec_extract patterns. */
12945 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
12946 integer_type_node, NULL_TREE);
12947 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
12948 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
12950 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
12951 integer_type_node, NULL_TREE);
12952 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
12953 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
12955 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
12956 integer_type_node, NULL_TREE);
12957 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
12958 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
12960 ftype = build_function_type_list (float_type_node, V4SF_type_node,
12961 integer_type_node, NULL_TREE);
12962 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
12963 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
12967 ftype = build_function_type_list (double_type_node, V2DF_type_node,
12968 integer_type_node, NULL_TREE);
12969 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
12970 VSX_BUILTIN_VEC_EXT_V2DF);
12972 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
12973 integer_type_node, NULL_TREE);
12974 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
12975 VSX_BUILTIN_VEC_EXT_V2DI);
12979 /* Hash function for builtin functions with up to 3 arguments and a return
12982 builtin_hash_function (const void *hash_entry)
12986 const struct builtin_hash_struct *bh =
12987 (const struct builtin_hash_struct *) hash_entry;
12989 for (i = 0; i < 4; i++)
12991 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
12992 ret = (ret * 2) + bh->uns_p[i];
12998 /* Compare builtin hash entries H1 and H2 for equivalence. */
13000 builtin_hash_eq (const void *h1, const void *h2)
13002 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
13003 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
13005 return ((p1->mode[0] == p2->mode[0])
13006 && (p1->mode[1] == p2->mode[1])
13007 && (p1->mode[2] == p2->mode[2])
13008 && (p1->mode[3] == p2->mode[3])
13009 && (p1->uns_p[0] == p2->uns_p[0])
13010 && (p1->uns_p[1] == p2->uns_p[1])
13011 && (p1->uns_p[2] == p2->uns_p[2])
13012 && (p1->uns_p[3] == p2->uns_p[3]));
13015 /* Map types for builtin functions with an explicit return type and up to 3
13016 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
13017 of the argument. */
13019 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
13020 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
13021 enum rs6000_builtins builtin, const char *name)
13023 struct builtin_hash_struct h;
13024 struct builtin_hash_struct *h2;
13028 tree ret_type = NULL_TREE;
13029 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
13031 /* Create builtin_hash_table. */
13032 if (builtin_hash_table == NULL)
13033 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
13034 builtin_hash_eq, NULL);
13036 h.type = NULL_TREE;
13037 h.mode[0] = mode_ret;
13038 h.mode[1] = mode_arg0;
13039 h.mode[2] = mode_arg1;
13040 h.mode[3] = mode_arg2;
13046 /* If the builtin is a type that produces unsigned results or takes unsigned
13047 arguments, and it is returned as a decl for the vectorizer (such as
13048 widening multiplies, permute), make sure the arguments and return value
13049 are type correct. */
13052 /* unsigned 2 argument functions. */
13053 case ALTIVEC_BUILTIN_VMULEUB_UNS:
13054 case ALTIVEC_BUILTIN_VMULEUH_UNS:
13055 case ALTIVEC_BUILTIN_VMULOUB_UNS:
13056 case ALTIVEC_BUILTIN_VMULOUH_UNS:
13062 /* unsigned 3 argument functions. */
13063 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
13064 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
13065 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
13066 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
13067 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
13068 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
13069 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
13070 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
13071 case VSX_BUILTIN_VPERM_16QI_UNS:
13072 case VSX_BUILTIN_VPERM_8HI_UNS:
13073 case VSX_BUILTIN_VPERM_4SI_UNS:
13074 case VSX_BUILTIN_VPERM_2DI_UNS:
13075 case VSX_BUILTIN_XXSEL_16QI_UNS:
13076 case VSX_BUILTIN_XXSEL_8HI_UNS:
13077 case VSX_BUILTIN_XXSEL_4SI_UNS:
13078 case VSX_BUILTIN_XXSEL_2DI_UNS:
13085 /* signed permute functions with unsigned char mask. */
13086 case ALTIVEC_BUILTIN_VPERM_16QI:
13087 case ALTIVEC_BUILTIN_VPERM_8HI:
13088 case ALTIVEC_BUILTIN_VPERM_4SI:
13089 case ALTIVEC_BUILTIN_VPERM_4SF:
13090 case ALTIVEC_BUILTIN_VPERM_2DI:
13091 case ALTIVEC_BUILTIN_VPERM_2DF:
13092 case VSX_BUILTIN_VPERM_16QI:
13093 case VSX_BUILTIN_VPERM_8HI:
13094 case VSX_BUILTIN_VPERM_4SI:
13095 case VSX_BUILTIN_VPERM_4SF:
13096 case VSX_BUILTIN_VPERM_2DI:
13097 case VSX_BUILTIN_VPERM_2DF:
13101 /* unsigned args, signed return. */
13102 case VSX_BUILTIN_XVCVUXDDP_UNS:
13103 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
13107 /* signed args, unsigned return. */
13108 case VSX_BUILTIN_XVCVDPUXDS_UNS:
13109 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
13117 /* Figure out how many args are present. */
13118 while (num_args > 0 && h.mode[num_args] == VOIDmode)
13122 fatal_error ("internal error: builtin function %s had no type", name);
13124 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
13125 if (!ret_type && h.uns_p[0])
13126 ret_type = builtin_mode_to_type[h.mode[0]][0];
13129 fatal_error ("internal error: builtin function %s had an unexpected "
13130 "return type %s", name, GET_MODE_NAME (h.mode[0]));
13132 for (i = 0; i < (int) ARRAY_SIZE (arg_type); i++)
13133 arg_type[i] = NULL_TREE;
13135 for (i = 0; i < num_args; i++)
13137 int m = (int) h.mode[i+1];
13138 int uns_p = h.uns_p[i+1];
13140 arg_type[i] = builtin_mode_to_type[m][uns_p];
13141 if (!arg_type[i] && uns_p)
13142 arg_type[i] = builtin_mode_to_type[m][0];
13145 fatal_error ("internal error: builtin function %s, argument %d "
13146 "had unexpected argument type %s", name, i,
13147 GET_MODE_NAME (m));
13150 found = htab_find_slot (builtin_hash_table, &h, INSERT);
13151 if (*found == NULL)
13153 h2 = ggc_alloc_builtin_hash_struct ();
13155 *found = (void *)h2;
13157 h2->type = build_function_type_list (ret_type, arg_type[0], arg_type[1],
13158 arg_type[2], NULL_TREE);
13161 return ((struct builtin_hash_struct *)(*found))->type;
13165 rs6000_common_init_builtins (void)
13167 const struct builtin_description *d;
13170 tree opaque_ftype_opaque = NULL_TREE;
13171 tree opaque_ftype_opaque_opaque = NULL_TREE;
13172 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
13173 tree v2si_ftype_qi = NULL_TREE;
13174 tree v2si_ftype_v2si_qi = NULL_TREE;
13175 tree v2si_ftype_int_qi = NULL_TREE;
13177 if (!TARGET_PAIRED_FLOAT)
13179 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
13180 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
13183 /* Add the ternary operators. */
13185 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
13188 int mask = d->mask;
13190 if ((mask != 0 && (mask & target_flags) == 0)
13191 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13194 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13195 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13196 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13197 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13199 if (! (type = opaque_ftype_opaque_opaque_opaque))
13200 type = opaque_ftype_opaque_opaque_opaque
13201 = build_function_type_list (opaque_V4SI_type_node,
13202 opaque_V4SI_type_node,
13203 opaque_V4SI_type_node,
13204 opaque_V4SI_type_node,
13209 enum insn_code icode = d->icode;
13210 if (d->name == 0 || icode == CODE_FOR_nothing)
13213 type = builtin_function_type (insn_data[icode].operand[0].mode,
13214 insn_data[icode].operand[1].mode,
13215 insn_data[icode].operand[2].mode,
13216 insn_data[icode].operand[3].mode,
13220 def_builtin (d->mask, d->name, type, d->code);
13223 /* Add the binary operators. */
13225 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
13227 enum machine_mode mode0, mode1, mode2;
13229 int mask = d->mask;
13231 if ((mask != 0 && (mask & target_flags) == 0)
13232 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13235 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13236 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13237 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13238 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13240 if (! (type = opaque_ftype_opaque_opaque))
13241 type = opaque_ftype_opaque_opaque
13242 = build_function_type_list (opaque_V4SI_type_node,
13243 opaque_V4SI_type_node,
13244 opaque_V4SI_type_node,
13249 enum insn_code icode = d->icode;
13250 if (d->name == 0 || icode == CODE_FOR_nothing)
13253 mode0 = insn_data[icode].operand[0].mode;
13254 mode1 = insn_data[icode].operand[1].mode;
13255 mode2 = insn_data[icode].operand[2].mode;
13257 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
13259 if (! (type = v2si_ftype_v2si_qi))
13260 type = v2si_ftype_v2si_qi
13261 = build_function_type_list (opaque_V2SI_type_node,
13262 opaque_V2SI_type_node,
13267 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
13268 && mode2 == QImode)
13270 if (! (type = v2si_ftype_int_qi))
13271 type = v2si_ftype_int_qi
13272 = build_function_type_list (opaque_V2SI_type_node,
13279 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
13283 def_builtin (d->mask, d->name, type, d->code);
13286 /* Add the simple unary operators. */
13287 d = (struct builtin_description *) bdesc_1arg;
13288 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
13290 enum machine_mode mode0, mode1;
13292 int mask = d->mask;
13294 if ((mask != 0 && (mask & target_flags) == 0)
13295 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13298 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13299 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13300 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13301 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13303 if (! (type = opaque_ftype_opaque))
13304 type = opaque_ftype_opaque
13305 = build_function_type_list (opaque_V4SI_type_node,
13306 opaque_V4SI_type_node,
13311 enum insn_code icode = d->icode;
13312 if (d->name == 0 || icode == CODE_FOR_nothing)
13315 mode0 = insn_data[icode].operand[0].mode;
13316 mode1 = insn_data[icode].operand[1].mode;
13318 if (mode0 == V2SImode && mode1 == QImode)
13320 if (! (type = v2si_ftype_qi))
13321 type = v2si_ftype_qi
13322 = build_function_type_list (opaque_V2SI_type_node,
13328 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
13332 def_builtin (d->mask, d->name, type, d->code);
13337 rs6000_init_libfuncs (void)
13339 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
13340 && !TARGET_POWER2 && !TARGET_POWERPC)
13342 /* AIX library routines for float->int conversion. */
13343 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
13344 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
13345 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
13346 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
13349 if (!TARGET_IEEEQUAD)
13350 /* AIX/Darwin/64-bit Linux quad floating point routines. */
13351 if (!TARGET_XL_COMPAT)
13353 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
13354 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
13355 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
13356 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
13358 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
13360 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
13361 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
13362 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
13363 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
13364 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
13365 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
13366 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
13368 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
13369 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
13370 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
13371 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
13372 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
13373 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
13374 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
13375 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
13378 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
13379 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
13383 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
13384 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
13385 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
13386 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
13390 /* 32-bit SVR4 quad floating point routines. */
13392 set_optab_libfunc (add_optab, TFmode, "_q_add");
13393 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
13394 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
13395 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
13396 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
13397 if (TARGET_PPC_GPOPT || TARGET_POWER2)
13398 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
13400 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
13401 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
13402 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
13403 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
13404 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
13405 set_optab_libfunc (le_optab, TFmode, "_q_fle");
13407 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
13408 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
13409 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
13410 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
13411 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
13412 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
13413 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
13414 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
13419 /* Expand a block clear operation, and return 1 if successful. Return 0
13420 if we should let the compiler generate normal code.
13422 operands[0] is the destination
13423 operands[1] is the length
13424 operands[3] is the alignment */
13427 expand_block_clear (rtx operands[])
13429 rtx orig_dest = operands[0];
13430 rtx bytes_rtx = operands[1];
13431 rtx align_rtx = operands[3];
13432 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
13433 HOST_WIDE_INT align;
13434 HOST_WIDE_INT bytes;
13439 /* If this is not a fixed size move, just call memcpy */
13443 /* This must be a fixed size alignment */
13444 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13445 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13447 /* Anything to clear? */
13448 bytes = INTVAL (bytes_rtx);
13452 /* Use the builtin memset after a point, to avoid huge code bloat.
13453 When optimize_size, avoid any significant code bloat; calling
13454 memset is about 4 instructions, so allow for one instruction to
13455 load zero and three to do clearing. */
13456 if (TARGET_ALTIVEC && align >= 128)
13458 else if (TARGET_POWERPC64 && align >= 32)
13460 else if (TARGET_SPE && align >= 64)
13465 if (optimize_size && bytes > 3 * clear_step)
13467 if (! optimize_size && bytes > 8 * clear_step)
13470 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
13472 enum machine_mode mode = BLKmode;
13475 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
13480 else if (bytes >= 8 && TARGET_SPE && align >= 64)
13485 else if (bytes >= 8 && TARGET_POWERPC64
13486 /* 64-bit loads and stores require word-aligned
13488 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13493 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13494 { /* move 4 bytes */
13498 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13499 { /* move 2 bytes */
13503 else /* move 1 byte at a time */
13509 dest = adjust_address (orig_dest, mode, offset);
13511 emit_move_insn (dest, CONST0_RTX (mode));
13518 /* Expand a block move operation, and return 1 if successful. Return 0
13519 if we should let the compiler generate normal code.
13521 operands[0] is the destination
13522 operands[1] is the source
13523 operands[2] is the length
13524 operands[3] is the alignment */
13526 #define MAX_MOVE_REG 4
13529 expand_block_move (rtx operands[])
13531 rtx orig_dest = operands[0];
13532 rtx orig_src = operands[1];
13533 rtx bytes_rtx = operands[2];
13534 rtx align_rtx = operands[3];
13535 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
13540 rtx stores[MAX_MOVE_REG];
13543 /* If this is not a fixed size move, just call memcpy */
13547 /* This must be a fixed size alignment */
13548 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13549 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13551 /* Anything to move? */
13552 bytes = INTVAL (bytes_rtx);
13556 if (bytes > rs6000_block_move_inline_limit)
13559 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
13562 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
13563 rtx (*mov) (rtx, rtx);
13565 enum machine_mode mode = BLKmode;
13568 /* Altivec first, since it will be faster than a string move
13569 when it applies, and usually not significantly larger. */
13570 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
13574 gen_func.mov = gen_movv4si;
13576 else if (TARGET_SPE && bytes >= 8 && align >= 64)
13580 gen_func.mov = gen_movv2si;
13582 else if (TARGET_STRING
13583 && bytes > 24 /* move up to 32 bytes at a time */
13589 && ! fixed_regs[10]
13590 && ! fixed_regs[11]
13591 && ! fixed_regs[12])
13593 move_bytes = (bytes > 32) ? 32 : bytes;
13594 gen_func.movmemsi = gen_movmemsi_8reg;
13596 else if (TARGET_STRING
13597 && bytes > 16 /* move up to 24 bytes at a time */
13603 && ! fixed_regs[10])
13605 move_bytes = (bytes > 24) ? 24 : bytes;
13606 gen_func.movmemsi = gen_movmemsi_6reg;
13608 else if (TARGET_STRING
13609 && bytes > 8 /* move up to 16 bytes at a time */
13613 && ! fixed_regs[8])
13615 move_bytes = (bytes > 16) ? 16 : bytes;
13616 gen_func.movmemsi = gen_movmemsi_4reg;
13618 else if (bytes >= 8 && TARGET_POWERPC64
13619 /* 64-bit loads and stores require word-aligned
13621 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13625 gen_func.mov = gen_movdi;
13627 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
13628 { /* move up to 8 bytes at a time */
13629 move_bytes = (bytes > 8) ? 8 : bytes;
13630 gen_func.movmemsi = gen_movmemsi_2reg;
13632 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13633 { /* move 4 bytes */
13636 gen_func.mov = gen_movsi;
13638 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13639 { /* move 2 bytes */
13642 gen_func.mov = gen_movhi;
13644 else if (TARGET_STRING && bytes > 1)
13645 { /* move up to 4 bytes at a time */
13646 move_bytes = (bytes > 4) ? 4 : bytes;
13647 gen_func.movmemsi = gen_movmemsi_1reg;
13649 else /* move 1 byte at a time */
13653 gen_func.mov = gen_movqi;
13656 src = adjust_address (orig_src, mode, offset);
13657 dest = adjust_address (orig_dest, mode, offset);
13659 if (mode != BLKmode)
13661 rtx tmp_reg = gen_reg_rtx (mode);
13663 emit_insn ((*gen_func.mov) (tmp_reg, src));
13664 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
13667 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
13670 for (i = 0; i < num_reg; i++)
13671 emit_insn (stores[i]);
13675 if (mode == BLKmode)
13677 /* Move the address into scratch registers. The movmemsi
13678 patterns require zero offset. */
13679 if (!REG_P (XEXP (src, 0)))
13681 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
13682 src = replace_equiv_address (src, src_reg);
13684 set_mem_size (src, move_bytes);
13686 if (!REG_P (XEXP (dest, 0)))
13688 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
13689 dest = replace_equiv_address (dest, dest_reg);
13691 set_mem_size (dest, move_bytes);
13693 emit_insn ((*gen_func.movmemsi) (dest, src,
13694 GEN_INT (move_bytes & 31),
13703 /* Return a string to perform a load_multiple operation.
13704 operands[0] is the vector.
13705 operands[1] is the source address.
13706 operands[2] is the first destination register. */
13709 rs6000_output_load_multiple (rtx operands[3])
13711 /* We have to handle the case where the pseudo used to contain the address
13712 is assigned to one of the output registers. */
13714 int words = XVECLEN (operands[0], 0);
13717 if (XVECLEN (operands[0], 0) == 1)
13718 return "{l|lwz} %2,0(%1)";
13720 for (i = 0; i < words; i++)
13721 if (refers_to_regno_p (REGNO (operands[2]) + i,
13722 REGNO (operands[2]) + i + 1, operands[1], 0))
13726 xop[0] = GEN_INT (4 * (words-1));
13727 xop[1] = operands[1];
13728 xop[2] = operands[2];
13729 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
13734 xop[0] = GEN_INT (4 * (words-1));
13735 xop[1] = operands[1];
13736 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
13737 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);
13742 for (j = 0; j < words; j++)
13745 xop[0] = GEN_INT (j * 4);
13746 xop[1] = operands[1];
13747 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
13748 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
13750 xop[0] = GEN_INT (i * 4);
13751 xop[1] = operands[1];
13752 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
13757 return "{lsi|lswi} %2,%1,%N0";
13761 /* A validation routine: say whether CODE, a condition code, and MODE
13762 match. The other alternatives either don't make sense or should
13763 never be generated. */
13766 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
13768 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
13769 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
13770 && GET_MODE_CLASS (mode) == MODE_CC);
13772 /* These don't make sense. */
13773 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
13774 || mode != CCUNSmode);
13776 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
13777 || mode == CCUNSmode);
13779 gcc_assert (mode == CCFPmode
13780 || (code != ORDERED && code != UNORDERED
13781 && code != UNEQ && code != LTGT
13782 && code != UNGT && code != UNLT
13783 && code != UNGE && code != UNLE));
13785 /* These should never be generated except for
13786 flag_finite_math_only. */
13787 gcc_assert (mode != CCFPmode
13788 || flag_finite_math_only
13789 || (code != LE && code != GE
13790 && code != UNEQ && code != LTGT
13791 && code != UNGT && code != UNLT));
13793 /* These are invalid; the information is not there. */
13794 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
13798 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
13799 mask required to convert the result of a rotate insn into a shift
13800 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
13803 includes_lshift_p (rtx shiftop, rtx andop)
13805 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
13807 shift_mask <<= INTVAL (shiftop);
13809 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
13812 /* Similar, but for right shift. */
13815 includes_rshift_p (rtx shiftop, rtx andop)
13817 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
13819 shift_mask >>= INTVAL (shiftop);
13821 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
13824 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
13825 to perform a left shift. It must have exactly SHIFTOP least
13826 significant 0's, then one or more 1's, then zero or more 0's. */
13829 includes_rldic_lshift_p (rtx shiftop, rtx andop)
13831 if (GET_CODE (andop) == CONST_INT)
13833 HOST_WIDE_INT c, lsb, shift_mask;
13835 c = INTVAL (andop);
13836 if (c == 0 || c == ~0)
13840 shift_mask <<= INTVAL (shiftop);
13842 /* Find the least significant one bit. */
13845 /* It must coincide with the LSB of the shift mask. */
13846 if (-lsb != shift_mask)
13849 /* Invert to look for the next transition (if any). */
13852 /* Remove the low group of ones (originally low group of zeros). */
13855 /* Again find the lsb, and check we have all 1's above. */
13859 else if (GET_CODE (andop) == CONST_DOUBLE
13860 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
13862 HOST_WIDE_INT low, high, lsb;
13863 HOST_WIDE_INT shift_mask_low, shift_mask_high;
13865 low = CONST_DOUBLE_LOW (andop);
13866 if (HOST_BITS_PER_WIDE_INT < 64)
13867 high = CONST_DOUBLE_HIGH (andop);
13869 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
13870 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
13873 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13875 shift_mask_high = ~0;
13876 if (INTVAL (shiftop) > 32)
13877 shift_mask_high <<= INTVAL (shiftop) - 32;
13879 lsb = high & -high;
13881 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
13887 lsb = high & -high;
13888 return high == -lsb;
13891 shift_mask_low = ~0;
13892 shift_mask_low <<= INTVAL (shiftop);
13896 if (-lsb != shift_mask_low)
13899 if (HOST_BITS_PER_WIDE_INT < 64)
13904 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13906 lsb = high & -high;
13907 return high == -lsb;
13911 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
13917 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
13918 to perform a left shift. It must have SHIFTOP or more least
13919 significant 0's, with the remainder of the word 1's. */
13922 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
13924 if (GET_CODE (andop) == CONST_INT)
13926 HOST_WIDE_INT c, lsb, shift_mask;
13929 shift_mask <<= INTVAL (shiftop);
13930 c = INTVAL (andop);
13932 /* Find the least significant one bit. */
13935 /* It must be covered by the shift mask.
13936 This test also rejects c == 0. */
13937 if ((lsb & shift_mask) == 0)
13940 /* Check we have all 1's above the transition, and reject all 1's. */
13941 return c == -lsb && lsb != 1;
13943 else if (GET_CODE (andop) == CONST_DOUBLE
13944 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
13946 HOST_WIDE_INT low, lsb, shift_mask_low;
13948 low = CONST_DOUBLE_LOW (andop);
13950 if (HOST_BITS_PER_WIDE_INT < 64)
13952 HOST_WIDE_INT high, shift_mask_high;
13954 high = CONST_DOUBLE_HIGH (andop);
13958 shift_mask_high = ~0;
13959 if (INTVAL (shiftop) > 32)
13960 shift_mask_high <<= INTVAL (shiftop) - 32;
13962 lsb = high & -high;
13964 if ((lsb & shift_mask_high) == 0)
13967 return high == -lsb;
13973 shift_mask_low = ~0;
13974 shift_mask_low <<= INTVAL (shiftop);
13978 if ((lsb & shift_mask_low) == 0)
13981 return low == -lsb && lsb != 1;
13987 /* Return 1 if operands will generate a valid arguments to rlwimi
13988 instruction for insert with right shift in 64-bit mode. The mask may
13989 not start on the first bit or stop on the last bit because wrap-around
13990 effects of instruction do not correspond to semantics of RTL insn. */
13993 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
13995 if (INTVAL (startop) > 32
13996 && INTVAL (startop) < 64
13997 && INTVAL (sizeop) > 1
13998 && INTVAL (sizeop) + INTVAL (startop) < 64
13999 && INTVAL (shiftop) > 0
14000 && INTVAL (sizeop) + INTVAL (shiftop) < 32
14001 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
14007 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
14008 for lfq and stfq insns iff the registers are hard registers. */
14011 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
14013 /* We might have been passed a SUBREG. */
14014 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
14017 /* We might have been passed non floating point registers. */
14018 if (!FP_REGNO_P (REGNO (reg1))
14019 || !FP_REGNO_P (REGNO (reg2)))
14022 return (REGNO (reg1) == REGNO (reg2) - 1);
14025 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
14026 addr1 and addr2 must be in consecutive memory locations
14027 (addr2 == addr1 + 8). */
14030 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
14033 unsigned int reg1, reg2;
14034 int offset1, offset2;
14036 /* The mems cannot be volatile. */
14037 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
14040 addr1 = XEXP (mem1, 0);
14041 addr2 = XEXP (mem2, 0);
14043 /* Extract an offset (if used) from the first addr. */
14044 if (GET_CODE (addr1) == PLUS)
14046 /* If not a REG, return zero. */
14047 if (GET_CODE (XEXP (addr1, 0)) != REG)
14051 reg1 = REGNO (XEXP (addr1, 0));
14052 /* The offset must be constant! */
14053 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
14055 offset1 = INTVAL (XEXP (addr1, 1));
14058 else if (GET_CODE (addr1) != REG)
14062 reg1 = REGNO (addr1);
14063 /* This was a simple (mem (reg)) expression. Offset is 0. */
14067 /* And now for the second addr. */
14068 if (GET_CODE (addr2) == PLUS)
14070 /* If not a REG, return zero. */
14071 if (GET_CODE (XEXP (addr2, 0)) != REG)
14075 reg2 = REGNO (XEXP (addr2, 0));
14076 /* The offset must be constant. */
14077 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
14079 offset2 = INTVAL (XEXP (addr2, 1));
14082 else if (GET_CODE (addr2) != REG)
14086 reg2 = REGNO (addr2);
14087 /* This was a simple (mem (reg)) expression. Offset is 0. */
14091 /* Both of these must have the same base register. */
14095 /* The offset for the second addr must be 8 more than the first addr. */
14096 if (offset2 != offset1 + 8)
14099 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
14106 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
14108 static bool eliminated = false;
14111 if (mode != SDmode)
14112 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
14115 rtx mem = cfun->machine->sdmode_stack_slot;
14116 gcc_assert (mem != NULL_RTX);
14120 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
14121 cfun->machine->sdmode_stack_slot = mem;
14127 if (TARGET_DEBUG_ADDR)
14129 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
14130 GET_MODE_NAME (mode));
14132 fprintf (stderr, "\tNULL_RTX\n");
14141 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
14143 /* Don't walk into types. */
14144 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
14146 *walk_subtrees = 0;
14150 switch (TREE_CODE (*tp))
14159 case VIEW_CONVERT_EXPR:
14160 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
14170 enum reload_reg_type {
14172 VECTOR_REGISTER_TYPE,
14173 OTHER_REGISTER_TYPE
14176 static enum reload_reg_type
14177 rs6000_reload_register_type (enum reg_class rclass)
14183 return GPR_REGISTER_TYPE;
14188 return VECTOR_REGISTER_TYPE;
14191 return OTHER_REGISTER_TYPE;
14195 /* Inform reload about cases where moving X with a mode MODE to a register in
14196 RCLASS requires an extra scratch or immediate register. Return the class
14197 needed for the immediate register.
14199 For VSX and Altivec, we may need a register to convert sp+offset into
14202 For misaligned 64-bit gpr loads and stores we need a register to
14203 convert an offset address to indirect. */
14206 rs6000_secondary_reload (bool in_p,
14208 reg_class_t rclass_i,
14209 enum machine_mode mode,
14210 secondary_reload_info *sri)
14212 enum reg_class rclass = (enum reg_class) rclass_i;
14213 reg_class_t ret = ALL_REGS;
14214 enum insn_code icode;
14215 bool default_p = false;
14217 sri->icode = CODE_FOR_nothing;
14219 /* Convert vector loads and stores into gprs to use an additional base
14221 icode = rs6000_vector_reload[mode][in_p != false];
14222 if (icode != CODE_FOR_nothing)
14225 sri->icode = CODE_FOR_nothing;
14226 sri->extra_cost = 0;
14228 if (GET_CODE (x) == MEM)
14230 rtx addr = XEXP (x, 0);
14232 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
14233 an extra register in that case, but it would need an extra
14234 register if the addressing is reg+reg or (reg+reg)&(-16). */
14235 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
14237 if (!legitimate_indirect_address_p (addr, false)
14238 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14240 sri->icode = icode;
14241 /* account for splitting the loads, and converting the
14242 address from reg+reg to reg. */
14243 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
14244 + ((GET_CODE (addr) == AND) ? 1 : 0));
14247 /* Loads to and stores from vector registers can only do reg+reg
14248 addressing. Altivec registers can also do (reg+reg)&(-16). */
14249 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
14250 || rclass == FLOAT_REGS || rclass == NO_REGS)
14252 if (!VECTOR_MEM_ALTIVEC_P (mode)
14253 && GET_CODE (addr) == AND
14254 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14255 && INTVAL (XEXP (addr, 1)) == -16
14256 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
14257 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
14259 sri->icode = icode;
14260 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
14263 else if (!legitimate_indirect_address_p (addr, false)
14264 && (rclass == NO_REGS
14265 || !legitimate_indexed_address_p (addr, false)))
14267 sri->icode = icode;
14268 sri->extra_cost = 1;
14271 icode = CODE_FOR_nothing;
14273 /* Any other loads, including to pseudo registers which haven't been
14274 assigned to a register yet, default to require a scratch
14278 sri->icode = icode;
14279 sri->extra_cost = 2;
14282 else if (REG_P (x))
14284 int regno = true_regnum (x);
14286 icode = CODE_FOR_nothing;
14287 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
14291 enum reg_class xclass = REGNO_REG_CLASS (regno);
14292 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
14293 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
14295 /* If memory is needed, use default_secondary_reload to create the
14297 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
14306 else if (TARGET_POWERPC64
14307 && rs6000_reload_register_type (rclass) == GPR_REGISTER_TYPE
14309 && GET_MODE_SIZE (GET_MODE (x)) >= UNITS_PER_WORD)
14311 rtx addr = XEXP (x, 0);
14313 if (GET_CODE (addr) == PRE_MODIFY)
14314 addr = XEXP (addr, 1);
14315 else if (GET_CODE (addr) == LO_SUM
14316 && GET_CODE (XEXP (addr, 0)) == REG
14317 && GET_CODE (XEXP (addr, 1)) == CONST)
14318 addr = XEXP (XEXP (addr, 1), 0);
14320 if (GET_CODE (addr) == PLUS
14321 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14322 && (INTVAL (XEXP (addr, 1)) & 3) != 0)
14325 sri->icode = CODE_FOR_reload_di_load;
14327 sri->icode = CODE_FOR_reload_di_store;
14328 sri->extra_cost = 2;
14338 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
14340 gcc_assert (ret != ALL_REGS);
14342 if (TARGET_DEBUG_ADDR)
14345 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
14347 reg_class_names[ret],
14348 in_p ? "true" : "false",
14349 reg_class_names[rclass],
14350 GET_MODE_NAME (mode));
14353 fprintf (stderr, ", default secondary reload");
14355 if (sri->icode != CODE_FOR_nothing)
14356 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
14357 insn_data[sri->icode].name, sri->extra_cost);
14359 fprintf (stderr, "\n");
14367 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
14368 to SP+reg addressing. */
14371 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
14373 int regno = true_regnum (reg);
14374 enum machine_mode mode = GET_MODE (reg);
14375 enum reg_class rclass;
14377 rtx and_op2 = NULL_RTX;
14380 rtx scratch_or_premodify = scratch;
14384 if (TARGET_DEBUG_ADDR)
14386 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
14387 store_p ? "store" : "load");
14388 fprintf (stderr, "reg:\n");
14390 fprintf (stderr, "mem:\n");
14392 fprintf (stderr, "scratch:\n");
14393 debug_rtx (scratch);
14396 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
14397 gcc_assert (GET_CODE (mem) == MEM);
14398 rclass = REGNO_REG_CLASS (regno);
14399 addr = XEXP (mem, 0);
14403 /* GPRs can handle reg + small constant, all other addresses need to use
14404 the scratch register. */
14407 if (GET_CODE (addr) == AND)
14409 and_op2 = XEXP (addr, 1);
14410 addr = XEXP (addr, 0);
14413 if (GET_CODE (addr) == PRE_MODIFY)
14415 scratch_or_premodify = XEXP (addr, 0);
14416 gcc_assert (REG_P (scratch_or_premodify));
14417 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14418 addr = XEXP (addr, 1);
14421 if (GET_CODE (addr) == PLUS
14422 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
14423 || and_op2 != NULL_RTX))
14425 addr_op1 = XEXP (addr, 0);
14426 addr_op2 = XEXP (addr, 1);
14427 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
14429 if (!REG_P (addr_op2)
14430 && (GET_CODE (addr_op2) != CONST_INT
14431 || !satisfies_constraint_I (addr_op2)))
14433 if (TARGET_DEBUG_ADDR)
14436 "\nMove plus addr to register %s, mode = %s: ",
14437 rs6000_reg_names[REGNO (scratch)],
14438 GET_MODE_NAME (mode));
14439 debug_rtx (addr_op2);
14441 rs6000_emit_move (scratch, addr_op2, Pmode);
14442 addr_op2 = scratch;
14445 emit_insn (gen_rtx_SET (VOIDmode,
14446 scratch_or_premodify,
14447 gen_rtx_PLUS (Pmode,
14451 addr = scratch_or_premodify;
14452 scratch_or_premodify = scratch;
14454 else if (!legitimate_indirect_address_p (addr, false)
14455 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14457 if (TARGET_DEBUG_ADDR)
14459 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14460 rs6000_reg_names[REGNO (scratch_or_premodify)],
14461 GET_MODE_NAME (mode));
14464 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14465 addr = scratch_or_premodify;
14466 scratch_or_premodify = scratch;
14470 /* Float/Altivec registers can only handle reg+reg addressing. Move
14471 other addresses into a scratch register. */
14476 /* With float regs, we need to handle the AND ourselves, since we can't
14477 use the Altivec instruction with an implicit AND -16. Allow scalar
14478 loads to float registers to use reg+offset even if VSX. */
14479 if (GET_CODE (addr) == AND
14480 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
14481 || GET_CODE (XEXP (addr, 1)) != CONST_INT
14482 || INTVAL (XEXP (addr, 1)) != -16
14483 || !VECTOR_MEM_ALTIVEC_P (mode)))
14485 and_op2 = XEXP (addr, 1);
14486 addr = XEXP (addr, 0);
14489 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
14490 as the address later. */
14491 if (GET_CODE (addr) == PRE_MODIFY
14492 && (!VECTOR_MEM_VSX_P (mode)
14493 || and_op2 != NULL_RTX
14494 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
14496 scratch_or_premodify = XEXP (addr, 0);
14497 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
14499 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14500 addr = XEXP (addr, 1);
14503 if (legitimate_indirect_address_p (addr, false) /* reg */
14504 || legitimate_indexed_address_p (addr, false) /* reg+reg */
14505 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
14506 || (GET_CODE (addr) == AND /* Altivec memory */
14507 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14508 && INTVAL (XEXP (addr, 1)) == -16
14509 && VECTOR_MEM_ALTIVEC_P (mode))
14510 || (rclass == FLOAT_REGS /* legacy float mem */
14511 && GET_MODE_SIZE (mode) == 8
14512 && and_op2 == NULL_RTX
14513 && scratch_or_premodify == scratch
14514 && rs6000_legitimate_offset_address_p (mode, addr, false)))
14517 else if (GET_CODE (addr) == PLUS)
14519 addr_op1 = XEXP (addr, 0);
14520 addr_op2 = XEXP (addr, 1);
14521 gcc_assert (REG_P (addr_op1));
14523 if (TARGET_DEBUG_ADDR)
14525 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
14526 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14527 debug_rtx (addr_op2);
14529 rs6000_emit_move (scratch, addr_op2, Pmode);
14530 emit_insn (gen_rtx_SET (VOIDmode,
14531 scratch_or_premodify,
14532 gen_rtx_PLUS (Pmode,
14535 addr = scratch_or_premodify;
14536 scratch_or_premodify = scratch;
14539 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
14540 || GET_CODE (addr) == CONST_INT || REG_P (addr))
14542 if (TARGET_DEBUG_ADDR)
14544 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14545 rs6000_reg_names[REGNO (scratch_or_premodify)],
14546 GET_MODE_NAME (mode));
14550 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14551 addr = scratch_or_premodify;
14552 scratch_or_premodify = scratch;
14556 gcc_unreachable ();
14561 gcc_unreachable ();
14564 /* If the original address involved a pre-modify that we couldn't use the VSX
14565 memory instruction with update, and we haven't taken care of already,
14566 store the address in the pre-modify register and use that as the
14568 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
14570 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
14571 addr = scratch_or_premodify;
14574 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
14575 memory instruction, recreate the AND now, including the clobber which is
14576 generated by the general ANDSI3/ANDDI3 patterns for the
14577 andi. instruction. */
14578 if (and_op2 != NULL_RTX)
14580 if (! legitimate_indirect_address_p (addr, false))
14582 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
14586 if (TARGET_DEBUG_ADDR)
14588 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
14589 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14590 debug_rtx (and_op2);
14593 and_rtx = gen_rtx_SET (VOIDmode,
14595 gen_rtx_AND (Pmode,
14599 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
14600 emit_insn (gen_rtx_PARALLEL (VOIDmode,
14601 gen_rtvec (2, and_rtx, cc_clobber)));
14605 /* Adjust the address if it changed. */
14606 if (addr != XEXP (mem, 0))
14608 mem = change_address (mem, mode, addr);
14609 if (TARGET_DEBUG_ADDR)
14610 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
14613 /* Now create the move. */
14615 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
14617 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
14622 /* Convert reloads involving 64-bit gprs and misaligned offset
14623 addressing to use indirect addressing. */
14626 rs6000_secondary_reload_ppc64 (rtx reg, rtx mem, rtx scratch, bool store_p)
14628 int regno = true_regnum (reg);
14629 enum reg_class rclass;
14631 rtx scratch_or_premodify = scratch;
14633 if (TARGET_DEBUG_ADDR)
14635 fprintf (stderr, "\nrs6000_secondary_reload_ppc64, type = %s\n",
14636 store_p ? "store" : "load");
14637 fprintf (stderr, "reg:\n");
14639 fprintf (stderr, "mem:\n");
14641 fprintf (stderr, "scratch:\n");
14642 debug_rtx (scratch);
14645 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
14646 gcc_assert (GET_CODE (mem) == MEM);
14647 rclass = REGNO_REG_CLASS (regno);
14648 gcc_assert (rclass == GENERAL_REGS || rclass == BASE_REGS);
14649 addr = XEXP (mem, 0);
14651 if (GET_CODE (addr) == PRE_MODIFY)
14653 scratch_or_premodify = XEXP (addr, 0);
14654 gcc_assert (REG_P (scratch_or_premodify));
14655 addr = XEXP (addr, 1);
14657 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
14659 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14661 mem = replace_equiv_address_nv (mem, scratch_or_premodify);
14663 /* Now create the move. */
14665 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
14667 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
14672 /* Allocate a 64-bit stack slot to be used for copying SDmode
14673 values through if this function has any SDmode references. */
14676 rs6000_alloc_sdmode_stack_slot (void)
14680 gimple_stmt_iterator gsi;
14682 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
14685 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
14687 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
14690 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14691 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14697 /* Check for any SDmode parameters of the function. */
14698 for (t = DECL_ARGUMENTS (cfun->decl); t; t = DECL_CHAIN (t))
14700 if (TREE_TYPE (t) == error_mark_node)
14703 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
14704 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
14706 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14707 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14715 rs6000_instantiate_decls (void)
14717 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
14718 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
14721 /* Given an rtx X being reloaded into a reg required to be
14722 in class CLASS, return the class of reg to actually use.
14723 In general this is just CLASS; but on some machines
14724 in some cases it is preferable to use a more restrictive class.
14726 On the RS/6000, we have to return NO_REGS when we want to reload a
14727 floating-point CONST_DOUBLE to force it to be copied to memory.
14729 We also don't want to reload integer values into floating-point
14730 registers if we can at all help it. In fact, this can
14731 cause reload to die, if it tries to generate a reload of CTR
14732 into a FP register and discovers it doesn't have the memory location
14735 ??? Would it be a good idea to have reload do the converse, that is
14736 try to reload floating modes into FP registers if possible?
14739 static enum reg_class
14740 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
14742 enum machine_mode mode = GET_MODE (x);
14744 if (VECTOR_UNIT_VSX_P (mode)
14745 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
14748 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
14749 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
14750 && easy_vector_constant (x, mode))
14751 return ALTIVEC_REGS;
14753 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
14756 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
14757 return GENERAL_REGS;
14759 /* For VSX, prefer the traditional registers for 64-bit values because we can
14760 use the non-VSX loads. Prefer the Altivec registers if Altivec is
14761 handling the vector operations (i.e. V16QI, V8HI, and V4SI), or if we
14762 prefer Altivec loads.. */
14763 if (rclass == VSX_REGS)
14765 if (GET_MODE_SIZE (mode) <= 8)
14768 if (VECTOR_UNIT_ALTIVEC_P (mode) || VECTOR_MEM_ALTIVEC_P (mode))
14769 return ALTIVEC_REGS;
14777 /* Debug version of rs6000_preferred_reload_class. */
14778 static enum reg_class
14779 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
14781 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
14784 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
14786 reg_class_names[ret], reg_class_names[rclass],
14787 GET_MODE_NAME (GET_MODE (x)));
14793 /* If we are copying between FP or AltiVec registers and anything else, we need
14794 a memory location. The exception is when we are targeting ppc64 and the
14795 move to/from fpr to gpr instructions are available. Also, under VSX, you
14796 can copy vector registers from the FP register set to the Altivec register
14797 set and vice versa. */
14800 rs6000_secondary_memory_needed (enum reg_class class1,
14801 enum reg_class class2,
14802 enum machine_mode mode)
14804 if (class1 == class2)
14807 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
14808 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
14809 between these classes. But we need memory for other things that can go in
14810 FLOAT_REGS like SFmode. */
14812 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
14813 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
14814 || class1 == FLOAT_REGS))
14815 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
14816 && class2 != FLOAT_REGS);
14818 if (class1 == VSX_REGS || class2 == VSX_REGS)
14821 if (class1 == FLOAT_REGS
14822 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14823 || ((mode != DFmode)
14824 && (mode != DDmode)
14825 && (mode != DImode))))
14828 if (class2 == FLOAT_REGS
14829 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14830 || ((mode != DFmode)
14831 && (mode != DDmode)
14832 && (mode != DImode))))
14835 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
14841 /* Debug version of rs6000_secondary_memory_needed. */
14843 rs6000_debug_secondary_memory_needed (enum reg_class class1,
14844 enum reg_class class2,
14845 enum machine_mode mode)
14847 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
14850 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
14851 "class2 = %s, mode = %s\n",
14852 ret ? "true" : "false", reg_class_names[class1],
14853 reg_class_names[class2], GET_MODE_NAME (mode));
14858 /* Return the register class of a scratch register needed to copy IN into
14859 or out of a register in RCLASS in MODE. If it can be done directly,
14860 NO_REGS is returned. */
14862 static enum reg_class
14863 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
14868 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
14870 && MACHOPIC_INDIRECT
14874 /* We cannot copy a symbolic operand directly into anything
14875 other than BASE_REGS for TARGET_ELF. So indicate that a
14876 register from BASE_REGS is needed as an intermediate
14879 On Darwin, pic addresses require a load from memory, which
14880 needs a base register. */
14881 if (rclass != BASE_REGS
14882 && (GET_CODE (in) == SYMBOL_REF
14883 || GET_CODE (in) == HIGH
14884 || GET_CODE (in) == LABEL_REF
14885 || GET_CODE (in) == CONST))
14889 if (GET_CODE (in) == REG)
14891 regno = REGNO (in);
14892 if (regno >= FIRST_PSEUDO_REGISTER)
14894 regno = true_regnum (in);
14895 if (regno >= FIRST_PSEUDO_REGISTER)
14899 else if (GET_CODE (in) == SUBREG)
14901 regno = true_regnum (in);
14902 if (regno >= FIRST_PSEUDO_REGISTER)
14908 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
14910 if (rclass == GENERAL_REGS || rclass == BASE_REGS
14911 || (regno >= 0 && INT_REGNO_P (regno)))
14914 /* Constants, memory, and FP registers can go into FP registers. */
14915 if ((regno == -1 || FP_REGNO_P (regno))
14916 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
14917 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
14919 /* Memory, and FP/altivec registers can go into fp/altivec registers under
14922 && (regno == -1 || VSX_REGNO_P (regno))
14923 && VSX_REG_CLASS_P (rclass))
14926 /* Memory, and AltiVec registers can go into AltiVec registers. */
14927 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
14928 && rclass == ALTIVEC_REGS)
14931 /* We can copy among the CR registers. */
14932 if ((rclass == CR_REGS || rclass == CR0_REGS)
14933 && regno >= 0 && CR_REGNO_P (regno))
14936 /* Otherwise, we need GENERAL_REGS. */
14937 return GENERAL_REGS;
14940 /* Debug version of rs6000_secondary_reload_class. */
14941 static enum reg_class
14942 rs6000_debug_secondary_reload_class (enum reg_class rclass,
14943 enum machine_mode mode, rtx in)
14945 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
14947 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
14948 "mode = %s, input rtx:\n",
14949 reg_class_names[ret], reg_class_names[rclass],
14950 GET_MODE_NAME (mode));
14956 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
14959 rs6000_cannot_change_mode_class (enum machine_mode from,
14960 enum machine_mode to,
14961 enum reg_class rclass)
14963 unsigned from_size = GET_MODE_SIZE (from);
14964 unsigned to_size = GET_MODE_SIZE (to);
14966 if (from_size != to_size)
14968 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
14969 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
14970 && reg_classes_intersect_p (xclass, rclass));
14973 if (TARGET_E500_DOUBLE
14974 && ((((to) == DFmode) + ((from) == DFmode)) == 1
14975 || (((to) == TFmode) + ((from) == TFmode)) == 1
14976 || (((to) == DDmode) + ((from) == DDmode)) == 1
14977 || (((to) == TDmode) + ((from) == TDmode)) == 1
14978 || (((to) == DImode) + ((from) == DImode)) == 1))
14981 /* Since the VSX register set includes traditional floating point registers
14982 and altivec registers, just check for the size being different instead of
14983 trying to check whether the modes are vector modes. Otherwise it won't
14984 allow say DF and DI to change classes. */
14985 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
14986 return (from_size != 8 && from_size != 16);
14988 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
14989 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
14992 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
14993 && reg_classes_intersect_p (GENERAL_REGS, rclass))
14999 /* Debug version of rs6000_cannot_change_mode_class. */
15001 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
15002 enum machine_mode to,
15003 enum reg_class rclass)
15005 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
15008 "rs6000_cannot_change_mode_class, return %s, from = %s, "
15009 "to = %s, rclass = %s\n",
15010 ret ? "true" : "false",
15011 GET_MODE_NAME (from), GET_MODE_NAME (to),
15012 reg_class_names[rclass]);
15017 /* Given a comparison operation, return the bit number in CCR to test. We
15018 know this is a valid comparison.
15020 SCC_P is 1 if this is for an scc. That means that %D will have been
15021 used instead of %C, so the bits will be in different places.
15023 Return -1 if OP isn't a valid comparison for some reason. */
15026 ccr_bit (rtx op, int scc_p)
15028 enum rtx_code code = GET_CODE (op);
15029 enum machine_mode cc_mode;
15034 if (!COMPARISON_P (op))
15037 reg = XEXP (op, 0);
15039 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
15041 cc_mode = GET_MODE (reg);
15042 cc_regnum = REGNO (reg);
15043 base_bit = 4 * (cc_regnum - CR0_REGNO);
15045 validate_condition_mode (code, cc_mode);
15047 /* When generating a sCOND operation, only positive conditions are
15050 || code == EQ || code == GT || code == LT || code == UNORDERED
15051 || code == GTU || code == LTU);
15056 return scc_p ? base_bit + 3 : base_bit + 2;
15058 return base_bit + 2;
15059 case GT: case GTU: case UNLE:
15060 return base_bit + 1;
15061 case LT: case LTU: case UNGE:
15063 case ORDERED: case UNORDERED:
15064 return base_bit + 3;
15067 /* If scc, we will have done a cror to put the bit in the
15068 unordered position. So test that bit. For integer, this is ! LT
15069 unless this is an scc insn. */
15070 return scc_p ? base_bit + 3 : base_bit;
15073 return scc_p ? base_bit + 3 : base_bit + 1;
15076 gcc_unreachable ();
15080 /* Return the GOT register. */
15083 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
15085 /* The second flow pass currently (June 1999) can't update
15086 regs_ever_live without disturbing other parts of the compiler, so
15087 update it here to make the prolog/epilogue code happy. */
15088 if (!can_create_pseudo_p ()
15089 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
15090 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
15092 crtl->uses_pic_offset_table = 1;
15094 return pic_offset_table_rtx;
15097 static rs6000_stack_t stack_info;
15099 /* Function to init struct machine_function.
15100 This will be called, via a pointer variable,
15101 from push_function_context. */
15103 static struct machine_function *
15104 rs6000_init_machine_status (void)
15106 stack_info.reload_completed = 0;
15107 return ggc_alloc_cleared_machine_function ();
15110 /* These macros test for integers and extract the low-order bits. */
15112 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
15113 && GET_MODE (X) == VOIDmode)
15115 #define INT_LOWPART(X) \
15116 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
15119 extract_MB (rtx op)
15122 unsigned long val = INT_LOWPART (op);
15124 /* If the high bit is zero, the value is the first 1 bit we find
15126 if ((val & 0x80000000) == 0)
15128 gcc_assert (val & 0xffffffff);
15131 while (((val <<= 1) & 0x80000000) == 0)
15136 /* If the high bit is set and the low bit is not, or the mask is all
15137 1's, the value is zero. */
15138 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
15141 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15144 while (((val >>= 1) & 1) != 0)
15151 extract_ME (rtx op)
15154 unsigned long val = INT_LOWPART (op);
15156 /* If the low bit is zero, the value is the first 1 bit we find from
15158 if ((val & 1) == 0)
15160 gcc_assert (val & 0xffffffff);
15163 while (((val >>= 1) & 1) == 0)
15169 /* If the low bit is set and the high bit is not, or the mask is all
15170 1's, the value is 31. */
15171 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
15174 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15177 while (((val <<= 1) & 0x80000000) != 0)
15183 /* Locate some local-dynamic symbol still in use by this function
15184 so that we can print its name in some tls_ld pattern. */
15186 static const char *
15187 rs6000_get_some_local_dynamic_name (void)
15191 if (cfun->machine->some_ld_name)
15192 return cfun->machine->some_ld_name;
15194 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
15196 && for_each_rtx (&PATTERN (insn),
15197 rs6000_get_some_local_dynamic_name_1, 0))
15198 return cfun->machine->some_ld_name;
15200 gcc_unreachable ();
15203 /* Helper function for rs6000_get_some_local_dynamic_name. */
15206 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
15210 if (GET_CODE (x) == SYMBOL_REF)
15212 const char *str = XSTR (x, 0);
15213 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
15215 cfun->machine->some_ld_name = str;
15223 /* Write out a function code label. */
15226 rs6000_output_function_entry (FILE *file, const char *fname)
15228 if (fname[0] != '.')
15230 switch (DEFAULT_ABI)
15233 gcc_unreachable ();
15239 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
15248 RS6000_OUTPUT_BASENAME (file, fname);
15251 /* Print an operand. Recognize special options, documented below. */
15254 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
15255 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
15257 #define SMALL_DATA_RELOC "sda21"
15258 #define SMALL_DATA_REG 0
15262 print_operand (FILE *file, rtx x, int code)
15266 unsigned HOST_WIDE_INT uval;
15271 /* Write out an instruction after the call which may be replaced
15272 with glue code by the loader. This depends on the AIX version. */
15273 asm_fprintf (file, RS6000_CALL_GLUE);
15276 /* %a is output_address. */
15279 /* If X is a constant integer whose low-order 5 bits are zero,
15280 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
15281 in the AIX assembler where "sri" with a zero shift count
15282 writes a trash instruction. */
15283 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
15290 /* If constant, low-order 16 bits of constant, unsigned.
15291 Otherwise, write normally. */
15293 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
15295 print_operand (file, x, 0);
15299 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
15300 for 64-bit mask direction. */
15301 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
15304 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
15308 /* X is a CR register. Print the number of the GT bit of the CR. */
15309 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15310 output_operand_lossage ("invalid %%c value");
15312 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
15316 /* Like 'J' but get to the GT bit only. */
15317 gcc_assert (GET_CODE (x) == REG);
15319 /* Bit 1 is GT bit. */
15320 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
15322 /* Add one for shift count in rlinm for scc. */
15323 fprintf (file, "%d", i + 1);
15327 /* X is a CR register. Print the number of the EQ bit of the CR */
15328 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15329 output_operand_lossage ("invalid %%E value");
15331 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
15335 /* X is a CR register. Print the shift count needed to move it
15336 to the high-order four bits. */
15337 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15338 output_operand_lossage ("invalid %%f value");
15340 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
15344 /* Similar, but print the count for the rotate in the opposite
15346 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15347 output_operand_lossage ("invalid %%F value");
15349 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
15353 /* X is a constant integer. If it is negative, print "m",
15354 otherwise print "z". This is to make an aze or ame insn. */
15355 if (GET_CODE (x) != CONST_INT)
15356 output_operand_lossage ("invalid %%G value");
15357 else if (INTVAL (x) >= 0)
15364 /* If constant, output low-order five bits. Otherwise, write
15367 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
15369 print_operand (file, x, 0);
15373 /* If constant, output low-order six bits. Otherwise, write
15376 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
15378 print_operand (file, x, 0);
15382 /* Print `i' if this is a constant, else nothing. */
15388 /* Write the bit number in CCR for jump. */
15389 i = ccr_bit (x, 0);
15391 output_operand_lossage ("invalid %%j code");
15393 fprintf (file, "%d", i);
15397 /* Similar, but add one for shift count in rlinm for scc and pass
15398 scc flag to `ccr_bit'. */
15399 i = ccr_bit (x, 1);
15401 output_operand_lossage ("invalid %%J code");
15403 /* If we want bit 31, write a shift count of zero, not 32. */
15404 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15408 /* X must be a constant. Write the 1's complement of the
15411 output_operand_lossage ("invalid %%k value");
15413 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
15417 /* X must be a symbolic constant on ELF. Write an
15418 expression suitable for an 'addi' that adds in the low 16
15419 bits of the MEM. */
15420 if (GET_CODE (x) == CONST)
15422 if (GET_CODE (XEXP (x, 0)) != PLUS
15423 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
15424 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
15425 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
15426 output_operand_lossage ("invalid %%K value");
15428 print_operand_address (file, x);
15429 fputs ("@l", file);
15432 /* %l is output_asm_label. */
15435 /* Write second word of DImode or DFmode reference. Works on register
15436 or non-indexed memory only. */
15437 if (GET_CODE (x) == REG)
15438 fputs (reg_names[REGNO (x) + 1], file);
15439 else if (GET_CODE (x) == MEM)
15441 /* Handle possible auto-increment. Since it is pre-increment and
15442 we have already done it, we can just use an offset of word. */
15443 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15444 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15445 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15447 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15448 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15451 output_address (XEXP (adjust_address_nv (x, SImode,
15455 if (small_data_operand (x, GET_MODE (x)))
15456 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15457 reg_names[SMALL_DATA_REG]);
15462 /* MB value for a mask operand. */
15463 if (! mask_operand (x, SImode))
15464 output_operand_lossage ("invalid %%m value");
15466 fprintf (file, "%d", extract_MB (x));
15470 /* ME value for a mask operand. */
15471 if (! mask_operand (x, SImode))
15472 output_operand_lossage ("invalid %%M value");
15474 fprintf (file, "%d", extract_ME (x));
15477 /* %n outputs the negative of its operand. */
15480 /* Write the number of elements in the vector times 4. */
15481 if (GET_CODE (x) != PARALLEL)
15482 output_operand_lossage ("invalid %%N value");
15484 fprintf (file, "%d", XVECLEN (x, 0) * 4);
15488 /* Similar, but subtract 1 first. */
15489 if (GET_CODE (x) != PARALLEL)
15490 output_operand_lossage ("invalid %%O value");
15492 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
15496 /* X is a CONST_INT that is a power of two. Output the logarithm. */
15498 || INT_LOWPART (x) < 0
15499 || (i = exact_log2 (INT_LOWPART (x))) < 0)
15500 output_operand_lossage ("invalid %%p value");
15502 fprintf (file, "%d", i);
15506 /* The operand must be an indirect memory reference. The result
15507 is the register name. */
15508 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
15509 || REGNO (XEXP (x, 0)) >= 32)
15510 output_operand_lossage ("invalid %%P value");
15512 fputs (reg_names[REGNO (XEXP (x, 0))], file);
15516 /* This outputs the logical code corresponding to a boolean
15517 expression. The expression may have one or both operands
15518 negated (if one, only the first one). For condition register
15519 logical operations, it will also treat the negated
15520 CR codes as NOTs, but not handle NOTs of them. */
15522 const char *const *t = 0;
15524 enum rtx_code code = GET_CODE (x);
15525 static const char * const tbl[3][3] = {
15526 { "and", "andc", "nor" },
15527 { "or", "orc", "nand" },
15528 { "xor", "eqv", "xor" } };
15532 else if (code == IOR)
15534 else if (code == XOR)
15537 output_operand_lossage ("invalid %%q value");
15539 if (GET_CODE (XEXP (x, 0)) != NOT)
15543 if (GET_CODE (XEXP (x, 1)) == NOT)
15561 /* X is a CR register. Print the mask for `mtcrf'. */
15562 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15563 output_operand_lossage ("invalid %%R value");
15565 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
15569 /* Low 5 bits of 32 - value */
15571 output_operand_lossage ("invalid %%s value");
15573 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
15577 /* PowerPC64 mask position. All 0's is excluded.
15578 CONST_INT 32-bit mask is considered sign-extended so any
15579 transition must occur within the CONST_INT, not on the boundary. */
15580 if (! mask64_operand (x, DImode))
15581 output_operand_lossage ("invalid %%S value");
15583 uval = INT_LOWPART (x);
15585 if (uval & 1) /* Clear Left */
15587 #if HOST_BITS_PER_WIDE_INT > 64
15588 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15592 else /* Clear Right */
15595 #if HOST_BITS_PER_WIDE_INT > 64
15596 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15602 gcc_assert (i >= 0);
15603 fprintf (file, "%d", i);
15607 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
15608 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
15610 /* Bit 3 is OV bit. */
15611 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
15613 /* If we want bit 31, write a shift count of zero, not 32. */
15614 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15618 /* Print the symbolic name of a branch target register. */
15619 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
15620 && REGNO (x) != CTR_REGNO))
15621 output_operand_lossage ("invalid %%T value");
15622 else if (REGNO (x) == LR_REGNO)
15623 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
15625 fputs ("ctr", file);
15629 /* High-order 16 bits of constant for use in unsigned operand. */
15631 output_operand_lossage ("invalid %%u value");
15633 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15634 (INT_LOWPART (x) >> 16) & 0xffff);
15638 /* High-order 16 bits of constant for use in signed operand. */
15640 output_operand_lossage ("invalid %%v value");
15642 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15643 (INT_LOWPART (x) >> 16) & 0xffff);
15647 /* Print `u' if this has an auto-increment or auto-decrement. */
15648 if (GET_CODE (x) == MEM
15649 && (GET_CODE (XEXP (x, 0)) == PRE_INC
15650 || GET_CODE (XEXP (x, 0)) == PRE_DEC
15651 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
15656 /* Print the trap code for this operand. */
15657 switch (GET_CODE (x))
15660 fputs ("eq", file); /* 4 */
15663 fputs ("ne", file); /* 24 */
15666 fputs ("lt", file); /* 16 */
15669 fputs ("le", file); /* 20 */
15672 fputs ("gt", file); /* 8 */
15675 fputs ("ge", file); /* 12 */
15678 fputs ("llt", file); /* 2 */
15681 fputs ("lle", file); /* 6 */
15684 fputs ("lgt", file); /* 1 */
15687 fputs ("lge", file); /* 5 */
15690 gcc_unreachable ();
15695 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
15698 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
15699 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
15701 print_operand (file, x, 0);
15705 /* MB value for a PowerPC64 rldic operand. */
15706 val = (GET_CODE (x) == CONST_INT
15707 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
15712 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
15713 if ((val <<= 1) < 0)
15716 #if HOST_BITS_PER_WIDE_INT == 32
15717 if (GET_CODE (x) == CONST_INT && i >= 0)
15718 i += 32; /* zero-extend high-part was all 0's */
15719 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
15721 val = CONST_DOUBLE_LOW (x);
15727 for ( ; i < 64; i++)
15728 if ((val <<= 1) < 0)
15733 fprintf (file, "%d", i + 1);
15737 /* X is a FPR or Altivec register used in a VSX context. */
15738 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
15739 output_operand_lossage ("invalid %%x value");
15742 int reg = REGNO (x);
15743 int vsx_reg = (FP_REGNO_P (reg)
15745 : reg - FIRST_ALTIVEC_REGNO + 32);
15747 #ifdef TARGET_REGNAMES
15748 if (TARGET_REGNAMES)
15749 fprintf (file, "%%vs%d", vsx_reg);
15752 fprintf (file, "%d", vsx_reg);
15757 if (GET_CODE (x) == MEM
15758 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
15759 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
15760 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
15765 /* Like 'L', for third word of TImode */
15766 if (GET_CODE (x) == REG)
15767 fputs (reg_names[REGNO (x) + 2], file);
15768 else if (GET_CODE (x) == MEM)
15770 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15771 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15772 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15773 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15774 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15776 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
15777 if (small_data_operand (x, GET_MODE (x)))
15778 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15779 reg_names[SMALL_DATA_REG]);
15784 /* X is a SYMBOL_REF. Write out the name preceded by a
15785 period and without any trailing data in brackets. Used for function
15786 names. If we are configured for System V (or the embedded ABI) on
15787 the PowerPC, do not emit the period, since those systems do not use
15788 TOCs and the like. */
15789 gcc_assert (GET_CODE (x) == SYMBOL_REF);
15791 /* Mark the decl as referenced so that cgraph will output the
15793 if (SYMBOL_REF_DECL (x))
15794 mark_decl_referenced (SYMBOL_REF_DECL (x));
15796 /* For macho, check to see if we need a stub. */
15799 const char *name = XSTR (x, 0);
15801 if (darwin_emit_branch_islands
15802 && MACHOPIC_INDIRECT
15803 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
15804 name = machopic_indirection_name (x, /*stub_p=*/true);
15806 assemble_name (file, name);
15808 else if (!DOT_SYMBOLS)
15809 assemble_name (file, XSTR (x, 0));
15811 rs6000_output_function_entry (file, XSTR (x, 0));
15815 /* Like 'L', for last word of TImode. */
15816 if (GET_CODE (x) == REG)
15817 fputs (reg_names[REGNO (x) + 3], file);
15818 else if (GET_CODE (x) == MEM)
15820 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15821 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15822 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15823 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15824 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15826 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
15827 if (small_data_operand (x, GET_MODE (x)))
15828 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15829 reg_names[SMALL_DATA_REG]);
15833 /* Print AltiVec or SPE memory operand. */
15838 gcc_assert (GET_CODE (x) == MEM);
15842 /* Ugly hack because %y is overloaded. */
15843 if ((TARGET_SPE || TARGET_E500_DOUBLE)
15844 && (GET_MODE_SIZE (GET_MODE (x)) == 8
15845 || GET_MODE (x) == TFmode
15846 || GET_MODE (x) == TImode))
15848 /* Handle [reg]. */
15849 if (GET_CODE (tmp) == REG)
15851 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
15854 /* Handle [reg+UIMM]. */
15855 else if (GET_CODE (tmp) == PLUS &&
15856 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
15860 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
15862 x = INTVAL (XEXP (tmp, 1));
15863 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
15867 /* Fall through. Must be [reg+reg]. */
15869 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
15870 && GET_CODE (tmp) == AND
15871 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
15872 && INTVAL (XEXP (tmp, 1)) == -16)
15873 tmp = XEXP (tmp, 0);
15874 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
15875 && GET_CODE (tmp) == PRE_MODIFY)
15876 tmp = XEXP (tmp, 1);
15877 if (GET_CODE (tmp) == REG)
15878 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
15881 if (!GET_CODE (tmp) == PLUS
15882 || !REG_P (XEXP (tmp, 0))
15883 || !REG_P (XEXP (tmp, 1)))
15885 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
15889 if (REGNO (XEXP (tmp, 0)) == 0)
15890 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
15891 reg_names[ REGNO (XEXP (tmp, 0)) ]);
15893 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
15894 reg_names[ REGNO (XEXP (tmp, 1)) ]);
15900 if (GET_CODE (x) == REG)
15901 fprintf (file, "%s", reg_names[REGNO (x)]);
15902 else if (GET_CODE (x) == MEM)
15904 /* We need to handle PRE_INC and PRE_DEC here, since we need to
15905 know the width from the mode. */
15906 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
15907 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
15908 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
15909 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
15910 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
15911 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
15912 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15913 output_address (XEXP (XEXP (x, 0), 1));
15915 output_address (XEXP (x, 0));
15919 if (toc_relative_expr_p (x))
15920 /* This hack along with a corresponding hack in
15921 rs6000_output_addr_const_extra arranges to output addends
15922 where the assembler expects to find them. eg.
15923 (const (plus (unspec [symbol_ref ("x") tocrel]) 4))
15924 without this hack would be output as "x@toc+4". We
15926 output_addr_const (file, tocrel_base);
15928 output_addr_const (file, x);
15933 assemble_name (file, rs6000_get_some_local_dynamic_name ());
15937 output_operand_lossage ("invalid %%xn code");
15941 /* Print the address of an operand. */
15944 print_operand_address (FILE *file, rtx x)
15946 if (GET_CODE (x) == REG)
15947 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
15948 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
15949 || GET_CODE (x) == LABEL_REF)
15951 output_addr_const (file, x);
15952 if (small_data_operand (x, GET_MODE (x)))
15953 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15954 reg_names[SMALL_DATA_REG]);
15956 gcc_assert (!TARGET_TOC);
15958 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
15960 gcc_assert (REG_P (XEXP (x, 0)));
15961 if (REGNO (XEXP (x, 0)) == 0)
15962 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
15963 reg_names[ REGNO (XEXP (x, 0)) ]);
15965 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
15966 reg_names[ REGNO (XEXP (x, 1)) ]);
15968 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
15969 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
15970 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
15972 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15973 && CONSTANT_P (XEXP (x, 1)))
15975 fprintf (file, "lo16(");
15976 output_addr_const (file, XEXP (x, 1));
15977 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15980 else if (legitimate_constant_pool_address_p (x, QImode, true))
15982 /* This hack along with a corresponding hack in
15983 rs6000_output_addr_const_extra arranges to output addends
15984 where the assembler expects to find them. eg.
15986 . (const (plus (unspec [symbol_ref ("x") tocrel]) 8)))
15987 without this hack would be output as "x@toc+8@l(9)". We
15988 want "x+8@toc@l(9)". */
15989 output_addr_const (file, tocrel_base);
15990 if (GET_CODE (x) == LO_SUM)
15991 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15993 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
15996 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15997 && CONSTANT_P (XEXP (x, 1)))
15999 output_addr_const (file, XEXP (x, 1));
16000 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16004 gcc_unreachable ();
16007 /* Implement TARGET_OUTPUT_ADDR_CONST_EXTRA. */
16010 rs6000_output_addr_const_extra (FILE *file, rtx x)
16012 if (GET_CODE (x) == UNSPEC)
16013 switch (XINT (x, 1))
16015 case UNSPEC_TOCREL:
16016 gcc_assert (GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF);
16017 output_addr_const (file, XVECEXP (x, 0, 0));
16018 if (x == tocrel_base && tocrel_offset != const0_rtx)
16020 if (INTVAL (tocrel_offset) >= 0)
16021 fprintf (file, "+");
16022 output_addr_const (file, tocrel_offset);
16024 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
16027 assemble_name (file, toc_label_name);
16029 else if (TARGET_ELF)
16030 fputs ("@toc", file);
16034 case UNSPEC_MACHOPIC_OFFSET:
16035 output_addr_const (file, XVECEXP (x, 0, 0));
16037 machopic_output_function_base_name (file);
16044 /* Target hook for assembling integer objects. The PowerPC version has
16045 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
16046 is defined. It also needs to handle DI-mode objects on 64-bit
16050 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
16052 #ifdef RELOCATABLE_NEEDS_FIXUP
16053 /* Special handling for SI values. */
16054 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
16056 static int recurse = 0;
16058 /* For -mrelocatable, we mark all addresses that need to be fixed up
16059 in the .fixup section. */
16060 if (TARGET_RELOCATABLE
16061 && in_section != toc_section
16062 && in_section != text_section
16063 && !unlikely_text_section_p (in_section)
16065 && GET_CODE (x) != CONST_INT
16066 && GET_CODE (x) != CONST_DOUBLE
16072 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
16074 ASM_OUTPUT_LABEL (asm_out_file, buf);
16075 fprintf (asm_out_file, "\t.long\t(");
16076 output_addr_const (asm_out_file, x);
16077 fprintf (asm_out_file, ")@fixup\n");
16078 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
16079 ASM_OUTPUT_ALIGN (asm_out_file, 2);
16080 fprintf (asm_out_file, "\t.long\t");
16081 assemble_name (asm_out_file, buf);
16082 fprintf (asm_out_file, "\n\t.previous\n");
16086 /* Remove initial .'s to turn a -mcall-aixdesc function
16087 address into the address of the descriptor, not the function
16089 else if (GET_CODE (x) == SYMBOL_REF
16090 && XSTR (x, 0)[0] == '.'
16091 && DEFAULT_ABI == ABI_AIX)
16093 const char *name = XSTR (x, 0);
16094 while (*name == '.')
16097 fprintf (asm_out_file, "\t.long\t%s\n", name);
16101 #endif /* RELOCATABLE_NEEDS_FIXUP */
16102 return default_assemble_integer (x, size, aligned_p);
16105 #if defined (HAVE_GAS_HIDDEN) && !defined (TARGET_MACHO)
16106 /* Emit an assembler directive to set symbol visibility for DECL to
16107 VISIBILITY_TYPE. */
16110 rs6000_assemble_visibility (tree decl, int vis)
16112 /* Functions need to have their entry point symbol visibility set as
16113 well as their descriptor symbol visibility. */
16114 if (DEFAULT_ABI == ABI_AIX
16116 && TREE_CODE (decl) == FUNCTION_DECL)
16118 static const char * const visibility_types[] = {
16119 NULL, "internal", "hidden", "protected"
16122 const char *name, *type;
16124 name = ((* targetm.strip_name_encoding)
16125 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
16126 type = visibility_types[vis];
16128 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
16129 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
16132 default_assemble_visibility (decl, vis);
16137 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
16139 /* Reversal of FP compares takes care -- an ordered compare
16140 becomes an unordered compare and vice versa. */
16141 if (mode == CCFPmode
16142 && (!flag_finite_math_only
16143 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
16144 || code == UNEQ || code == LTGT))
16145 return reverse_condition_maybe_unordered (code);
16147 return reverse_condition (code);
16150 /* Generate a compare for CODE. Return a brand-new rtx that
16151 represents the result of the compare. */
16154 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
16156 enum machine_mode comp_mode;
16157 rtx compare_result;
16158 enum rtx_code code = GET_CODE (cmp);
16159 rtx op0 = XEXP (cmp, 0);
16160 rtx op1 = XEXP (cmp, 1);
16162 if (FLOAT_MODE_P (mode))
16163 comp_mode = CCFPmode;
16164 else if (code == GTU || code == LTU
16165 || code == GEU || code == LEU)
16166 comp_mode = CCUNSmode;
16167 else if ((code == EQ || code == NE)
16168 && GET_CODE (op0) == SUBREG
16169 && GET_CODE (op1) == SUBREG
16170 && SUBREG_PROMOTED_UNSIGNED_P (op0)
16171 && SUBREG_PROMOTED_UNSIGNED_P (op1))
16172 /* These are unsigned values, perhaps there will be a later
16173 ordering compare that can be shared with this one.
16174 Unfortunately we cannot detect the signedness of the operands
16175 for non-subregs. */
16176 comp_mode = CCUNSmode;
16178 comp_mode = CCmode;
16180 /* First, the compare. */
16181 compare_result = gen_reg_rtx (comp_mode);
16183 /* E500 FP compare instructions on the GPRs. Yuck! */
16184 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
16185 && FLOAT_MODE_P (mode))
16187 rtx cmp, or_result, compare_result2;
16188 enum machine_mode op_mode = GET_MODE (op0);
16190 if (op_mode == VOIDmode)
16191 op_mode = GET_MODE (op1);
16193 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
16194 This explains the following mess. */
16198 case EQ: case UNEQ: case NE: case LTGT:
16202 cmp = (flag_finite_math_only && !flag_trapping_math)
16203 ? gen_tstsfeq_gpr (compare_result, op0, op1)
16204 : gen_cmpsfeq_gpr (compare_result, op0, op1);
16208 cmp = (flag_finite_math_only && !flag_trapping_math)
16209 ? gen_tstdfeq_gpr (compare_result, op0, op1)
16210 : gen_cmpdfeq_gpr (compare_result, op0, op1);
16214 cmp = (flag_finite_math_only && !flag_trapping_math)
16215 ? gen_tsttfeq_gpr (compare_result, op0, op1)
16216 : gen_cmptfeq_gpr (compare_result, op0, op1);
16220 gcc_unreachable ();
16224 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
16228 cmp = (flag_finite_math_only && !flag_trapping_math)
16229 ? gen_tstsfgt_gpr (compare_result, op0, op1)
16230 : gen_cmpsfgt_gpr (compare_result, op0, op1);
16234 cmp = (flag_finite_math_only && !flag_trapping_math)
16235 ? gen_tstdfgt_gpr (compare_result, op0, op1)
16236 : gen_cmpdfgt_gpr (compare_result, op0, op1);
16240 cmp = (flag_finite_math_only && !flag_trapping_math)
16241 ? gen_tsttfgt_gpr (compare_result, op0, op1)
16242 : gen_cmptfgt_gpr (compare_result, op0, op1);
16246 gcc_unreachable ();
16250 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
16254 cmp = (flag_finite_math_only && !flag_trapping_math)
16255 ? gen_tstsflt_gpr (compare_result, op0, op1)
16256 : gen_cmpsflt_gpr (compare_result, op0, op1);
16260 cmp = (flag_finite_math_only && !flag_trapping_math)
16261 ? gen_tstdflt_gpr (compare_result, op0, op1)
16262 : gen_cmpdflt_gpr (compare_result, op0, op1);
16266 cmp = (flag_finite_math_only && !flag_trapping_math)
16267 ? gen_tsttflt_gpr (compare_result, op0, op1)
16268 : gen_cmptflt_gpr (compare_result, op0, op1);
16272 gcc_unreachable ();
16276 gcc_unreachable ();
16279 /* Synthesize LE and GE from LT/GT || EQ. */
16280 if (code == LE || code == GE || code == LEU || code == GEU)
16286 case LE: code = LT; break;
16287 case GE: code = GT; break;
16288 case LEU: code = LT; break;
16289 case GEU: code = GT; break;
16290 default: gcc_unreachable ();
16293 compare_result2 = gen_reg_rtx (CCFPmode);
16299 cmp = (flag_finite_math_only && !flag_trapping_math)
16300 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
16301 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
16305 cmp = (flag_finite_math_only && !flag_trapping_math)
16306 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
16307 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
16311 cmp = (flag_finite_math_only && !flag_trapping_math)
16312 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
16313 : gen_cmptfeq_gpr (compare_result2, op0, op1);
16317 gcc_unreachable ();
16321 /* OR them together. */
16322 or_result = gen_reg_rtx (CCFPmode);
16323 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
16325 compare_result = or_result;
16330 if (code == NE || code == LTGT)
16340 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
16341 CLOBBERs to match cmptf_internal2 pattern. */
16342 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
16343 && GET_MODE (op0) == TFmode
16344 && !TARGET_IEEEQUAD
16345 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
16346 emit_insn (gen_rtx_PARALLEL (VOIDmode,
16348 gen_rtx_SET (VOIDmode,
16350 gen_rtx_COMPARE (comp_mode, op0, op1)),
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 (DFmode)),
16356 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16357 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16358 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16359 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (Pmode)))));
16360 else if (GET_CODE (op1) == UNSPEC
16361 && XINT (op1, 1) == UNSPEC_SP_TEST)
16363 rtx op1b = XVECEXP (op1, 0, 0);
16364 comp_mode = CCEQmode;
16365 compare_result = gen_reg_rtx (CCEQmode);
16367 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
16369 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
16372 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
16373 gen_rtx_COMPARE (comp_mode, op0, op1)));
16376 /* Some kinds of FP comparisons need an OR operation;
16377 under flag_finite_math_only we don't bother. */
16378 if (FLOAT_MODE_P (mode)
16379 && !flag_finite_math_only
16380 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
16381 && (code == LE || code == GE
16382 || code == UNEQ || code == LTGT
16383 || code == UNGT || code == UNLT))
16385 enum rtx_code or1, or2;
16386 rtx or1_rtx, or2_rtx, compare2_rtx;
16387 rtx or_result = gen_reg_rtx (CCEQmode);
16391 case LE: or1 = LT; or2 = EQ; break;
16392 case GE: or1 = GT; or2 = EQ; break;
16393 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
16394 case LTGT: or1 = LT; or2 = GT; break;
16395 case UNGT: or1 = UNORDERED; or2 = GT; break;
16396 case UNLT: or1 = UNORDERED; or2 = LT; break;
16397 default: gcc_unreachable ();
16399 validate_condition_mode (or1, comp_mode);
16400 validate_condition_mode (or2, comp_mode);
16401 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
16402 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
16403 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
16404 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
16406 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
16408 compare_result = or_result;
16412 validate_condition_mode (code, GET_MODE (compare_result));
16414 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
16418 /* Emit the RTL for an sISEL pattern. */
16421 rs6000_emit_sISEL (enum machine_mode mode ATTRIBUTE_UNUSED, rtx operands[])
16423 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
16427 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
16430 enum machine_mode op_mode;
16431 enum rtx_code cond_code;
16432 rtx result = operands[0];
16434 if (TARGET_ISEL && (mode == SImode || mode == DImode))
16436 rs6000_emit_sISEL (mode, operands);
16440 condition_rtx = rs6000_generate_compare (operands[1], mode);
16441 cond_code = GET_CODE (condition_rtx);
16443 if (FLOAT_MODE_P (mode)
16444 && !TARGET_FPRS && TARGET_HARD_FLOAT)
16448 PUT_MODE (condition_rtx, SImode);
16449 t = XEXP (condition_rtx, 0);
16451 gcc_assert (cond_code == NE || cond_code == EQ);
16453 if (cond_code == NE)
16454 emit_insn (gen_e500_flip_gt_bit (t, t));
16456 emit_insn (gen_move_from_CR_gt_bit (result, t));
16460 if (cond_code == NE
16461 || cond_code == GE || cond_code == LE
16462 || cond_code == GEU || cond_code == LEU
16463 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
16465 rtx not_result = gen_reg_rtx (CCEQmode);
16466 rtx not_op, rev_cond_rtx;
16467 enum machine_mode cc_mode;
16469 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
16471 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
16472 SImode, XEXP (condition_rtx, 0), const0_rtx);
16473 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
16474 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
16475 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
16478 op_mode = GET_MODE (XEXP (operands[1], 0));
16479 if (op_mode == VOIDmode)
16480 op_mode = GET_MODE (XEXP (operands[1], 1));
16482 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
16484 PUT_MODE (condition_rtx, DImode);
16485 convert_move (result, condition_rtx, 0);
16489 PUT_MODE (condition_rtx, SImode);
16490 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
16494 /* Emit a branch of kind CODE to location LOC. */
16497 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
16499 rtx condition_rtx, loc_ref;
16501 condition_rtx = rs6000_generate_compare (operands[0], mode);
16502 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
16503 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
16504 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
16505 loc_ref, pc_rtx)));
16508 /* Return the string to output a conditional branch to LABEL, which is
16509 the operand number of the label, or -1 if the branch is really a
16510 conditional return.
16512 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
16513 condition code register and its mode specifies what kind of
16514 comparison we made.
16516 REVERSED is nonzero if we should reverse the sense of the comparison.
16518 INSN is the insn. */
16521 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
16523 static char string[64];
16524 enum rtx_code code = GET_CODE (op);
16525 rtx cc_reg = XEXP (op, 0);
16526 enum machine_mode mode = GET_MODE (cc_reg);
16527 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
16528 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
16529 int really_reversed = reversed ^ need_longbranch;
16535 validate_condition_mode (code, mode);
16537 /* Work out which way this really branches. We could use
16538 reverse_condition_maybe_unordered here always but this
16539 makes the resulting assembler clearer. */
16540 if (really_reversed)
16542 /* Reversal of FP compares takes care -- an ordered compare
16543 becomes an unordered compare and vice versa. */
16544 if (mode == CCFPmode)
16545 code = reverse_condition_maybe_unordered (code);
16547 code = reverse_condition (code);
16550 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
16552 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
16557 /* Opposite of GT. */
16566 gcc_unreachable ();
16572 /* Not all of these are actually distinct opcodes, but
16573 we distinguish them for clarity of the resulting assembler. */
16574 case NE: case LTGT:
16575 ccode = "ne"; break;
16576 case EQ: case UNEQ:
16577 ccode = "eq"; break;
16579 ccode = "ge"; break;
16580 case GT: case GTU: case UNGT:
16581 ccode = "gt"; break;
16583 ccode = "le"; break;
16584 case LT: case LTU: case UNLT:
16585 ccode = "lt"; break;
16586 case UNORDERED: ccode = "un"; break;
16587 case ORDERED: ccode = "nu"; break;
16588 case UNGE: ccode = "nl"; break;
16589 case UNLE: ccode = "ng"; break;
16591 gcc_unreachable ();
16594 /* Maybe we have a guess as to how likely the branch is.
16595 The old mnemonics don't have a way to specify this information. */
16597 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
16598 if (note != NULL_RTX)
16600 /* PROB is the difference from 50%. */
16601 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
16603 /* Only hint for highly probable/improbable branches on newer
16604 cpus as static prediction overrides processor dynamic
16605 prediction. For older cpus we may as well always hint, but
16606 assume not taken for branches that are very close to 50% as a
16607 mispredicted taken branch is more expensive than a
16608 mispredicted not-taken branch. */
16609 if (rs6000_always_hint
16610 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
16611 && br_prob_note_reliable_p (note)))
16613 if (abs (prob) > REG_BR_PROB_BASE / 20
16614 && ((prob > 0) ^ need_longbranch))
16622 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
16624 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
16626 /* We need to escape any '%' characters in the reg_names string.
16627 Assume they'd only be the first character.... */
16628 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
16630 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
16634 /* If the branch distance was too far, we may have to use an
16635 unconditional branch to go the distance. */
16636 if (need_longbranch)
16637 s += sprintf (s, ",$+8\n\tb %s", label);
16639 s += sprintf (s, ",%s", label);
16645 /* Return the string to flip the GT bit on a CR. */
16647 output_e500_flip_gt_bit (rtx dst, rtx src)
16649 static char string[64];
16652 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
16653 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
16656 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
16657 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
16659 sprintf (string, "crnot %d,%d", a, b);
16663 /* Return insn for VSX or Altivec comparisons. */
16666 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
16669 enum machine_mode mode = GET_MODE (op0);
16677 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
16683 mask = gen_reg_rtx (mode);
16684 emit_insn (gen_rtx_SET (VOIDmode,
16686 gen_rtx_fmt_ee (code, mode, op0, op1)));
16693 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
16694 DMODE is expected destination mode. This is a recursive function. */
16697 rs6000_emit_vector_compare (enum rtx_code rcode,
16699 enum machine_mode dmode)
16702 bool swap_operands = false;
16703 bool try_again = false;
16705 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
16706 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
16708 /* See if the comparison works as is. */
16709 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16717 swap_operands = true;
16722 swap_operands = true;
16730 /* Invert condition and try again.
16731 e.g., A != B becomes ~(A==B). */
16733 enum rtx_code rev_code;
16734 enum insn_code nor_code;
16737 rev_code = reverse_condition_maybe_unordered (rcode);
16738 if (rev_code == UNKNOWN)
16741 nor_code = optab_handler (one_cmpl_optab, dmode);
16742 if (nor_code == CODE_FOR_nothing)
16745 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
16749 mask = gen_reg_rtx (dmode);
16750 emit_insn (GEN_FCN (nor_code) (mask, mask2));
16758 /* Try GT/GTU/LT/LTU OR EQ */
16761 enum insn_code ior_code;
16762 enum rtx_code new_code;
16783 gcc_unreachable ();
16786 ior_code = optab_handler (ior_optab, dmode);
16787 if (ior_code == CODE_FOR_nothing)
16790 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
16794 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
16798 mask = gen_reg_rtx (dmode);
16799 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
16817 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16822 /* You only get two chances. */
16826 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
16827 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
16828 operands for the relation operation COND. */
16831 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
16832 rtx cond, rtx cc_op0, rtx cc_op1)
16834 enum machine_mode dest_mode = GET_MODE (dest);
16835 enum rtx_code rcode = GET_CODE (cond);
16836 enum machine_mode cc_mode = CCmode;
16840 bool invert_move = false;
16842 if (VECTOR_UNIT_NONE_P (dest_mode))
16847 /* Swap operands if we can, and fall back to doing the operation as
16848 specified, and doing a NOR to invert the test. */
16854 /* Invert condition and try again.
16855 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
16856 invert_move = true;
16857 rcode = reverse_condition_maybe_unordered (rcode);
16858 if (rcode == UNKNOWN)
16862 /* Mark unsigned tests with CCUNSmode. */
16867 cc_mode = CCUNSmode;
16874 /* Get the vector mask for the given relational operations. */
16875 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
16883 op_true = op_false;
16887 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, CONST0_RTX (dest_mode));
16888 emit_insn (gen_rtx_SET (VOIDmode,
16890 gen_rtx_IF_THEN_ELSE (dest_mode,
16897 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
16898 operands of the last comparison is nonzero/true, FALSE_COND if it
16899 is zero/false. Return 0 if the hardware has no such operation. */
16902 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
16904 enum rtx_code code = GET_CODE (op);
16905 rtx op0 = XEXP (op, 0);
16906 rtx op1 = XEXP (op, 1);
16907 REAL_VALUE_TYPE c1;
16908 enum machine_mode compare_mode = GET_MODE (op0);
16909 enum machine_mode result_mode = GET_MODE (dest);
16911 bool is_against_zero;
16913 /* These modes should always match. */
16914 if (GET_MODE (op1) != compare_mode
16915 /* In the isel case however, we can use a compare immediate, so
16916 op1 may be a small constant. */
16917 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
16919 if (GET_MODE (true_cond) != result_mode)
16921 if (GET_MODE (false_cond) != result_mode)
16924 /* First, work out if the hardware can do this at all, or
16925 if it's too slow.... */
16926 if (!FLOAT_MODE_P (compare_mode))
16929 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
16932 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
16933 && SCALAR_FLOAT_MODE_P (compare_mode))
16936 is_against_zero = op1 == CONST0_RTX (compare_mode);
16938 /* A floating-point subtract might overflow, underflow, or produce
16939 an inexact result, thus changing the floating-point flags, so it
16940 can't be generated if we care about that. It's safe if one side
16941 of the construct is zero, since then no subtract will be
16943 if (SCALAR_FLOAT_MODE_P (compare_mode)
16944 && flag_trapping_math && ! is_against_zero)
16947 /* Eliminate half of the comparisons by switching operands, this
16948 makes the remaining code simpler. */
16949 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
16950 || code == LTGT || code == LT || code == UNLE)
16952 code = reverse_condition_maybe_unordered (code);
16954 true_cond = false_cond;
16958 /* UNEQ and LTGT take four instructions for a comparison with zero,
16959 it'll probably be faster to use a branch here too. */
16960 if (code == UNEQ && HONOR_NANS (compare_mode))
16963 if (GET_CODE (op1) == CONST_DOUBLE)
16964 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
16966 /* We're going to try to implement comparisons by performing
16967 a subtract, then comparing against zero. Unfortunately,
16968 Inf - Inf is NaN which is not zero, and so if we don't
16969 know that the operand is finite and the comparison
16970 would treat EQ different to UNORDERED, we can't do it. */
16971 if (HONOR_INFINITIES (compare_mode)
16972 && code != GT && code != UNGE
16973 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
16974 /* Constructs of the form (a OP b ? a : b) are safe. */
16975 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
16976 || (! rtx_equal_p (op0, true_cond)
16977 && ! rtx_equal_p (op1, true_cond))))
16980 /* At this point we know we can use fsel. */
16982 /* Reduce the comparison to a comparison against zero. */
16983 if (! is_against_zero)
16985 temp = gen_reg_rtx (compare_mode);
16986 emit_insn (gen_rtx_SET (VOIDmode, temp,
16987 gen_rtx_MINUS (compare_mode, op0, op1)));
16989 op1 = CONST0_RTX (compare_mode);
16992 /* If we don't care about NaNs we can reduce some of the comparisons
16993 down to faster ones. */
16994 if (! HONOR_NANS (compare_mode))
17000 true_cond = false_cond;
17013 /* Now, reduce everything down to a GE. */
17020 temp = gen_reg_rtx (compare_mode);
17021 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17026 temp = gen_reg_rtx (compare_mode);
17027 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
17032 temp = gen_reg_rtx (compare_mode);
17033 emit_insn (gen_rtx_SET (VOIDmode, temp,
17034 gen_rtx_NEG (compare_mode,
17035 gen_rtx_ABS (compare_mode, op0))));
17040 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
17041 temp = gen_reg_rtx (result_mode);
17042 emit_insn (gen_rtx_SET (VOIDmode, temp,
17043 gen_rtx_IF_THEN_ELSE (result_mode,
17044 gen_rtx_GE (VOIDmode,
17046 true_cond, false_cond)));
17047 false_cond = true_cond;
17050 temp = gen_reg_rtx (compare_mode);
17051 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17056 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
17057 temp = gen_reg_rtx (result_mode);
17058 emit_insn (gen_rtx_SET (VOIDmode, temp,
17059 gen_rtx_IF_THEN_ELSE (result_mode,
17060 gen_rtx_GE (VOIDmode,
17062 true_cond, false_cond)));
17063 true_cond = false_cond;
17066 temp = gen_reg_rtx (compare_mode);
17067 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17072 gcc_unreachable ();
17075 emit_insn (gen_rtx_SET (VOIDmode, dest,
17076 gen_rtx_IF_THEN_ELSE (result_mode,
17077 gen_rtx_GE (VOIDmode,
17079 true_cond, false_cond)));
17083 /* Same as above, but for ints (isel). */
17086 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
17088 rtx condition_rtx, cr;
17089 enum machine_mode mode = GET_MODE (dest);
17090 enum rtx_code cond_code;
17091 rtx (*isel_func) (rtx, rtx, rtx, rtx, rtx);
17094 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
17097 /* We still have to do the compare, because isel doesn't do a
17098 compare, it just looks at the CRx bits set by a previous compare
17100 condition_rtx = rs6000_generate_compare (op, mode);
17101 cond_code = GET_CODE (condition_rtx);
17102 cr = XEXP (condition_rtx, 0);
17103 signedp = GET_MODE (cr) == CCmode;
17105 isel_func = (mode == SImode
17106 ? (signedp ? gen_isel_signed_si : gen_isel_unsigned_si)
17107 : (signedp ? gen_isel_signed_di : gen_isel_unsigned_di));
17111 case LT: case GT: case LTU: case GTU: case EQ:
17112 /* isel handles these directly. */
17116 /* We need to swap the sense of the comparison. */
17119 true_cond = false_cond;
17121 PUT_CODE (condition_rtx, reverse_condition (cond_code));
17126 false_cond = force_reg (mode, false_cond);
17127 if (true_cond != const0_rtx)
17128 true_cond = force_reg (mode, true_cond);
17130 emit_insn (isel_func (dest, condition_rtx, true_cond, false_cond, cr));
17136 output_isel (rtx *operands)
17138 enum rtx_code code;
17140 code = GET_CODE (operands[1]);
17142 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
17144 gcc_assert (GET_CODE (operands[2]) == REG
17145 && GET_CODE (operands[3]) == REG);
17146 PUT_CODE (operands[1], reverse_condition (code));
17147 return "isel %0,%3,%2,%j1";
17150 return "isel %0,%2,%3,%j1";
17154 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
17156 enum machine_mode mode = GET_MODE (op0);
17160 /* VSX/altivec have direct min/max insns. */
17161 if ((code == SMAX || code == SMIN)
17162 && (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
17163 || (mode == SFmode && VECTOR_UNIT_VSX_P (DFmode))))
17165 emit_insn (gen_rtx_SET (VOIDmode,
17167 gen_rtx_fmt_ee (code, mode, op0, op1)));
17171 if (code == SMAX || code == SMIN)
17176 if (code == SMAX || code == UMAX)
17177 target = emit_conditional_move (dest, c, op0, op1, mode,
17178 op0, op1, mode, 0);
17180 target = emit_conditional_move (dest, c, op0, op1, mode,
17181 op1, op0, mode, 0);
17182 gcc_assert (target);
17183 if (target != dest)
17184 emit_move_insn (dest, target);
17187 /* Emit instructions to perform a load-reserved/store-conditional operation.
17188 The operation performed is an atomic
17189 (set M (CODE:MODE M OP))
17190 If not NULL, BEFORE is atomically set to M before the operation, and
17191 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
17192 If SYNC_P then a memory barrier is emitted before the operation.
17193 Either OP or M may be wrapped in a NOT operation. */
17196 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
17197 rtx m, rtx op, rtx before_param, rtx after_param,
17200 enum machine_mode used_mode;
17201 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
17204 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17205 rtx shift = NULL_RTX;
17208 emit_insn (gen_lwsync ());
17212 /* If this is smaller than SImode, we'll have to use SImode with
17214 if (mode == QImode || mode == HImode)
17218 if (MEM_ALIGN (used_m) >= 32)
17221 if (BYTES_BIG_ENDIAN)
17222 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
17224 shift = GEN_INT (ishift);
17225 used_m = change_address (used_m, SImode, 0);
17229 rtx addrSI, aligned_addr;
17230 int shift_mask = mode == QImode ? 0x18 : 0x10;
17232 addrSI = gen_lowpart_common (SImode,
17233 force_reg (Pmode, XEXP (used_m, 0)));
17234 addrSI = force_reg (SImode, addrSI);
17235 shift = gen_reg_rtx (SImode);
17237 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17238 GEN_INT (shift_mask)));
17239 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17241 aligned_addr = expand_binop (Pmode, and_optab,
17243 GEN_INT (-4), NULL_RTX,
17244 1, OPTAB_LIB_WIDEN);
17245 used_m = change_address (used_m, SImode, aligned_addr);
17246 set_mem_align (used_m, 32);
17248 /* It's safe to keep the old alias set of USED_M, because
17249 the operation is atomic and only affects the original
17253 if (GET_CODE (op) == NOT)
17255 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
17256 oldop = gen_rtx_NOT (SImode, oldop);
17259 oldop = lowpart_subreg (SImode, op, mode);
17265 newop = expand_binop (SImode, and_optab,
17266 oldop, GEN_INT (imask), NULL_RTX,
17267 1, OPTAB_LIB_WIDEN);
17268 emit_insn (gen_ashlsi3 (newop, newop, shift));
17271 case NOT: /* NAND */
17272 newop = expand_binop (SImode, ior_optab,
17273 oldop, GEN_INT (~imask), NULL_RTX,
17274 1, OPTAB_LIB_WIDEN);
17275 emit_insn (gen_rotlsi3 (newop, newop, shift));
17279 newop = expand_binop (SImode, ior_optab,
17280 oldop, GEN_INT (~imask), NULL_RTX,
17281 1, OPTAB_LIB_WIDEN);
17282 emit_insn (gen_rotlsi3 (newop, newop, shift));
17290 newop = expand_binop (SImode, and_optab,
17291 oldop, GEN_INT (imask), NULL_RTX,
17292 1, OPTAB_LIB_WIDEN);
17293 emit_insn (gen_ashlsi3 (newop, newop, shift));
17295 mask = gen_reg_rtx (SImode);
17296 emit_move_insn (mask, GEN_INT (imask));
17297 emit_insn (gen_ashlsi3 (mask, mask, shift));
17300 newop = gen_rtx_PLUS (SImode, m, newop);
17302 newop = gen_rtx_MINUS (SImode, m, newop);
17303 newop = gen_rtx_AND (SImode, newop, mask);
17304 newop = gen_rtx_IOR (SImode, newop,
17305 gen_rtx_AND (SImode,
17306 gen_rtx_NOT (SImode, mask),
17312 gcc_unreachable ();
17316 used_mode = SImode;
17317 before = gen_reg_rtx (used_mode);
17318 after = gen_reg_rtx (used_mode);
17323 before = before_param;
17324 after = after_param;
17326 if (before == NULL_RTX)
17327 before = gen_reg_rtx (used_mode);
17328 if (after == NULL_RTX)
17329 after = gen_reg_rtx (used_mode);
17332 if ((code == PLUS || code == MINUS)
17333 && used_mode != mode)
17334 the_op = op; /* Computed above. */
17335 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
17336 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
17337 else if (code == NOT)
17338 the_op = gen_rtx_fmt_ee (IOR, used_mode,
17339 gen_rtx_NOT (used_mode, m),
17340 gen_rtx_NOT (used_mode, op));
17342 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
17344 set_after = gen_rtx_SET (VOIDmode, after, the_op);
17345 set_before = gen_rtx_SET (VOIDmode, before, used_m);
17346 set_atomic = gen_rtx_SET (VOIDmode, used_m,
17347 gen_rtx_UNSPEC (used_mode,
17348 gen_rtvec (1, the_op),
17350 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
17352 if ((code == PLUS || code == MINUS) && used_mode != mode)
17353 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
17354 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
17356 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
17357 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
17359 /* Shift and mask the return values properly. */
17360 if (used_mode != mode && before_param)
17362 emit_insn (gen_lshrsi3 (before, before, shift));
17363 convert_move (before_param, before, 1);
17366 if (used_mode != mode && after_param)
17368 emit_insn (gen_lshrsi3 (after, after, shift));
17369 convert_move (after_param, after, 1);
17372 /* The previous sequence will end with a branch that's dependent on
17373 the conditional store, so placing an isync will ensure that no
17374 other instructions (especially, no load or store instructions)
17375 can start before the atomic operation completes. */
17377 emit_insn (gen_isync ());
17380 /* A subroutine of the atomic operation splitters. Jump to LABEL if
17381 COND is true. Mark the jump as unlikely to be taken. */
17384 emit_unlikely_jump (rtx cond, rtx label)
17386 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
17389 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
17390 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
17391 add_reg_note (x, REG_BR_PROB, very_unlikely);
17394 /* A subroutine of the atomic operation splitters. Emit a load-locked
17395 instruction in MODE. */
17398 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
17400 rtx (*fn) (rtx, rtx) = NULL;
17401 if (mode == SImode)
17402 fn = gen_load_locked_si;
17403 else if (mode == DImode)
17404 fn = gen_load_locked_di;
17405 emit_insn (fn (reg, mem));
17408 /* A subroutine of the atomic operation splitters. Emit a store-conditional
17409 instruction in MODE. */
17412 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
17414 rtx (*fn) (rtx, rtx, rtx) = NULL;
17415 if (mode == SImode)
17416 fn = gen_store_conditional_si;
17417 else if (mode == DImode)
17418 fn = gen_store_conditional_di;
17420 /* Emit sync before stwcx. to address PPC405 Erratum. */
17421 if (PPC405_ERRATUM77)
17422 emit_insn (gen_memory_barrier ());
17424 emit_insn (fn (res, mem, val));
17427 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
17428 to perform. MEM is the memory on which to operate. VAL is the second
17429 operand of the binary operator. BEFORE and AFTER are optional locations to
17430 return the value of MEM either before of after the operation. SCRATCH is
17431 a scratch register. */
17434 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
17435 rtx before, rtx after, rtx scratch)
17437 enum machine_mode mode = GET_MODE (mem);
17438 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17440 emit_insn (gen_lwsync ());
17442 label = gen_label_rtx ();
17443 emit_label (label);
17444 label = gen_rtx_LABEL_REF (VOIDmode, label);
17446 if (before == NULL_RTX)
17448 emit_load_locked (mode, before, mem);
17451 x = gen_rtx_IOR (mode,
17452 gen_rtx_NOT (mode, before),
17453 gen_rtx_NOT (mode, val));
17454 else if (code == AND)
17455 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
17457 x = gen_rtx_fmt_ee (code, mode, before, val);
17459 if (after != NULL_RTX)
17460 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
17461 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
17463 emit_store_conditional (mode, cond, mem, scratch);
17465 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17466 emit_unlikely_jump (x, label);
17468 emit_insn (gen_isync ());
17471 /* Expand an atomic compare and swap operation. MEM is the memory on which
17472 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
17473 value to be stored. SCRATCH is a scratch GPR. */
17476 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
17479 enum machine_mode mode = GET_MODE (mem);
17480 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17482 emit_insn (gen_lwsync ());
17484 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17485 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17486 emit_label (XEXP (label1, 0));
17488 emit_load_locked (mode, retval, mem);
17490 x = gen_rtx_COMPARE (CCmode, retval, oldval);
17491 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
17493 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17494 emit_unlikely_jump (x, label2);
17496 emit_move_insn (scratch, newval);
17497 emit_store_conditional (mode, cond, mem, scratch);
17499 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17500 emit_unlikely_jump (x, label1);
17502 emit_insn (gen_isync ());
17503 emit_label (XEXP (label2, 0));
17506 /* Expand an atomic test and set operation. MEM is the memory on which
17507 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
17510 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
17512 enum machine_mode mode = GET_MODE (mem);
17513 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17515 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17516 emit_label (XEXP (label, 0));
17518 emit_load_locked (mode, retval, mem);
17519 emit_move_insn (scratch, val);
17520 emit_store_conditional (mode, cond, mem, scratch);
17522 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17523 emit_unlikely_jump (x, label);
17525 emit_insn (gen_isync ());
17529 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
17531 enum machine_mode mode = GET_MODE (mem);
17532 rtx addrSI, align, wdst, shift, mask;
17533 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
17534 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17536 /* Shift amount for subword relative to aligned word. */
17537 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
17538 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
17539 shift = gen_reg_rtx (SImode);
17540 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17541 GEN_INT (shift_mask)));
17542 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17544 /* Shift and mask old value into position within word. */
17545 oldval = convert_modes (SImode, mode, oldval, 1);
17546 oldval = expand_binop (SImode, and_optab,
17547 oldval, GEN_INT (imask), NULL_RTX,
17548 1, OPTAB_LIB_WIDEN);
17549 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
17551 /* Shift and mask new value into position within word. */
17552 newval = convert_modes (SImode, mode, newval, 1);
17553 newval = expand_binop (SImode, and_optab,
17554 newval, GEN_INT (imask), NULL_RTX,
17555 1, OPTAB_LIB_WIDEN);
17556 emit_insn (gen_ashlsi3 (newval, newval, shift));
17558 /* Mask for insertion. */
17559 mask = gen_reg_rtx (SImode);
17560 emit_move_insn (mask, GEN_INT (imask));
17561 emit_insn (gen_ashlsi3 (mask, mask, shift));
17563 /* Address of aligned word containing subword. */
17564 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
17565 NULL_RTX, 1, OPTAB_LIB_WIDEN);
17566 mem = change_address (mem, SImode, align);
17567 set_mem_align (mem, 32);
17568 MEM_VOLATILE_P (mem) = 1;
17570 wdst = gen_reg_rtx (SImode);
17571 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
17572 oldval, newval, mem));
17574 /* Shift the result back. */
17575 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
17577 emit_move_insn (dst, gen_lowpart (mode, wdst));
17581 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
17582 rtx oldval, rtx newval, rtx mem,
17585 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17587 emit_insn (gen_lwsync ());
17588 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17589 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17590 emit_label (XEXP (label1, 0));
17592 emit_load_locked (SImode, scratch, mem);
17594 /* Mask subword within loaded value for comparison with oldval.
17595 Use UNSPEC_AND to avoid clobber.*/
17596 emit_insn (gen_rtx_SET (SImode, dest,
17597 gen_rtx_UNSPEC (SImode,
17598 gen_rtvec (2, scratch, mask),
17601 x = gen_rtx_COMPARE (CCmode, dest, oldval);
17602 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
17604 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17605 emit_unlikely_jump (x, label2);
17607 /* Clear subword within loaded value for insertion of new value. */
17608 emit_insn (gen_rtx_SET (SImode, scratch,
17609 gen_rtx_AND (SImode,
17610 gen_rtx_NOT (SImode, mask), scratch)));
17611 emit_insn (gen_iorsi3 (scratch, scratch, newval));
17612 emit_store_conditional (SImode, cond, mem, scratch);
17614 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17615 emit_unlikely_jump (x, label1);
17617 emit_insn (gen_isync ());
17618 emit_label (XEXP (label2, 0));
17622 /* Emit instructions to move SRC to DST. Called by splitters for
17623 multi-register moves. It will emit at most one instruction for
17624 each register that is accessed; that is, it won't emit li/lis pairs
17625 (or equivalent for 64-bit code). One of SRC or DST must be a hard
17629 rs6000_split_multireg_move (rtx dst, rtx src)
17631 /* The register number of the first register being moved. */
17633 /* The mode that is to be moved. */
17634 enum machine_mode mode;
17635 /* The mode that the move is being done in, and its size. */
17636 enum machine_mode reg_mode;
17638 /* The number of registers that will be moved. */
17641 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
17642 mode = GET_MODE (dst);
17643 nregs = hard_regno_nregs[reg][mode];
17644 if (FP_REGNO_P (reg))
17645 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
17646 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
17647 else if (ALTIVEC_REGNO_P (reg))
17648 reg_mode = V16QImode;
17649 else if (TARGET_E500_DOUBLE && mode == TFmode)
17652 reg_mode = word_mode;
17653 reg_mode_size = GET_MODE_SIZE (reg_mode);
17655 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
17657 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
17659 /* Move register range backwards, if we might have destructive
17662 for (i = nregs - 1; i >= 0; i--)
17663 emit_insn (gen_rtx_SET (VOIDmode,
17664 simplify_gen_subreg (reg_mode, dst, mode,
17665 i * reg_mode_size),
17666 simplify_gen_subreg (reg_mode, src, mode,
17667 i * reg_mode_size)));
17673 bool used_update = false;
17674 rtx restore_basereg = NULL_RTX;
17676 if (MEM_P (src) && INT_REGNO_P (reg))
17680 if (GET_CODE (XEXP (src, 0)) == PRE_INC
17681 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
17684 breg = XEXP (XEXP (src, 0), 0);
17685 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
17686 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
17687 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
17688 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17689 src = replace_equiv_address (src, breg);
17691 else if (! rs6000_offsettable_memref_p (src))
17693 if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)
17695 rtx basereg = XEXP (XEXP (src, 0), 0);
17698 rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0);
17699 emit_insn (gen_rtx_SET (VOIDmode, ndst,
17700 gen_rtx_MEM (reg_mode, XEXP (src, 0))));
17701 used_update = true;
17704 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17705 XEXP (XEXP (src, 0), 1)));
17706 src = replace_equiv_address (src, basereg);
17710 rtx basereg = gen_rtx_REG (Pmode, reg);
17711 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
17712 src = replace_equiv_address (src, basereg);
17716 breg = XEXP (src, 0);
17717 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
17718 breg = XEXP (breg, 0);
17720 /* If the base register we are using to address memory is
17721 also a destination reg, then change that register last. */
17723 && REGNO (breg) >= REGNO (dst)
17724 && REGNO (breg) < REGNO (dst) + nregs)
17725 j = REGNO (breg) - REGNO (dst);
17727 else if (MEM_P (dst) && INT_REGNO_P (reg))
17731 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
17732 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
17735 breg = XEXP (XEXP (dst, 0), 0);
17736 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
17737 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
17738 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
17740 /* We have to update the breg before doing the store.
17741 Use store with update, if available. */
17745 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17746 emit_insn (TARGET_32BIT
17747 ? (TARGET_POWERPC64
17748 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
17749 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
17750 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
17751 used_update = true;
17754 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17755 dst = replace_equiv_address (dst, breg);
17757 else if (!rs6000_offsettable_memref_p (dst)
17758 && GET_CODE (XEXP (dst, 0)) != LO_SUM)
17760 if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY)
17762 rtx basereg = XEXP (XEXP (dst, 0), 0);
17765 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17766 emit_insn (gen_rtx_SET (VOIDmode,
17767 gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc));
17768 used_update = true;
17771 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17772 XEXP (XEXP (dst, 0), 1)));
17773 dst = replace_equiv_address (dst, basereg);
17777 rtx basereg = XEXP (XEXP (dst, 0), 0);
17778 rtx offsetreg = XEXP (XEXP (dst, 0), 1);
17779 gcc_assert (GET_CODE (XEXP (dst, 0)) == PLUS
17781 && REG_P (offsetreg)
17782 && REGNO (basereg) != REGNO (offsetreg));
17783 if (REGNO (basereg) == 0)
17785 rtx tmp = offsetreg;
17786 offsetreg = basereg;
17789 emit_insn (gen_add3_insn (basereg, basereg, offsetreg));
17790 restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg);
17791 dst = replace_equiv_address (dst, basereg);
17794 else if (GET_CODE (XEXP (dst, 0)) != LO_SUM)
17795 gcc_assert (rs6000_offsettable_memref_p (dst));
17798 for (i = 0; i < nregs; i++)
17800 /* Calculate index to next subword. */
17805 /* If compiler already emitted move of first word by
17806 store with update, no need to do anything. */
17807 if (j == 0 && used_update)
17810 emit_insn (gen_rtx_SET (VOIDmode,
17811 simplify_gen_subreg (reg_mode, dst, mode,
17812 j * reg_mode_size),
17813 simplify_gen_subreg (reg_mode, src, mode,
17814 j * reg_mode_size)));
17816 if (restore_basereg != NULL_RTX)
17817 emit_insn (restore_basereg);
17822 /* This page contains routines that are used to determine what the
17823 function prologue and epilogue code will do and write them out. */
17825 /* Return the first fixed-point register that is required to be
17826 saved. 32 if none. */
17829 first_reg_to_save (void)
17833 /* Find lowest numbered live register. */
17834 for (first_reg = 13; first_reg <= 31; first_reg++)
17835 if (df_regs_ever_live_p (first_reg)
17836 && (! call_used_regs[first_reg]
17837 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
17838 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
17839 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
17840 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
17845 && crtl->uses_pic_offset_table
17846 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
17847 return RS6000_PIC_OFFSET_TABLE_REGNUM;
17853 /* Similar, for FP regs. */
17856 first_fp_reg_to_save (void)
17860 /* Find lowest numbered live register. */
17861 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
17862 if (df_regs_ever_live_p (first_reg))
17868 /* Similar, for AltiVec regs. */
17871 first_altivec_reg_to_save (void)
17875 /* Stack frame remains as is unless we are in AltiVec ABI. */
17876 if (! TARGET_ALTIVEC_ABI)
17877 return LAST_ALTIVEC_REGNO + 1;
17879 /* On Darwin, the unwind routines are compiled without
17880 TARGET_ALTIVEC, and use save_world to save/restore the
17881 altivec registers when necessary. */
17882 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17883 && ! TARGET_ALTIVEC)
17884 return FIRST_ALTIVEC_REGNO + 20;
17886 /* Find lowest numbered live register. */
17887 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
17888 if (df_regs_ever_live_p (i))
17894 /* Return a 32-bit mask of the AltiVec registers we need to set in
17895 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
17896 the 32-bit word is 0. */
17898 static unsigned int
17899 compute_vrsave_mask (void)
17901 unsigned int i, mask = 0;
17903 /* On Darwin, the unwind routines are compiled without
17904 TARGET_ALTIVEC, and use save_world to save/restore the
17905 call-saved altivec registers when necessary. */
17906 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17907 && ! TARGET_ALTIVEC)
17910 /* First, find out if we use _any_ altivec registers. */
17911 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
17912 if (df_regs_ever_live_p (i))
17913 mask |= ALTIVEC_REG_BIT (i);
17918 /* Next, remove the argument registers from the set. These must
17919 be in the VRSAVE mask set by the caller, so we don't need to add
17920 them in again. More importantly, the mask we compute here is
17921 used to generate CLOBBERs in the set_vrsave insn, and we do not
17922 wish the argument registers to die. */
17923 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
17924 mask &= ~ALTIVEC_REG_BIT (i);
17926 /* Similarly, remove the return value from the set. */
17929 diddle_return_value (is_altivec_return_reg, &yes);
17931 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
17937 /* For a very restricted set of circumstances, we can cut down the
17938 size of prologues/epilogues by calling our own save/restore-the-world
17942 compute_save_world_info (rs6000_stack_t *info_ptr)
17944 info_ptr->world_save_p = 1;
17945 info_ptr->world_save_p
17946 = (WORLD_SAVE_P (info_ptr)
17947 && DEFAULT_ABI == ABI_DARWIN
17948 && !cfun->has_nonlocal_label
17949 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
17950 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
17951 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
17952 && info_ptr->cr_save_p);
17954 /* This will not work in conjunction with sibcalls. Make sure there
17955 are none. (This check is expensive, but seldom executed.) */
17956 if (WORLD_SAVE_P (info_ptr))
17959 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
17960 if ( GET_CODE (insn) == CALL_INSN
17961 && SIBLING_CALL_P (insn))
17963 info_ptr->world_save_p = 0;
17968 if (WORLD_SAVE_P (info_ptr))
17970 /* Even if we're not touching VRsave, make sure there's room on the
17971 stack for it, if it looks like we're calling SAVE_WORLD, which
17972 will attempt to save it. */
17973 info_ptr->vrsave_size = 4;
17975 /* If we are going to save the world, we need to save the link register too. */
17976 info_ptr->lr_save_p = 1;
17978 /* "Save" the VRsave register too if we're saving the world. */
17979 if (info_ptr->vrsave_mask == 0)
17980 info_ptr->vrsave_mask = compute_vrsave_mask ();
17982 /* Because the Darwin register save/restore routines only handle
17983 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
17985 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
17986 && (info_ptr->first_altivec_reg_save
17987 >= FIRST_SAVED_ALTIVEC_REGNO));
17994 is_altivec_return_reg (rtx reg, void *xyes)
17996 bool *yes = (bool *) xyes;
17997 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
18002 /* Determine the strategy for savings/restoring registers. */
18005 SAVRES_MULTIPLE = 0x1,
18006 SAVE_INLINE_FPRS = 0x2,
18007 SAVE_INLINE_GPRS = 0x4,
18008 REST_INLINE_FPRS = 0x8,
18009 REST_INLINE_GPRS = 0x10,
18010 SAVE_NOINLINE_GPRS_SAVES_LR = 0x20,
18011 SAVE_NOINLINE_FPRS_SAVES_LR = 0x40,
18012 REST_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x80
18016 rs6000_savres_strategy (rs6000_stack_t *info,
18017 bool using_static_chain_p)
18021 if (TARGET_MULTIPLE
18022 && !TARGET_POWERPC64
18023 && !(TARGET_SPE_ABI && info->spe_64bit_regs_used)
18024 && info->first_gp_reg_save < 31
18025 && no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true))
18026 strategy |= SAVRES_MULTIPLE;
18028 if (crtl->calls_eh_return
18029 || cfun->machine->ra_need_lr
18030 || info->total_size > 32767)
18031 strategy |= (SAVE_INLINE_FPRS | REST_INLINE_FPRS
18032 | SAVE_INLINE_GPRS | REST_INLINE_GPRS);
18034 if (info->first_fp_reg_save == 64
18035 || FP_SAVE_INLINE (info->first_fp_reg_save)
18036 /* The out-of-line FP routines use double-precision stores;
18037 we can't use those routines if we don't have such stores. */
18038 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
18039 || !no_global_regs_above (info->first_fp_reg_save, /*gpr=*/false))
18040 strategy |= SAVE_INLINE_FPRS | REST_INLINE_FPRS;
18042 if (info->first_gp_reg_save == 32
18043 || GP_SAVE_INLINE (info->first_gp_reg_save)
18044 || !((strategy & SAVRES_MULTIPLE)
18045 || no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true)))
18046 strategy |= SAVE_INLINE_GPRS | REST_INLINE_GPRS;
18048 /* Don't bother to try to save things out-of-line if r11 is occupied
18049 by the static chain. It would require too much fiddling and the
18050 static chain is rarely used anyway. */
18051 if (using_static_chain_p)
18052 strategy |= SAVE_INLINE_FPRS | SAVE_INLINE_GPRS;
18054 /* If we are going to use store multiple, then don't even bother
18055 with the out-of-line routines, since the store-multiple
18056 instruction will always be smaller. */
18057 if ((strategy & SAVRES_MULTIPLE))
18058 strategy |= SAVE_INLINE_GPRS;
18060 /* The situation is more complicated with load multiple. We'd
18061 prefer to use the out-of-line routines for restores, since the
18062 "exit" out-of-line routines can handle the restore of LR and the
18063 frame teardown. However if doesn't make sense to use the
18064 out-of-line routine if that is the only reason we'd need to save
18065 LR, and we can't use the "exit" out-of-line gpr restore if we
18066 have saved some fprs; In those cases it is advantageous to use
18067 load multiple when available. */
18068 if ((strategy & SAVRES_MULTIPLE)
18069 && (!info->lr_save_p
18070 || info->first_fp_reg_save != 64))
18071 strategy |= REST_INLINE_GPRS;
18073 /* We can only use load multiple or the out-of-line routines to
18074 restore if we've used store multiple or out-of-line routines
18075 in the prologue, i.e. if we've saved all the registers from
18076 first_gp_reg_save. Otherwise, we risk loading garbage. */
18077 if ((strategy & (SAVE_INLINE_GPRS | SAVRES_MULTIPLE)) == SAVE_INLINE_GPRS)
18078 strategy |= REST_INLINE_GPRS;
18080 /* Saving CR interferes with the exit routines used on the SPE, so
18083 && info->spe_64bit_regs_used
18084 && info->cr_save_p)
18085 strategy |= REST_INLINE_GPRS;
18087 #ifdef POWERPC_LINUX
18090 if (!(strategy & SAVE_INLINE_FPRS))
18091 strategy |= SAVE_NOINLINE_FPRS_SAVES_LR;
18092 else if (!(strategy & SAVE_INLINE_GPRS)
18093 && info->first_fp_reg_save == 64)
18094 strategy |= SAVE_NOINLINE_GPRS_SAVES_LR;
18097 if (TARGET_AIX && !(strategy & REST_INLINE_FPRS))
18098 strategy |= REST_NOINLINE_FPRS_DOESNT_RESTORE_LR;
18103 /* Calculate the stack information for the current function. This is
18104 complicated by having two separate calling sequences, the AIX calling
18105 sequence and the V.4 calling sequence.
18107 AIX (and Darwin/Mac OS X) stack frames look like:
18109 SP----> +---------------------------------------+
18110 | back chain to caller | 0 0
18111 +---------------------------------------+
18112 | saved CR | 4 8 (8-11)
18113 +---------------------------------------+
18115 +---------------------------------------+
18116 | reserved for compilers | 12 24
18117 +---------------------------------------+
18118 | reserved for binders | 16 32
18119 +---------------------------------------+
18120 | saved TOC pointer | 20 40
18121 +---------------------------------------+
18122 | Parameter save area (P) | 24 48
18123 +---------------------------------------+
18124 | Alloca space (A) | 24+P etc.
18125 +---------------------------------------+
18126 | Local variable space (L) | 24+P+A
18127 +---------------------------------------+
18128 | Float/int conversion temporary (X) | 24+P+A+L
18129 +---------------------------------------+
18130 | Save area for AltiVec registers (W) | 24+P+A+L+X
18131 +---------------------------------------+
18132 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
18133 +---------------------------------------+
18134 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
18135 +---------------------------------------+
18136 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
18137 +---------------------------------------+
18138 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
18139 +---------------------------------------+
18140 old SP->| back chain to caller's caller |
18141 +---------------------------------------+
18143 The required alignment for AIX configurations is two words (i.e., 8
18147 V.4 stack frames look like:
18149 SP----> +---------------------------------------+
18150 | back chain to caller | 0
18151 +---------------------------------------+
18152 | caller's saved LR | 4
18153 +---------------------------------------+
18154 | Parameter save area (P) | 8
18155 +---------------------------------------+
18156 | Alloca space (A) | 8+P
18157 +---------------------------------------+
18158 | Varargs save area (V) | 8+P+A
18159 +---------------------------------------+
18160 | Local variable space (L) | 8+P+A+V
18161 +---------------------------------------+
18162 | Float/int conversion temporary (X) | 8+P+A+V+L
18163 +---------------------------------------+
18164 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
18165 +---------------------------------------+
18166 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
18167 +---------------------------------------+
18168 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
18169 +---------------------------------------+
18170 | SPE: area for 64-bit GP registers |
18171 +---------------------------------------+
18172 | SPE alignment padding |
18173 +---------------------------------------+
18174 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
18175 +---------------------------------------+
18176 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
18177 +---------------------------------------+
18178 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
18179 +---------------------------------------+
18180 old SP->| back chain to caller's caller |
18181 +---------------------------------------+
18183 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
18184 given. (But note below and in sysv4.h that we require only 8 and
18185 may round up the size of our stack frame anyways. The historical
18186 reason is early versions of powerpc-linux which didn't properly
18187 align the stack at program startup. A happy side-effect is that
18188 -mno-eabi libraries can be used with -meabi programs.)
18190 The EABI configuration defaults to the V.4 layout. However,
18191 the stack alignment requirements may differ. If -mno-eabi is not
18192 given, the required stack alignment is 8 bytes; if -mno-eabi is
18193 given, the required alignment is 16 bytes. (But see V.4 comment
18196 #ifndef ABI_STACK_BOUNDARY
18197 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
18200 static rs6000_stack_t *
18201 rs6000_stack_info (void)
18203 rs6000_stack_t *info_ptr = &stack_info;
18204 int reg_size = TARGET_32BIT ? 4 : 8;
18208 HOST_WIDE_INT non_fixed_size;
18209 bool using_static_chain_p;
18211 if (reload_completed && info_ptr->reload_completed)
18214 memset (info_ptr, 0, sizeof (*info_ptr));
18215 info_ptr->reload_completed = reload_completed;
18219 /* Cache value so we don't rescan instruction chain over and over. */
18220 if (cfun->machine->insn_chain_scanned_p == 0)
18221 cfun->machine->insn_chain_scanned_p
18222 = spe_func_has_64bit_regs_p () + 1;
18223 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
18226 /* Select which calling sequence. */
18227 info_ptr->abi = DEFAULT_ABI;
18229 /* Calculate which registers need to be saved & save area size. */
18230 info_ptr->first_gp_reg_save = first_reg_to_save ();
18231 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
18232 even if it currently looks like we won't. Reload may need it to
18233 get at a constant; if so, it will have already created a constant
18234 pool entry for it. */
18235 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
18236 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
18237 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
18238 && crtl->uses_const_pool
18239 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
18240 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
18242 first_gp = info_ptr->first_gp_reg_save;
18244 info_ptr->gp_size = reg_size * (32 - first_gp);
18246 /* For the SPE, we have an additional upper 32-bits on each GPR.
18247 Ideally we should save the entire 64-bits only when the upper
18248 half is used in SIMD instructions. Since we only record
18249 registers live (not the size they are used in), this proves
18250 difficult because we'd have to traverse the instruction chain at
18251 the right time, taking reload into account. This is a real pain,
18252 so we opt to save the GPRs in 64-bits always if but one register
18253 gets used in 64-bits. Otherwise, all the registers in the frame
18254 get saved in 32-bits.
18256 So... since when we save all GPRs (except the SP) in 64-bits, the
18257 traditional GP save area will be empty. */
18258 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18259 info_ptr->gp_size = 0;
18261 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
18262 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
18264 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
18265 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
18266 - info_ptr->first_altivec_reg_save);
18268 /* Does this function call anything? */
18269 info_ptr->calls_p = (! current_function_is_leaf
18270 || cfun->machine->ra_needs_full_frame);
18272 /* Determine if we need to save the condition code registers. */
18273 if (df_regs_ever_live_p (CR2_REGNO)
18274 || df_regs_ever_live_p (CR3_REGNO)
18275 || df_regs_ever_live_p (CR4_REGNO))
18277 info_ptr->cr_save_p = 1;
18278 if (DEFAULT_ABI == ABI_V4)
18279 info_ptr->cr_size = reg_size;
18282 /* If the current function calls __builtin_eh_return, then we need
18283 to allocate stack space for registers that will hold data for
18284 the exception handler. */
18285 if (crtl->calls_eh_return)
18288 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
18291 /* SPE saves EH registers in 64-bits. */
18292 ehrd_size = i * (TARGET_SPE_ABI
18293 && info_ptr->spe_64bit_regs_used != 0
18294 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
18299 /* Determine various sizes. */
18300 info_ptr->reg_size = reg_size;
18301 info_ptr->fixed_size = RS6000_SAVE_AREA;
18302 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
18303 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
18304 TARGET_ALTIVEC ? 16 : 8);
18305 if (FRAME_GROWS_DOWNWARD)
18306 info_ptr->vars_size
18307 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
18308 + info_ptr->parm_size,
18309 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
18310 - (info_ptr->fixed_size + info_ptr->vars_size
18311 + info_ptr->parm_size);
18313 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18314 info_ptr->spe_gp_size = 8 * (32 - first_gp);
18316 info_ptr->spe_gp_size = 0;
18318 if (TARGET_ALTIVEC_ABI)
18319 info_ptr->vrsave_mask = compute_vrsave_mask ();
18321 info_ptr->vrsave_mask = 0;
18323 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
18324 info_ptr->vrsave_size = 4;
18326 info_ptr->vrsave_size = 0;
18328 compute_save_world_info (info_ptr);
18330 /* Calculate the offsets. */
18331 switch (DEFAULT_ABI)
18335 gcc_unreachable ();
18339 info_ptr->fp_save_offset = - info_ptr->fp_size;
18340 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18342 if (TARGET_ALTIVEC_ABI)
18344 info_ptr->vrsave_save_offset
18345 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
18347 /* Align stack so vector save area is on a quadword boundary.
18348 The padding goes above the vectors. */
18349 if (info_ptr->altivec_size != 0)
18350 info_ptr->altivec_padding_size
18351 = info_ptr->vrsave_save_offset & 0xF;
18353 info_ptr->altivec_padding_size = 0;
18355 info_ptr->altivec_save_offset
18356 = info_ptr->vrsave_save_offset
18357 - info_ptr->altivec_padding_size
18358 - info_ptr->altivec_size;
18359 gcc_assert (info_ptr->altivec_size == 0
18360 || info_ptr->altivec_save_offset % 16 == 0);
18362 /* Adjust for AltiVec case. */
18363 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
18366 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
18367 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
18368 info_ptr->lr_save_offset = 2*reg_size;
18372 info_ptr->fp_save_offset = - info_ptr->fp_size;
18373 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18374 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
18376 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18378 /* Align stack so SPE GPR save area is aligned on a
18379 double-word boundary. */
18380 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
18381 info_ptr->spe_padding_size
18382 = 8 - (-info_ptr->cr_save_offset % 8);
18384 info_ptr->spe_padding_size = 0;
18386 info_ptr->spe_gp_save_offset
18387 = info_ptr->cr_save_offset
18388 - info_ptr->spe_padding_size
18389 - info_ptr->spe_gp_size;
18391 /* Adjust for SPE case. */
18392 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
18394 else if (TARGET_ALTIVEC_ABI)
18396 info_ptr->vrsave_save_offset
18397 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
18399 /* Align stack so vector save area is on a quadword boundary. */
18400 if (info_ptr->altivec_size != 0)
18401 info_ptr->altivec_padding_size
18402 = 16 - (-info_ptr->vrsave_save_offset % 16);
18404 info_ptr->altivec_padding_size = 0;
18406 info_ptr->altivec_save_offset
18407 = info_ptr->vrsave_save_offset
18408 - info_ptr->altivec_padding_size
18409 - info_ptr->altivec_size;
18411 /* Adjust for AltiVec case. */
18412 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
18415 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
18416 info_ptr->ehrd_offset -= ehrd_size;
18417 info_ptr->lr_save_offset = reg_size;
18421 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
18422 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
18423 + info_ptr->gp_size
18424 + info_ptr->altivec_size
18425 + info_ptr->altivec_padding_size
18426 + info_ptr->spe_gp_size
18427 + info_ptr->spe_padding_size
18429 + info_ptr->cr_size
18430 + info_ptr->vrsave_size,
18433 non_fixed_size = (info_ptr->vars_size
18434 + info_ptr->parm_size
18435 + info_ptr->save_size);
18437 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
18438 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
18440 /* Determine if we need to save the link register. */
18441 if (info_ptr->calls_p
18442 || (DEFAULT_ABI == ABI_AIX
18444 && !TARGET_PROFILE_KERNEL)
18445 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
18446 #ifdef TARGET_RELOCATABLE
18447 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
18449 || rs6000_ra_ever_killed ())
18450 info_ptr->lr_save_p = 1;
18452 using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
18453 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
18454 && call_used_regs[STATIC_CHAIN_REGNUM]);
18455 info_ptr->savres_strategy = rs6000_savres_strategy (info_ptr,
18456 using_static_chain_p);
18458 if (!(info_ptr->savres_strategy & SAVE_INLINE_GPRS)
18459 || !(info_ptr->savres_strategy & SAVE_INLINE_FPRS)
18460 || !(info_ptr->savres_strategy & REST_INLINE_GPRS)
18461 || !(info_ptr->savres_strategy & REST_INLINE_FPRS))
18462 info_ptr->lr_save_p = 1;
18464 if (info_ptr->lr_save_p)
18465 df_set_regs_ever_live (LR_REGNO, true);
18467 /* Determine if we need to allocate any stack frame:
18469 For AIX we need to push the stack if a frame pointer is needed
18470 (because the stack might be dynamically adjusted), if we are
18471 debugging, if we make calls, or if the sum of fp_save, gp_save,
18472 and local variables are more than the space needed to save all
18473 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
18474 + 18*8 = 288 (GPR13 reserved).
18476 For V.4 we don't have the stack cushion that AIX uses, but assume
18477 that the debugger can handle stackless frames. */
18479 if (info_ptr->calls_p)
18480 info_ptr->push_p = 1;
18482 else if (DEFAULT_ABI == ABI_V4)
18483 info_ptr->push_p = non_fixed_size != 0;
18485 else if (frame_pointer_needed)
18486 info_ptr->push_p = 1;
18488 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
18489 info_ptr->push_p = 1;
18492 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
18494 /* Zero offsets if we're not saving those registers. */
18495 if (info_ptr->fp_size == 0)
18496 info_ptr->fp_save_offset = 0;
18498 if (info_ptr->gp_size == 0)
18499 info_ptr->gp_save_offset = 0;
18501 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
18502 info_ptr->altivec_save_offset = 0;
18504 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
18505 info_ptr->vrsave_save_offset = 0;
18507 if (! TARGET_SPE_ABI
18508 || info_ptr->spe_64bit_regs_used == 0
18509 || info_ptr->spe_gp_size == 0)
18510 info_ptr->spe_gp_save_offset = 0;
18512 if (! info_ptr->lr_save_p)
18513 info_ptr->lr_save_offset = 0;
18515 if (! info_ptr->cr_save_p)
18516 info_ptr->cr_save_offset = 0;
18521 /* Return true if the current function uses any GPRs in 64-bit SIMD
18525 spe_func_has_64bit_regs_p (void)
18529 /* Functions that save and restore all the call-saved registers will
18530 need to save/restore the registers in 64-bits. */
18531 if (crtl->calls_eh_return
18532 || cfun->calls_setjmp
18533 || crtl->has_nonlocal_goto)
18536 insns = get_insns ();
18538 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
18544 /* FIXME: This should be implemented with attributes...
18546 (set_attr "spe64" "true")....then,
18547 if (get_spe64(insn)) return true;
18549 It's the only reliable way to do the stuff below. */
18551 i = PATTERN (insn);
18552 if (GET_CODE (i) == SET)
18554 enum machine_mode mode = GET_MODE (SET_SRC (i));
18556 if (SPE_VECTOR_MODE (mode))
18558 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
18568 debug_stack_info (rs6000_stack_t *info)
18570 const char *abi_string;
18573 info = rs6000_stack_info ();
18575 fprintf (stderr, "\nStack information for function %s:\n",
18576 ((current_function_decl && DECL_NAME (current_function_decl))
18577 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
18582 default: abi_string = "Unknown"; break;
18583 case ABI_NONE: abi_string = "NONE"; break;
18584 case ABI_AIX: abi_string = "AIX"; break;
18585 case ABI_DARWIN: abi_string = "Darwin"; break;
18586 case ABI_V4: abi_string = "V.4"; break;
18589 fprintf (stderr, "\tABI = %5s\n", abi_string);
18591 if (TARGET_ALTIVEC_ABI)
18592 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
18594 if (TARGET_SPE_ABI)
18595 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
18597 if (info->first_gp_reg_save != 32)
18598 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
18600 if (info->first_fp_reg_save != 64)
18601 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
18603 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
18604 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
18605 info->first_altivec_reg_save);
18607 if (info->lr_save_p)
18608 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
18610 if (info->cr_save_p)
18611 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
18613 if (info->vrsave_mask)
18614 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
18617 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
18620 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
18622 if (info->gp_save_offset)
18623 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
18625 if (info->fp_save_offset)
18626 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
18628 if (info->altivec_save_offset)
18629 fprintf (stderr, "\taltivec_save_offset = %5d\n",
18630 info->altivec_save_offset);
18632 if (info->spe_gp_save_offset)
18633 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
18634 info->spe_gp_save_offset);
18636 if (info->vrsave_save_offset)
18637 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
18638 info->vrsave_save_offset);
18640 if (info->lr_save_offset)
18641 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
18643 if (info->cr_save_offset)
18644 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
18646 if (info->varargs_save_offset)
18647 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
18649 if (info->total_size)
18650 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18653 if (info->vars_size)
18654 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18657 if (info->parm_size)
18658 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
18660 if (info->fixed_size)
18661 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
18664 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
18666 if (info->spe_gp_size)
18667 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
18670 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
18672 if (info->altivec_size)
18673 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
18675 if (info->vrsave_size)
18676 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
18678 if (info->altivec_padding_size)
18679 fprintf (stderr, "\taltivec_padding_size= %5d\n",
18680 info->altivec_padding_size);
18682 if (info->spe_padding_size)
18683 fprintf (stderr, "\tspe_padding_size = %5d\n",
18684 info->spe_padding_size);
18687 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
18689 if (info->save_size)
18690 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
18692 if (info->reg_size != 4)
18693 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
18695 fprintf (stderr, "\n");
18699 rs6000_return_addr (int count, rtx frame)
18701 /* Currently we don't optimize very well between prolog and body
18702 code and for PIC code the code can be actually quite bad, so
18703 don't try to be too clever here. */
18704 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
18706 cfun->machine->ra_needs_full_frame = 1;
18713 plus_constant (copy_to_reg
18714 (gen_rtx_MEM (Pmode,
18715 memory_address (Pmode, frame))),
18716 RETURN_ADDRESS_OFFSET)));
18719 cfun->machine->ra_need_lr = 1;
18720 return get_hard_reg_initial_val (Pmode, LR_REGNO);
18723 /* Say whether a function is a candidate for sibcall handling or not. */
18726 rs6000_function_ok_for_sibcall (tree decl, tree exp)
18731 fntype = TREE_TYPE (decl);
18733 fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (exp)));
18735 /* We can't do it if the called function has more vector parameters
18736 than the current function; there's nowhere to put the VRsave code. */
18737 if (TARGET_ALTIVEC_ABI
18738 && TARGET_ALTIVEC_VRSAVE
18739 && !(decl && decl == current_function_decl))
18741 function_args_iterator args_iter;
18745 /* Functions with vector parameters are required to have a
18746 prototype, so the argument type info must be available
18748 FOREACH_FUNCTION_ARGS(fntype, type, args_iter)
18749 if (TREE_CODE (type) == VECTOR_TYPE
18750 && ALTIVEC_OR_VSX_VECTOR_MODE (TYPE_MODE (type)))
18753 FOREACH_FUNCTION_ARGS(TREE_TYPE (current_function_decl), type, args_iter)
18754 if (TREE_CODE (type) == VECTOR_TYPE
18755 && ALTIVEC_OR_VSX_VECTOR_MODE (TYPE_MODE (type)))
18762 /* Under the AIX ABI we can't allow calls to non-local functions,
18763 because the callee may have a different TOC pointer to the
18764 caller and there's no way to ensure we restore the TOC when we
18765 return. With the secure-plt SYSV ABI we can't make non-local
18766 calls when -fpic/PIC because the plt call stubs use r30. */
18767 if (DEFAULT_ABI == ABI_DARWIN
18768 || (DEFAULT_ABI == ABI_AIX
18770 && !DECL_EXTERNAL (decl)
18771 && (*targetm.binds_local_p) (decl))
18772 || (DEFAULT_ABI == ABI_V4
18773 && (!TARGET_SECURE_PLT
18776 && (*targetm.binds_local_p) (decl)))))
18778 tree attr_list = TYPE_ATTRIBUTES (fntype);
18780 if (!lookup_attribute ("longcall", attr_list)
18781 || lookup_attribute ("shortcall", attr_list))
18788 /* NULL if INSN insn is valid within a low-overhead loop.
18789 Otherwise return why doloop cannot be applied.
18790 PowerPC uses the COUNT register for branch on table instructions. */
18792 static const char *
18793 rs6000_invalid_within_doloop (const_rtx insn)
18796 return "Function call in the loop.";
18799 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
18800 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
18801 return "Computed branch in the loop.";
18807 rs6000_ra_ever_killed (void)
18813 if (cfun->is_thunk)
18816 if (cfun->machine->lr_save_state)
18817 return cfun->machine->lr_save_state - 1;
18819 /* regs_ever_live has LR marked as used if any sibcalls are present,
18820 but this should not force saving and restoring in the
18821 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
18822 clobbers LR, so that is inappropriate. */
18824 /* Also, the prologue can generate a store into LR that
18825 doesn't really count, like this:
18828 bcl to set PIC register
18832 When we're called from the epilogue, we need to avoid counting
18833 this as a store. */
18835 push_topmost_sequence ();
18836 top = get_insns ();
18837 pop_topmost_sequence ();
18838 reg = gen_rtx_REG (Pmode, LR_REGNO);
18840 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
18846 if (!SIBLING_CALL_P (insn))
18849 else if (find_regno_note (insn, REG_INC, LR_REGNO))
18851 else if (set_of (reg, insn) != NULL_RTX
18852 && !prologue_epilogue_contains (insn))
18859 /* Emit instructions needed to load the TOC register.
18860 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
18861 a constant pool; or for SVR4 -fpic. */
18864 rs6000_emit_load_toc_table (int fromprolog)
18867 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
18869 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
18872 rtx lab, tmp1, tmp2, got;
18874 lab = gen_label_rtx ();
18875 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (lab));
18876 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18878 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18880 got = rs6000_got_sym ();
18881 tmp1 = tmp2 = dest;
18884 tmp1 = gen_reg_rtx (Pmode);
18885 tmp2 = gen_reg_rtx (Pmode);
18887 emit_insn (gen_load_toc_v4_PIC_1 (lab));
18888 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
18889 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
18890 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
18892 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
18894 emit_insn (gen_load_toc_v4_pic_si ());
18895 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18897 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
18900 rtx temp0 = (fromprolog
18901 ? gen_rtx_REG (Pmode, 0)
18902 : gen_reg_rtx (Pmode));
18908 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
18909 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18911 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
18912 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18914 emit_insn (gen_load_toc_v4_PIC_1 (symF));
18915 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18916 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
18922 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18923 lab = gen_label_rtx ();
18924 emit_insn (gen_load_toc_v4_PIC_1b (tocsym, lab));
18925 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18926 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
18928 emit_insn (gen_addsi3 (dest, temp0, dest));
18930 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
18932 /* This is for AIX code running in non-PIC ELF32. */
18935 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
18936 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18938 emit_insn (gen_elf_high (dest, realsym));
18939 emit_insn (gen_elf_low (dest, dest, realsym));
18943 gcc_assert (DEFAULT_ABI == ABI_AIX);
18946 emit_insn (gen_load_toc_aix_si (dest));
18948 emit_insn (gen_load_toc_aix_di (dest));
18952 /* Emit instructions to restore the link register after determining where
18953 its value has been stored. */
18956 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
18958 rs6000_stack_t *info = rs6000_stack_info ();
18961 operands[0] = source;
18962 operands[1] = scratch;
18964 if (info->lr_save_p)
18966 rtx frame_rtx = stack_pointer_rtx;
18967 HOST_WIDE_INT sp_offset = 0;
18970 if (frame_pointer_needed
18971 || cfun->calls_alloca
18972 || info->total_size > 32767)
18974 tmp = gen_frame_mem (Pmode, frame_rtx);
18975 emit_move_insn (operands[1], tmp);
18976 frame_rtx = operands[1];
18978 else if (info->push_p)
18979 sp_offset = info->total_size;
18981 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
18982 tmp = gen_frame_mem (Pmode, tmp);
18983 emit_move_insn (tmp, operands[0]);
18986 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
18988 /* Freeze lr_save_p. We've just emitted rtl that depends on the
18989 state of lr_save_p so any change from here on would be a bug. In
18990 particular, stop rs6000_ra_ever_killed from considering the SET
18991 of lr we may have added just above. */
18992 cfun->machine->lr_save_state = info->lr_save_p + 1;
18995 static GTY(()) alias_set_type set = -1;
18998 get_TOC_alias_set (void)
19001 set = new_alias_set ();
19005 /* This returns nonzero if the current function uses the TOC. This is
19006 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
19007 is generated by the ABI_V4 load_toc_* patterns. */
19014 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
19017 rtx pat = PATTERN (insn);
19020 if (GET_CODE (pat) == PARALLEL)
19021 for (i = 0; i < XVECLEN (pat, 0); i++)
19023 rtx sub = XVECEXP (pat, 0, i);
19024 if (GET_CODE (sub) == USE)
19026 sub = XEXP (sub, 0);
19027 if (GET_CODE (sub) == UNSPEC
19028 && XINT (sub, 1) == UNSPEC_TOC)
19038 create_TOC_reference (rtx symbol, rtx largetoc_reg)
19040 rtx tocrel, tocreg;
19042 if (TARGET_DEBUG_ADDR)
19044 if (GET_CODE (symbol) == SYMBOL_REF)
19045 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
19049 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
19050 GET_RTX_NAME (GET_CODE (symbol)));
19051 debug_rtx (symbol);
19055 if (!can_create_pseudo_p ())
19056 df_set_regs_ever_live (TOC_REGISTER, true);
19058 tocrel = gen_rtx_CONST (Pmode,
19059 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol),
19061 tocreg = gen_rtx_REG (Pmode, TOC_REGISTER);
19062 if (TARGET_CMODEL != CMODEL_SMALL)
19064 rtx hi = gen_rtx_CONST (Pmode,
19065 gen_rtx_PLUS (Pmode, tocreg,
19066 gen_rtx_HIGH (Pmode, tocrel)));
19067 if (largetoc_reg != NULL)
19069 emit_move_insn (largetoc_reg, hi);
19072 return gen_rtx_LO_SUM (Pmode, hi, copy_rtx (tocrel));
19075 return gen_rtx_PLUS (Pmode, tocreg, tocrel);
19078 /* Issue assembly directives that create a reference to the given DWARF
19079 FRAME_TABLE_LABEL from the current function section. */
19081 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
19083 fprintf (asm_out_file, "\t.ref %s\n",
19084 TARGET_STRIP_NAME_ENCODING (frame_table_label));
19087 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
19088 and the change to the stack pointer. */
19091 rs6000_emit_stack_tie (void)
19093 rtx mem = gen_frame_mem (BLKmode,
19094 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
19096 emit_insn (gen_stack_tie (mem));
19099 /* Emit the correct code for allocating stack space, as insns.
19100 If COPY_REG, make sure a copy of the old frame is left there.
19101 The generated code may use hard register 0 as a temporary. */
19104 rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg)
19107 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19108 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
19109 rtx todec = gen_int_mode (-size, Pmode);
19112 if (INTVAL (todec) != -size)
19114 warning (0, "stack frame too large");
19115 emit_insn (gen_trap ());
19119 if (crtl->limit_stack)
19121 if (REG_P (stack_limit_rtx)
19122 && REGNO (stack_limit_rtx) > 1
19123 && REGNO (stack_limit_rtx) <= 31)
19125 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
19126 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19129 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
19131 && DEFAULT_ABI == ABI_V4)
19133 rtx toload = gen_rtx_CONST (VOIDmode,
19134 gen_rtx_PLUS (Pmode,
19138 emit_insn (gen_elf_high (tmp_reg, toload));
19139 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
19140 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19144 warning (0, "stack limit expression is not supported");
19148 emit_move_insn (copy_reg, stack_reg);
19152 /* Need a note here so that try_split doesn't get confused. */
19153 if (get_last_insn () == NULL_RTX)
19154 emit_note (NOTE_INSN_DELETED);
19155 insn = emit_move_insn (tmp_reg, todec);
19156 try_split (PATTERN (insn), insn, 0);
19160 insn = emit_insn (TARGET_32BIT
19161 ? gen_movsi_update_stack (stack_reg, stack_reg,
19163 : gen_movdi_di_update_stack (stack_reg, stack_reg,
19164 todec, stack_reg));
19165 /* Since we didn't use gen_frame_mem to generate the MEM, grab
19166 it now and set the alias set/attributes. The above gen_*_update
19167 calls will generate a PARALLEL with the MEM set being the first
19169 par = PATTERN (insn);
19170 gcc_assert (GET_CODE (par) == PARALLEL);
19171 set = XVECEXP (par, 0, 0);
19172 gcc_assert (GET_CODE (set) == SET);
19173 mem = SET_DEST (set);
19174 gcc_assert (MEM_P (mem));
19175 MEM_NOTRAP_P (mem) = 1;
19176 set_mem_alias_set (mem, get_frame_alias_set ());
19178 RTX_FRAME_RELATED_P (insn) = 1;
19179 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
19180 gen_rtx_SET (VOIDmode, stack_reg,
19181 gen_rtx_PLUS (Pmode, stack_reg,
19182 GEN_INT (-size))));
19185 #define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
19187 #if PROBE_INTERVAL > 32768
19188 #error Cannot use indexed addressing mode for stack probing
19191 /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
19192 inclusive. These are offsets from the current stack pointer. */
19195 rs6000_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size)
19197 /* See if we have a constant small number of probes to generate. If so,
19198 that's the easy case. */
19199 if (first + size <= 32768)
19203 /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
19204 it exceeds SIZE. If only one probe is needed, this will not
19205 generate any code. Then probe at FIRST + SIZE. */
19206 for (i = PROBE_INTERVAL; i < size; i += PROBE_INTERVAL)
19207 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + i)));
19209 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + size)));
19212 /* Otherwise, do the same as above, but in a loop. Note that we must be
19213 extra careful with variables wrapping around because we might be at
19214 the very top (or the very bottom) of the address space and we have
19215 to be able to handle this case properly; in particular, we use an
19216 equality test for the loop condition. */
19219 HOST_WIDE_INT rounded_size;
19220 rtx r12 = gen_rtx_REG (Pmode, 12);
19221 rtx r0 = gen_rtx_REG (Pmode, 0);
19223 /* Sanity check for the addressing mode we're going to use. */
19224 gcc_assert (first <= 32768);
19226 /* Step 1: round SIZE to the previous multiple of the interval. */
19228 rounded_size = size & -PROBE_INTERVAL;
19231 /* Step 2: compute initial and final value of the loop counter. */
19233 /* TEST_ADDR = SP + FIRST. */
19234 emit_insn (gen_rtx_SET (VOIDmode, r12,
19235 plus_constant (stack_pointer_rtx, -first)));
19237 /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE. */
19238 if (rounded_size > 32768)
19240 emit_move_insn (r0, GEN_INT (-rounded_size));
19241 emit_insn (gen_rtx_SET (VOIDmode, r0,
19242 gen_rtx_PLUS (Pmode, r12, r0)));
19245 emit_insn (gen_rtx_SET (VOIDmode, r0,
19246 plus_constant (r12, -rounded_size)));
19249 /* Step 3: the loop
19251 while (TEST_ADDR != LAST_ADDR)
19253 TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
19257 probes at FIRST + N * PROBE_INTERVAL for values of N from 1
19258 until it is equal to ROUNDED_SIZE. */
19261 emit_insn (gen_probe_stack_rangedi (r12, r12, r0));
19263 emit_insn (gen_probe_stack_rangesi (r12, r12, r0));
19266 /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
19267 that SIZE is equal to ROUNDED_SIZE. */
19269 if (size != rounded_size)
19270 emit_stack_probe (plus_constant (r12, rounded_size - size));
19274 /* Probe a range of stack addresses from REG1 to REG2 inclusive. These are
19275 absolute addresses. */
19278 output_probe_stack_range (rtx reg1, rtx reg2)
19280 static int labelno = 0;
19281 char loop_lab[32], end_lab[32];
19284 ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno);
19285 ASM_GENERATE_INTERNAL_LABEL (end_lab, "LPSRE", labelno++);
19287 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
19289 /* Jump to END_LAB if TEST_ADDR == LAST_ADDR. */
19293 output_asm_insn ("{cmp|cmpd} 0,%0,%1", xops);
19295 output_asm_insn ("{cmp|cmpw} 0,%0,%1", xops);
19297 fputs ("\tbeq 0,", asm_out_file);
19298 assemble_name_raw (asm_out_file, end_lab);
19299 fputc ('\n', asm_out_file);
19301 /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */
19302 xops[1] = GEN_INT (-PROBE_INTERVAL);
19303 output_asm_insn ("{cal %0,%1(%0)|addi %0,%0,%1}", xops);
19305 /* Probe at TEST_ADDR and branch. */
19306 xops[1] = gen_rtx_REG (Pmode, 0);
19307 output_asm_insn ("{st|stw} %1,0(%0)", xops);
19308 fprintf (asm_out_file, "\tb ");
19309 assemble_name_raw (asm_out_file, loop_lab);
19310 fputc ('\n', asm_out_file);
19312 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, end_lab);
19317 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
19318 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
19319 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
19320 deduce these equivalences by itself so it wasn't necessary to hold
19321 its hand so much. */
19324 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
19325 rtx reg2, rtx rreg)
19329 /* copy_rtx will not make unique copies of registers, so we need to
19330 ensure we don't have unwanted sharing here. */
19332 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19335 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19337 real = copy_rtx (PATTERN (insn));
19339 if (reg2 != NULL_RTX)
19340 real = replace_rtx (real, reg2, rreg);
19342 real = replace_rtx (real, reg,
19343 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
19344 STACK_POINTER_REGNUM),
19347 /* We expect that 'real' is either a SET or a PARALLEL containing
19348 SETs (and possibly other stuff). In a PARALLEL, all the SETs
19349 are important so they all have to be marked RTX_FRAME_RELATED_P. */
19351 if (GET_CODE (real) == SET)
19355 temp = simplify_rtx (SET_SRC (set));
19357 SET_SRC (set) = temp;
19358 temp = simplify_rtx (SET_DEST (set));
19360 SET_DEST (set) = temp;
19361 if (GET_CODE (SET_DEST (set)) == MEM)
19363 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19365 XEXP (SET_DEST (set), 0) = temp;
19372 gcc_assert (GET_CODE (real) == PARALLEL);
19373 for (i = 0; i < XVECLEN (real, 0); i++)
19374 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
19376 rtx set = XVECEXP (real, 0, i);
19378 temp = simplify_rtx (SET_SRC (set));
19380 SET_SRC (set) = temp;
19381 temp = simplify_rtx (SET_DEST (set));
19383 SET_DEST (set) = temp;
19384 if (GET_CODE (SET_DEST (set)) == MEM)
19386 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19388 XEXP (SET_DEST (set), 0) = temp;
19390 RTX_FRAME_RELATED_P (set) = 1;
19394 RTX_FRAME_RELATED_P (insn) = 1;
19395 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
19400 /* Returns an insn that has a vrsave set operation with the
19401 appropriate CLOBBERs. */
19404 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
19407 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
19408 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19411 = gen_rtx_SET (VOIDmode,
19413 gen_rtx_UNSPEC_VOLATILE (SImode,
19414 gen_rtvec (2, reg, vrsave),
19415 UNSPECV_SET_VRSAVE));
19419 /* We need to clobber the registers in the mask so the scheduler
19420 does not move sets to VRSAVE before sets of AltiVec registers.
19422 However, if the function receives nonlocal gotos, reload will set
19423 all call saved registers live. We will end up with:
19425 (set (reg 999) (mem))
19426 (parallel [ (set (reg vrsave) (unspec blah))
19427 (clobber (reg 999))])
19429 The clobber will cause the store into reg 999 to be dead, and
19430 flow will attempt to delete an epilogue insn. In this case, we
19431 need an unspec use/set of the register. */
19433 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
19434 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19436 if (!epiloguep || call_used_regs [i])
19437 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
19438 gen_rtx_REG (V4SImode, i));
19441 rtx reg = gen_rtx_REG (V4SImode, i);
19444 = gen_rtx_SET (VOIDmode,
19446 gen_rtx_UNSPEC (V4SImode,
19447 gen_rtvec (1, reg), 27));
19451 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
19453 for (i = 0; i < nclobs; ++i)
19454 XVECEXP (insn, 0, i) = clobs[i];
19459 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
19460 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
19463 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
19464 unsigned int regno, int offset, HOST_WIDE_INT total_size)
19466 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
19467 rtx replacea, replaceb;
19469 int_rtx = GEN_INT (offset);
19471 /* Some cases that need register indexed addressing. */
19472 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
19473 || (TARGET_VSX && ALTIVEC_OR_VSX_VECTOR_MODE (mode))
19474 || (TARGET_E500_DOUBLE && mode == DFmode)
19476 && SPE_VECTOR_MODE (mode)
19477 && !SPE_CONST_OFFSET_OK (offset)))
19479 /* Whomever calls us must make sure r11 is available in the
19480 flow path of instructions in the prologue. */
19481 offset_rtx = gen_rtx_REG (Pmode, 11);
19482 emit_move_insn (offset_rtx, int_rtx);
19484 replacea = offset_rtx;
19485 replaceb = int_rtx;
19489 offset_rtx = int_rtx;
19490 replacea = NULL_RTX;
19491 replaceb = NULL_RTX;
19494 reg = gen_rtx_REG (mode, regno);
19495 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
19496 mem = gen_frame_mem (mode, addr);
19498 insn = emit_move_insn (mem, reg);
19500 return rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
19503 /* Emit an offset memory reference suitable for a frame store, while
19504 converting to a valid addressing mode. */
19507 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
19509 rtx int_rtx, offset_rtx;
19511 int_rtx = GEN_INT (offset);
19513 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
19514 || (TARGET_E500_DOUBLE && mode == DFmode))
19516 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
19517 emit_move_insn (offset_rtx, int_rtx);
19520 offset_rtx = int_rtx;
19522 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
19525 /* Look for user-defined global regs. We should not save and restore these,
19526 and cannot use stmw/lmw if there are any in its range. */
19529 no_global_regs_above (int first, bool gpr)
19532 int last = gpr ? 32 : 64;
19533 for (i = first; i < last; i++)
19534 if (global_regs[i])
19539 #ifndef TARGET_FIX_AND_CONTINUE
19540 #define TARGET_FIX_AND_CONTINUE 0
19543 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
19544 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
19545 #define LAST_SAVRES_REGISTER 31
19546 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
19548 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
19550 /* Temporary holding space for an out-of-line register save/restore
19552 static char savres_routine_name[30];
19554 /* Return the name for an out-of-line register save/restore routine.
19555 We are saving/restoring GPRs if GPR is true. */
19558 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
19559 bool savep, bool gpr, bool lr)
19561 const char *prefix = "";
19562 const char *suffix = "";
19564 /* Different targets are supposed to define
19565 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
19566 routine name could be defined with:
19568 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
19570 This is a nice idea in practice, but in reality, things are
19571 complicated in several ways:
19573 - ELF targets have save/restore routines for GPRs.
19575 - SPE targets use different prefixes for 32/64-bit registers, and
19576 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
19578 - PPC64 ELF targets have routines for save/restore of GPRs that
19579 differ in what they do with the link register, so having a set
19580 prefix doesn't work. (We only use one of the save routines at
19581 the moment, though.)
19583 - PPC32 elf targets have "exit" versions of the restore routines
19584 that restore the link register and can save some extra space.
19585 These require an extra suffix. (There are also "tail" versions
19586 of the restore routines and "GOT" versions of the save routines,
19587 but we don't generate those at present. Same problems apply,
19590 We deal with all this by synthesizing our own prefix/suffix and
19591 using that for the simple sprintf call shown above. */
19594 /* No floating point saves on the SPE. */
19598 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
19600 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
19605 else if (DEFAULT_ABI == ABI_V4)
19611 prefix = savep ? "_savegpr_" : "_restgpr_";
19613 prefix = savep ? "_savefpr_" : "_restfpr_";
19618 else if (DEFAULT_ABI == ABI_AIX)
19620 #ifndef POWERPC_LINUX
19621 /* No out-of-line save/restore routines for GPRs on AIX. */
19622 gcc_assert (!TARGET_AIX || !gpr);
19628 ? (lr ? "_savegpr0_" : "_savegpr1_")
19629 : (lr ? "_restgpr0_" : "_restgpr1_"));
19630 #ifdef POWERPC_LINUX
19632 prefix = (savep ? "_savefpr_" : "_restfpr_");
19636 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
19637 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
19640 else if (DEFAULT_ABI == ABI_DARWIN)
19641 sorry ("out-of-line save/restore routines not supported on Darwin");
19643 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
19645 return savres_routine_name;
19648 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
19649 We are saving/restoring GPRs if GPR is true. */
19652 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
19655 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
19657 int select = ((savep ? 1 : 0) << 2
19659 /* On the SPE, we never have any FPRs, but we do have
19660 32/64-bit versions of the routines. */
19661 ? (info->spe_64bit_regs_used ? 1 : 0)
19662 : (gpr ? 1 : 0)) << 1)
19665 /* Don't generate bogus routine names. */
19666 gcc_assert (FIRST_SAVRES_REGISTER <= regno
19667 && regno <= LAST_SAVRES_REGISTER);
19669 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
19675 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
19677 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
19678 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
19679 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
19685 /* Emit a sequence of insns, including a stack tie if needed, for
19686 resetting the stack pointer. If SAVRES is true, then don't reset the
19687 stack pointer, but move the base of the frame into r11 for use by
19688 out-of-line register restore routines. */
19691 rs6000_emit_stack_reset (rs6000_stack_t *info,
19692 rtx sp_reg_rtx, rtx frame_reg_rtx,
19693 int sp_offset, bool savres)
19695 /* This blockage is needed so that sched doesn't decide to move
19696 the sp change before the register restores. */
19697 if (frame_reg_rtx != sp_reg_rtx
19699 && info->spe_64bit_regs_used != 0
19700 && info->first_gp_reg_save != 32))
19701 rs6000_emit_stack_tie ();
19703 if (frame_reg_rtx != sp_reg_rtx)
19705 if (sp_offset != 0)
19707 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
19708 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
19709 GEN_INT (sp_offset)));
19712 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
19714 else if (sp_offset != 0)
19716 /* If we are restoring registers out-of-line, we will be using the
19717 "exit" variants of the restore routines, which will reset the
19718 stack for us. But we do need to point r11 into the right place
19719 for those routines. */
19720 rtx dest_reg = (savres
19721 ? gen_rtx_REG (Pmode, 11)
19724 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
19725 GEN_INT (sp_offset)));
19732 /* Construct a parallel rtx describing the effect of a call to an
19733 out-of-line register save/restore routine. */
19736 rs6000_make_savres_rtx (rs6000_stack_t *info,
19737 rtx frame_reg_rtx, int save_area_offset,
19738 enum machine_mode reg_mode,
19739 bool savep, bool gpr, bool lr)
19742 int offset, start_reg, end_reg, n_regs;
19743 int reg_size = GET_MODE_SIZE (reg_mode);
19749 ? info->first_gp_reg_save
19750 : info->first_fp_reg_save);
19751 end_reg = gpr ? 32 : 64;
19752 n_regs = end_reg - start_reg;
19753 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
19756 RTVEC_ELT (p, offset++) = ret_rtx;
19758 RTVEC_ELT (p, offset++)
19759 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
19761 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
19762 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
19763 RTVEC_ELT (p, offset++)
19764 = gen_rtx_USE (VOIDmode,
19765 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
19769 for (i = 0; i < end_reg - start_reg; i++)
19771 rtx addr, reg, mem;
19772 reg = gen_rtx_REG (reg_mode, start_reg + i);
19773 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19774 GEN_INT (save_area_offset + reg_size*i));
19775 mem = gen_frame_mem (reg_mode, addr);
19777 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
19779 savep ? reg : mem);
19784 rtx addr, reg, mem;
19785 reg = gen_rtx_REG (Pmode, 0);
19786 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19787 GEN_INT (info->lr_save_offset));
19788 mem = gen_frame_mem (Pmode, addr);
19789 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
19792 return gen_rtx_PARALLEL (VOIDmode, p);
19795 /* Determine whether the gp REG is really used. */
19798 rs6000_reg_live_or_pic_offset_p (int reg)
19800 /* If the function calls eh_return, claim used all the registers that would
19801 be checked for liveness otherwise. This is required for the PIC offset
19802 register with -mminimal-toc on AIX, as it is advertised as "fixed" for
19803 register allocation purposes in this case. */
19805 return (((crtl->calls_eh_return || df_regs_ever_live_p (reg))
19806 && (!call_used_regs[reg]
19807 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
19808 && !TARGET_SINGLE_PIC_BASE
19809 && TARGET_TOC && TARGET_MINIMAL_TOC)))
19810 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
19811 && !TARGET_SINGLE_PIC_BASE
19812 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
19813 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
19816 /* Emit function prologue as insns. */
19819 rs6000_emit_prologue (void)
19821 rs6000_stack_t *info = rs6000_stack_info ();
19822 enum machine_mode reg_mode = Pmode;
19823 int reg_size = TARGET_32BIT ? 4 : 8;
19824 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19825 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
19826 rtx frame_reg_rtx = sp_reg_rtx;
19827 rtx cr_save_rtx = NULL_RTX;
19830 int saving_FPRs_inline;
19831 int saving_GPRs_inline;
19832 int using_store_multiple;
19833 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
19834 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
19835 && call_used_regs[STATIC_CHAIN_REGNUM]);
19836 HOST_WIDE_INT sp_offset = 0;
19838 if (flag_stack_usage_info)
19839 current_function_static_stack_size = info->total_size;
19841 if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK && info->total_size)
19842 rs6000_emit_probe_stack_range (STACK_CHECK_PROTECT, info->total_size);
19844 if (TARGET_FIX_AND_CONTINUE)
19846 /* gdb on darwin arranges to forward a function from the old
19847 address by modifying the first 5 instructions of the function
19848 to branch to the overriding function. This is necessary to
19849 permit function pointers that point to the old function to
19850 actually forward to the new function. */
19851 emit_insn (gen_nop ());
19852 emit_insn (gen_nop ());
19853 emit_insn (gen_nop ());
19854 emit_insn (gen_nop ());
19855 emit_insn (gen_nop ());
19858 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19860 reg_mode = V2SImode;
19864 strategy = info->savres_strategy;
19865 using_store_multiple = strategy & SAVRES_MULTIPLE;
19866 saving_FPRs_inline = strategy & SAVE_INLINE_FPRS;
19867 saving_GPRs_inline = strategy & SAVE_INLINE_GPRS;
19869 /* For V.4, update stack before we do any saving and set back pointer. */
19870 if (! WORLD_SAVE_P (info)
19872 && (DEFAULT_ABI == ABI_V4
19873 || crtl->calls_eh_return))
19875 bool need_r11 = (TARGET_SPE
19876 ? (!saving_GPRs_inline
19877 && info->spe_64bit_regs_used == 0)
19878 : (!saving_FPRs_inline || !saving_GPRs_inline));
19879 rtx copy_reg = need_r11 ? gen_rtx_REG (Pmode, 11) : NULL;
19881 if (info->total_size < 32767)
19882 sp_offset = info->total_size;
19884 frame_reg_rtx = copy_reg;
19885 else if (info->cr_save_p
19887 || info->first_fp_reg_save < 64
19888 || info->first_gp_reg_save < 32
19889 || info->altivec_size != 0
19890 || info->vrsave_mask != 0
19891 || crtl->calls_eh_return)
19893 copy_reg = frame_ptr_rtx;
19894 frame_reg_rtx = copy_reg;
19898 /* The prologue won't be saving any regs so there is no need
19899 to set up a frame register to access any frame save area.
19900 We also won't be using sp_offset anywhere below, but set
19901 the correct value anyway to protect against future
19902 changes to this function. */
19903 sp_offset = info->total_size;
19905 rs6000_emit_allocate_stack (info->total_size, copy_reg);
19906 if (frame_reg_rtx != sp_reg_rtx)
19907 rs6000_emit_stack_tie ();
19910 /* Handle world saves specially here. */
19911 if (WORLD_SAVE_P (info))
19918 /* save_world expects lr in r0. */
19919 reg0 = gen_rtx_REG (Pmode, 0);
19920 if (info->lr_save_p)
19922 insn = emit_move_insn (reg0,
19923 gen_rtx_REG (Pmode, LR_REGNO));
19924 RTX_FRAME_RELATED_P (insn) = 1;
19927 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
19928 assumptions about the offsets of various bits of the stack
19930 gcc_assert (info->gp_save_offset == -220
19931 && info->fp_save_offset == -144
19932 && info->lr_save_offset == 8
19933 && info->cr_save_offset == 4
19936 && (!crtl->calls_eh_return
19937 || info->ehrd_offset == -432)
19938 && info->vrsave_save_offset == -224
19939 && info->altivec_save_offset == -416);
19941 treg = gen_rtx_REG (SImode, 11);
19942 emit_move_insn (treg, GEN_INT (-info->total_size));
19944 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
19945 in R11. It also clobbers R12, so beware! */
19947 /* Preserve CR2 for save_world prologues */
19949 sz += 32 - info->first_gp_reg_save;
19950 sz += 64 - info->first_fp_reg_save;
19951 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
19952 p = rtvec_alloc (sz);
19954 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
19955 gen_rtx_REG (SImode,
19957 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
19958 gen_rtx_SYMBOL_REF (Pmode,
19960 /* We do floats first so that the instruction pattern matches
19962 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
19964 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19965 ? DFmode : SFmode),
19966 info->first_fp_reg_save + i);
19967 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19968 GEN_INT (info->fp_save_offset
19969 + sp_offset + 8 * i));
19970 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19971 ? DFmode : SFmode), addr);
19973 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19975 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
19977 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
19978 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19979 GEN_INT (info->altivec_save_offset
19980 + sp_offset + 16 * i));
19981 rtx mem = gen_frame_mem (V4SImode, addr);
19983 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19985 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19987 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19988 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19989 GEN_INT (info->gp_save_offset
19990 + sp_offset + reg_size * i));
19991 rtx mem = gen_frame_mem (reg_mode, addr);
19993 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19997 /* CR register traditionally saved as CR2. */
19998 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
19999 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20000 GEN_INT (info->cr_save_offset
20002 rtx mem = gen_frame_mem (reg_mode, addr);
20004 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20006 /* Explain about use of R0. */
20007 if (info->lr_save_p)
20009 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20010 GEN_INT (info->lr_save_offset
20012 rtx mem = gen_frame_mem (reg_mode, addr);
20014 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
20016 /* Explain what happens to the stack pointer. */
20018 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
20019 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
20022 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20023 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20024 treg, GEN_INT (-info->total_size));
20025 sp_offset = info->total_size;
20028 /* If we use the link register, get it into r0. */
20029 if (!WORLD_SAVE_P (info) && info->lr_save_p)
20031 rtx addr, reg, mem;
20033 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
20034 gen_rtx_REG (Pmode, LR_REGNO));
20035 RTX_FRAME_RELATED_P (insn) = 1;
20037 if (!(strategy & (SAVE_NOINLINE_GPRS_SAVES_LR
20038 | SAVE_NOINLINE_FPRS_SAVES_LR)))
20040 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20041 GEN_INT (info->lr_save_offset + sp_offset));
20042 reg = gen_rtx_REG (Pmode, 0);
20043 mem = gen_rtx_MEM (Pmode, addr);
20044 /* This should not be of rs6000_sr_alias_set, because of
20045 __builtin_return_address. */
20047 insn = emit_move_insn (mem, reg);
20048 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20049 NULL_RTX, NULL_RTX);
20053 /* If we need to save CR, put it into r12 or r11. */
20054 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
20059 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
20061 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20062 RTX_FRAME_RELATED_P (insn) = 1;
20063 /* Now, there's no way that dwarf2out_frame_debug_expr is going
20064 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
20065 But that's OK. All we have to do is specify that _one_ condition
20066 code register is saved in this stack slot. The thrower's epilogue
20067 will then restore all the call-saved registers.
20068 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
20069 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
20070 gen_rtx_REG (SImode, CR2_REGNO));
20071 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20074 /* Do any required saving of fpr's. If only one or two to save, do
20075 it ourselves. Otherwise, call function. */
20076 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
20079 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20080 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
20081 && ! call_used_regs[info->first_fp_reg_save+i]))
20082 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
20083 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20085 info->first_fp_reg_save + i,
20086 info->fp_save_offset + sp_offset + 8 * i,
20089 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
20093 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20094 info->fp_save_offset + sp_offset,
20096 /*savep=*/true, /*gpr=*/false,
20098 & SAVE_NOINLINE_FPRS_SAVES_LR)
20100 insn = emit_insn (par);
20101 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20102 NULL_RTX, NULL_RTX);
20105 /* Save GPRs. This is done as a PARALLEL if we are using
20106 the store-multiple instructions. */
20107 if (!WORLD_SAVE_P (info)
20109 && info->spe_64bit_regs_used != 0
20110 && info->first_gp_reg_save != 32)
20113 rtx spe_save_area_ptr;
20115 /* Determine whether we can address all of the registers that need
20116 to be saved with an offset from the stack pointer that fits in
20117 the small const field for SPE memory instructions. */
20118 int spe_regs_addressable_via_sp
20119 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
20120 + (32 - info->first_gp_reg_save - 1) * reg_size)
20121 && saving_GPRs_inline);
20124 if (spe_regs_addressable_via_sp)
20126 spe_save_area_ptr = frame_reg_rtx;
20127 spe_offset = info->spe_gp_save_offset + sp_offset;
20131 /* Make r11 point to the start of the SPE save area. We need
20132 to be careful here if r11 is holding the static chain. If
20133 it is, then temporarily save it in r0. We would use r0 as
20134 our base register here, but using r0 as a base register in
20135 loads and stores means something different from what we
20137 int ool_adjust = (saving_GPRs_inline
20139 : (info->first_gp_reg_save
20140 - (FIRST_SAVRES_REGISTER+1))*8);
20141 HOST_WIDE_INT offset = (info->spe_gp_save_offset
20142 + sp_offset - ool_adjust);
20144 if (using_static_chain_p)
20146 rtx r0 = gen_rtx_REG (Pmode, 0);
20147 gcc_assert (info->first_gp_reg_save > 11);
20149 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
20152 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
20153 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
20155 GEN_INT (offset)));
20156 /* We need to make sure the move to r11 gets noted for
20157 properly outputting unwind information. */
20158 if (!saving_GPRs_inline)
20159 rs6000_frame_related (insn, frame_reg_rtx, offset,
20160 NULL_RTX, NULL_RTX);
20164 if (saving_GPRs_inline)
20166 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20167 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20169 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20170 rtx offset, addr, mem;
20172 /* We're doing all this to ensure that the offset fits into
20173 the immediate offset of 'evstdd'. */
20174 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
20176 offset = GEN_INT (reg_size * i + spe_offset);
20177 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
20178 mem = gen_rtx_MEM (V2SImode, addr);
20180 insn = emit_move_insn (mem, reg);
20182 rs6000_frame_related (insn, spe_save_area_ptr,
20183 info->spe_gp_save_offset
20184 + sp_offset + reg_size * i,
20185 offset, const0_rtx);
20192 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
20194 /*savep=*/true, /*gpr=*/true,
20196 insn = emit_insn (par);
20197 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20198 NULL_RTX, NULL_RTX);
20202 /* Move the static chain pointer back. */
20203 if (using_static_chain_p && !spe_regs_addressable_via_sp)
20204 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
20206 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
20210 /* Need to adjust r11 (r12) if we saved any FPRs. */
20211 if (info->first_fp_reg_save != 64)
20213 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
20215 rtx offset = GEN_INT (sp_offset
20216 + (-8 * (64-info->first_fp_reg_save)));
20217 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
20220 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20221 info->gp_save_offset + sp_offset,
20223 /*savep=*/true, /*gpr=*/true,
20225 & SAVE_NOINLINE_GPRS_SAVES_LR)
20227 insn = emit_insn (par);
20228 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20229 NULL_RTX, NULL_RTX);
20231 else if (!WORLD_SAVE_P (info) && using_store_multiple)
20235 p = rtvec_alloc (32 - info->first_gp_reg_save);
20236 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20238 rtx addr, reg, mem;
20239 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20240 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20241 GEN_INT (info->gp_save_offset
20244 mem = gen_frame_mem (reg_mode, addr);
20246 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
20248 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20249 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20250 NULL_RTX, NULL_RTX);
20252 else if (!WORLD_SAVE_P (info))
20255 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20256 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20258 rtx addr, reg, mem;
20259 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20261 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20262 GEN_INT (info->gp_save_offset
20265 mem = gen_frame_mem (reg_mode, addr);
20267 insn = emit_move_insn (mem, reg);
20268 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20269 NULL_RTX, NULL_RTX);
20273 /* ??? There's no need to emit actual instructions here, but it's the
20274 easiest way to get the frame unwind information emitted. */
20275 if (crtl->calls_eh_return)
20277 unsigned int i, regno;
20281 regno = EH_RETURN_DATA_REGNO (i);
20282 if (regno == INVALID_REGNUM)
20285 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
20286 info->ehrd_offset + sp_offset
20287 + reg_size * (int) i,
20292 /* In AIX ABI we need to make sure r2 is really saved. */
20293 if (TARGET_AIX && crtl->calls_eh_return)
20295 rtx tmp_reg, tmp_reg_si, hi, lo, compare_result, toc_save_done, jump;
20296 rtx save_insn, join_insn, note;
20297 long toc_restore_insn;
20299 gcc_assert (frame_reg_rtx == frame_ptr_rtx
20300 || frame_reg_rtx == sp_reg_rtx);
20301 tmp_reg = gen_rtx_REG (Pmode, 11);
20302 tmp_reg_si = gen_rtx_REG (SImode, 11);
20303 if (using_static_chain_p)
20304 emit_move_insn (gen_rtx_REG (Pmode, 0), tmp_reg);
20305 gcc_assert (saving_GPRs_inline && saving_FPRs_inline);
20306 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, LR_REGNO));
20307 /* Peek at instruction to which this function returns. If it's
20308 restoring r2, then we know we've already saved r2. We can't
20309 unconditionally save r2 because the value we have will already
20310 be updated if we arrived at this function via a plt call or
20311 toc adjusting stub. */
20312 emit_move_insn (tmp_reg_si, gen_rtx_MEM (SImode, tmp_reg));
20313 toc_restore_insn = TARGET_32BIT ? 0x80410014 : 0xE8410028;
20314 hi = gen_int_mode (toc_restore_insn & ~0xffff, SImode);
20315 emit_insn (gen_xorsi3 (tmp_reg_si, tmp_reg_si, hi));
20316 compare_result = gen_rtx_REG (CCUNSmode, CR0_REGNO);
20317 validate_condition_mode (EQ, CCUNSmode);
20318 lo = gen_int_mode (toc_restore_insn & 0xffff, SImode);
20319 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
20320 gen_rtx_COMPARE (CCUNSmode, tmp_reg_si, lo)));
20321 toc_save_done = gen_label_rtx ();
20322 jump = gen_rtx_IF_THEN_ELSE (VOIDmode,
20323 gen_rtx_EQ (VOIDmode, compare_result,
20325 gen_rtx_LABEL_REF (VOIDmode, toc_save_done),
20327 jump = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, jump));
20328 JUMP_LABEL (jump) = toc_save_done;
20329 LABEL_NUSES (toc_save_done) += 1;
20331 save_insn = emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode,
20332 TOC_REGNUM, sp_offset + 5 * reg_size,
20335 emit_label (toc_save_done);
20337 /* ??? If we leave SAVE_INSN as marked as saving R2, then we'll
20338 have a CFG that has different saves along different paths.
20339 Move the note to a dummy blockage insn, which describes that
20340 R2 is unconditionally saved after the label. */
20341 /* ??? An alternate representation might be a special insn pattern
20342 containing both the branch and the store. That might let the
20343 code that minimizes the number of DW_CFA_advance opcodes better
20344 freedom in placing the annotations. */
20345 note = find_reg_note (save_insn, REG_FRAME_RELATED_EXPR, NULL);
20347 remove_note (save_insn, note);
20348 RTX_FRAME_RELATED_P (save_insn) = 0;
20350 join_insn = emit_insn (gen_blockage ());
20351 REG_NOTES (join_insn) = note;
20352 RTX_FRAME_RELATED_P (join_insn) = 1;
20354 if (using_static_chain_p)
20355 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, 0));
20358 /* Save CR if we use any that must be preserved. */
20359 if (!WORLD_SAVE_P (info) && info->cr_save_p)
20361 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20362 GEN_INT (info->cr_save_offset + sp_offset));
20363 rtx mem = gen_frame_mem (SImode, addr);
20364 /* See the large comment above about why CR2_REGNO is used. */
20365 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
20367 /* If r12 was used to hold the original sp, copy cr into r0 now
20369 if (REGNO (frame_reg_rtx) == 12)
20373 cr_save_rtx = gen_rtx_REG (SImode, 0);
20374 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20375 RTX_FRAME_RELATED_P (insn) = 1;
20376 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
20377 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20379 insn = emit_move_insn (mem, cr_save_rtx);
20381 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20382 NULL_RTX, NULL_RTX);
20385 /* Update stack and set back pointer unless this is V.4,
20386 for which it was done previously. */
20387 if (!WORLD_SAVE_P (info) && info->push_p
20388 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
20390 rtx copy_reg = NULL;
20392 if (info->total_size < 32767)
20393 sp_offset = info->total_size;
20394 else if (info->altivec_size != 0
20395 || info->vrsave_mask != 0)
20397 copy_reg = frame_ptr_rtx;
20398 frame_reg_rtx = copy_reg;
20401 sp_offset = info->total_size;
20402 rs6000_emit_allocate_stack (info->total_size, copy_reg);
20403 if (frame_reg_rtx != sp_reg_rtx)
20404 rs6000_emit_stack_tie ();
20407 /* Set frame pointer, if needed. */
20408 if (frame_pointer_needed)
20410 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
20412 RTX_FRAME_RELATED_P (insn) = 1;
20415 /* Save AltiVec registers if needed. Save here because the red zone does
20416 not include AltiVec registers. */
20417 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
20421 /* There should be a non inline version of this, for when we
20422 are saving lots of vector registers. */
20423 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20424 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20426 rtx areg, savereg, mem;
20429 offset = info->altivec_save_offset + sp_offset
20430 + 16 * (i - info->first_altivec_reg_save);
20432 savereg = gen_rtx_REG (V4SImode, i);
20434 areg = gen_rtx_REG (Pmode, 0);
20435 emit_move_insn (areg, GEN_INT (offset));
20437 /* AltiVec addressing mode is [reg+reg]. */
20438 mem = gen_frame_mem (V4SImode,
20439 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
20441 insn = emit_move_insn (mem, savereg);
20443 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20444 areg, GEN_INT (offset));
20448 /* VRSAVE is a bit vector representing which AltiVec registers
20449 are used. The OS uses this to determine which vector
20450 registers to save on a context switch. We need to save
20451 VRSAVE on the stack frame, add whatever AltiVec registers we
20452 used in this function, and do the corresponding magic in the
20455 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
20456 && info->vrsave_mask != 0)
20458 rtx reg, mem, vrsave;
20461 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
20462 as frame_reg_rtx and r11 as the static chain pointer for
20463 nested functions. */
20464 reg = gen_rtx_REG (SImode, 0);
20465 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
20467 emit_insn (gen_get_vrsave_internal (reg));
20469 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
20471 if (!WORLD_SAVE_P (info))
20474 offset = info->vrsave_save_offset + sp_offset;
20475 mem = gen_frame_mem (SImode,
20476 gen_rtx_PLUS (Pmode, frame_reg_rtx,
20477 GEN_INT (offset)));
20478 insn = emit_move_insn (mem, reg);
20481 /* Include the registers in the mask. */
20482 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
20484 insn = emit_insn (generate_set_vrsave (reg, info, 0));
20487 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
20488 if (!TARGET_SINGLE_PIC_BASE
20489 && ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
20490 || (DEFAULT_ABI == ABI_V4
20491 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
20492 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))))
20494 /* If emit_load_toc_table will use the link register, we need to save
20495 it. We use R12 for this purpose because emit_load_toc_table
20496 can use register 0. This allows us to use a plain 'blr' to return
20497 from the procedure more often. */
20498 int save_LR_around_toc_setup = (TARGET_ELF
20499 && DEFAULT_ABI != ABI_AIX
20501 && ! info->lr_save_p
20502 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
20503 if (save_LR_around_toc_setup)
20505 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
20507 insn = emit_move_insn (frame_ptr_rtx, lr);
20508 RTX_FRAME_RELATED_P (insn) = 1;
20510 rs6000_emit_load_toc_table (TRUE);
20512 insn = emit_move_insn (lr, frame_ptr_rtx);
20513 add_reg_note (insn, REG_CFA_RESTORE, lr);
20514 RTX_FRAME_RELATED_P (insn) = 1;
20517 rs6000_emit_load_toc_table (TRUE);
20521 if (!TARGET_SINGLE_PIC_BASE
20522 && DEFAULT_ABI == ABI_DARWIN
20523 && flag_pic && crtl->uses_pic_offset_table)
20525 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
20526 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
20528 /* Save and restore LR locally around this call (in R0). */
20529 if (!info->lr_save_p)
20530 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
20532 emit_insn (gen_load_macho_picbase (src));
20534 emit_move_insn (gen_rtx_REG (Pmode,
20535 RS6000_PIC_OFFSET_TABLE_REGNUM),
20538 if (!info->lr_save_p)
20539 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
20543 /* If we need to, save the TOC register after doing the stack setup.
20544 Do not emit eh frame info for this save. The unwinder wants info,
20545 conceptually attached to instructions in this function, about
20546 register values in the caller of this function. This R2 may have
20547 already been changed from the value in the caller.
20548 We don't attempt to write accurate DWARF EH frame info for R2
20549 because code emitted by gcc for a (non-pointer) function call
20550 doesn't save and restore R2. Instead, R2 is managed out-of-line
20551 by a linker generated plt call stub when the function resides in
20552 a shared library. This behaviour is costly to describe in DWARF,
20553 both in terms of the size of DWARF info and the time taken in the
20554 unwinder to interpret it. R2 changes, apart from the
20555 calls_eh_return case earlier in this function, are handled by
20556 linux-unwind.h frob_update_context. */
20557 if (rs6000_save_toc_in_prologue_p ())
20559 rtx addr = gen_rtx_PLUS (Pmode, sp_reg_rtx, GEN_INT (5 * reg_size));
20560 rtx mem = gen_frame_mem (reg_mode, addr);
20561 emit_move_insn (mem, gen_rtx_REG (reg_mode, TOC_REGNUM));
20565 /* Write function prologue. */
20568 rs6000_output_function_prologue (FILE *file,
20569 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
20571 rs6000_stack_t *info = rs6000_stack_info ();
20573 if (TARGET_DEBUG_STACK)
20574 debug_stack_info (info);
20576 /* Write .extern for any function we will call to save and restore
20578 if (info->first_fp_reg_save < 64)
20581 int regno = info->first_fp_reg_save - 32;
20583 if ((info->savres_strategy & SAVE_INLINE_FPRS) == 0)
20585 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
20586 /*gpr=*/false, /*lr=*/false);
20587 fprintf (file, "\t.extern %s\n", name);
20589 if ((info->savres_strategy & REST_INLINE_FPRS) == 0)
20591 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
20592 /*gpr=*/false, /*lr=*/true);
20593 fprintf (file, "\t.extern %s\n", name);
20597 /* Write .extern for AIX common mode routines, if needed. */
20598 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
20600 fputs ("\t.extern __mulh\n", file);
20601 fputs ("\t.extern __mull\n", file);
20602 fputs ("\t.extern __divss\n", file);
20603 fputs ("\t.extern __divus\n", file);
20604 fputs ("\t.extern __quoss\n", file);
20605 fputs ("\t.extern __quous\n", file);
20606 common_mode_defined = 1;
20609 rs6000_pic_labelno++;
20612 /* Non-zero if vmx regs are restored before the frame pop, zero if
20613 we restore after the pop when possible. */
20614 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
20616 /* Reload CR from REG. */
20619 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
20624 if (using_mfcr_multiple)
20626 for (i = 0; i < 8; i++)
20627 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20629 gcc_assert (count);
20632 if (using_mfcr_multiple && count > 1)
20637 p = rtvec_alloc (count);
20640 for (i = 0; i < 8; i++)
20641 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20643 rtvec r = rtvec_alloc (2);
20644 RTVEC_ELT (r, 0) = reg;
20645 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
20646 RTVEC_ELT (p, ndx) =
20647 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
20648 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
20651 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20652 gcc_assert (ndx == count);
20655 for (i = 0; i < 8; i++)
20656 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20658 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
20664 /* Return true if OFFSET from stack pointer can be clobbered by signals.
20665 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
20666 below stack pointer not cloberred by signals. */
20669 offset_below_red_zone_p (HOST_WIDE_INT offset)
20671 return offset < (DEFAULT_ABI == ABI_V4
20673 : TARGET_32BIT ? -220 : -288);
20676 /* Emit function epilogue as insns. */
20679 rs6000_emit_epilogue (int sibcall)
20681 rs6000_stack_t *info;
20682 int restoring_GPRs_inline;
20683 int restoring_FPRs_inline;
20684 int using_load_multiple;
20685 int using_mtcr_multiple;
20686 int use_backchain_to_restore_sp;
20690 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
20691 rtx frame_reg_rtx = sp_reg_rtx;
20692 rtx cfa_restores = NULL_RTX;
20694 rtx cr_save_reg = NULL_RTX;
20695 enum machine_mode reg_mode = Pmode;
20696 int reg_size = TARGET_32BIT ? 4 : 8;
20699 info = rs6000_stack_info ();
20701 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
20703 reg_mode = V2SImode;
20707 strategy = info->savres_strategy;
20708 using_load_multiple = strategy & SAVRES_MULTIPLE;
20709 restoring_FPRs_inline = sibcall || (strategy & REST_INLINE_FPRS);
20710 restoring_GPRs_inline = sibcall || (strategy & REST_INLINE_GPRS);
20711 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
20712 || rs6000_cpu == PROCESSOR_PPC603
20713 || rs6000_cpu == PROCESSOR_PPC750
20715 /* Restore via the backchain when we have a large frame, since this
20716 is more efficient than an addis, addi pair. The second condition
20717 here will not trigger at the moment; We don't actually need a
20718 frame pointer for alloca, but the generic parts of the compiler
20719 give us one anyway. */
20720 use_backchain_to_restore_sp = (info->total_size > 32767 - info->lr_save_offset
20721 || (cfun->calls_alloca
20722 && !frame_pointer_needed));
20723 restore_lr = (info->lr_save_p
20724 && (restoring_FPRs_inline
20725 || (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR))
20726 && (restoring_GPRs_inline
20727 || info->first_fp_reg_save < 64));
20729 if (WORLD_SAVE_P (info))
20733 const char *alloc_rname;
20736 /* eh_rest_world_r10 will return to the location saved in the LR
20737 stack slot (which is not likely to be our caller.)
20738 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
20739 rest_world is similar, except any R10 parameter is ignored.
20740 The exception-handling stuff that was here in 2.95 is no
20741 longer necessary. */
20745 + 32 - info->first_gp_reg_save
20746 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
20747 + 63 + 1 - info->first_fp_reg_save);
20749 strcpy (rname, ((crtl->calls_eh_return) ?
20750 "*eh_rest_world_r10" : "*rest_world"));
20751 alloc_rname = ggc_strdup (rname);
20754 RTVEC_ELT (p, j++) = ret_rtx;
20755 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
20756 gen_rtx_REG (Pmode,
20759 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
20760 /* The instruction pattern requires a clobber here;
20761 it is shared with the restVEC helper. */
20763 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
20766 /* CR register traditionally saved as CR2. */
20767 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
20768 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20769 GEN_INT (info->cr_save_offset));
20770 rtx mem = gen_frame_mem (reg_mode, addr);
20772 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20775 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20777 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20778 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20779 GEN_INT (info->gp_save_offset
20781 rtx mem = gen_frame_mem (reg_mode, addr);
20783 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20785 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
20787 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
20788 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20789 GEN_INT (info->altivec_save_offset
20791 rtx mem = gen_frame_mem (V4SImode, addr);
20793 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20795 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
20797 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20798 ? DFmode : SFmode),
20799 info->first_fp_reg_save + i);
20800 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20801 GEN_INT (info->fp_save_offset
20803 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20804 ? DFmode : SFmode), addr);
20806 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20809 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
20811 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
20813 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
20815 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
20817 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
20818 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
20823 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
20825 sp_offset = info->total_size;
20827 /* Restore AltiVec registers if we must do so before adjusting the
20829 if (TARGET_ALTIVEC_ABI
20830 && info->altivec_size != 0
20831 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20832 || (DEFAULT_ABI != ABI_V4
20833 && offset_below_red_zone_p (info->altivec_save_offset))))
20837 if (use_backchain_to_restore_sp)
20839 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20840 emit_move_insn (frame_reg_rtx,
20841 gen_rtx_MEM (Pmode, sp_reg_rtx));
20844 else if (frame_pointer_needed)
20845 frame_reg_rtx = hard_frame_pointer_rtx;
20847 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20848 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20850 rtx addr, areg, mem, reg;
20852 areg = gen_rtx_REG (Pmode, 0);
20854 (areg, GEN_INT (info->altivec_save_offset
20856 + 16 * (i - info->first_altivec_reg_save)));
20858 /* AltiVec addressing mode is [reg+reg]. */
20859 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
20860 mem = gen_frame_mem (V4SImode, addr);
20862 reg = gen_rtx_REG (V4SImode, i);
20863 emit_move_insn (reg, mem);
20864 if (offset_below_red_zone_p (info->altivec_save_offset
20865 + (i - info->first_altivec_reg_save)
20867 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20872 /* Restore VRSAVE if we must do so before adjusting the stack. */
20874 && TARGET_ALTIVEC_VRSAVE
20875 && info->vrsave_mask != 0
20876 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20877 || (DEFAULT_ABI != ABI_V4
20878 && offset_below_red_zone_p (info->vrsave_save_offset))))
20880 rtx addr, mem, reg;
20882 if (frame_reg_rtx == sp_reg_rtx)
20884 if (use_backchain_to_restore_sp)
20886 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20887 emit_move_insn (frame_reg_rtx,
20888 gen_rtx_MEM (Pmode, sp_reg_rtx));
20891 else if (frame_pointer_needed)
20892 frame_reg_rtx = hard_frame_pointer_rtx;
20895 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20896 GEN_INT (info->vrsave_save_offset + sp_offset));
20897 mem = gen_frame_mem (SImode, addr);
20898 reg = gen_rtx_REG (SImode, 12);
20899 emit_move_insn (reg, mem);
20901 emit_insn (generate_set_vrsave (reg, info, 1));
20905 /* If we have a large stack frame, restore the old stack pointer
20906 using the backchain. */
20907 if (use_backchain_to_restore_sp)
20909 if (frame_reg_rtx == sp_reg_rtx)
20911 /* Under V.4, don't reset the stack pointer until after we're done
20912 loading the saved registers. */
20913 if (DEFAULT_ABI == ABI_V4)
20914 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20916 insn = emit_move_insn (frame_reg_rtx,
20917 gen_rtx_MEM (Pmode, sp_reg_rtx));
20920 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20921 && DEFAULT_ABI == ABI_V4)
20922 /* frame_reg_rtx has been set up by the altivec restore. */
20926 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
20927 frame_reg_rtx = sp_reg_rtx;
20930 /* If we have a frame pointer, we can restore the old stack pointer
20932 else if (frame_pointer_needed)
20934 frame_reg_rtx = sp_reg_rtx;
20935 if (DEFAULT_ABI == ABI_V4)
20936 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20937 /* Prevent reordering memory accesses against stack pointer restore. */
20938 else if (cfun->calls_alloca
20939 || offset_below_red_zone_p (-info->total_size))
20941 rtx mem1 = gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx);
20942 rtx mem2 = gen_rtx_MEM (BLKmode, sp_reg_rtx);
20943 MEM_NOTRAP_P (mem1) = 1;
20944 MEM_NOTRAP_P (mem2) = 1;
20945 emit_insn (gen_frame_tie (mem1, mem2));
20948 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
20949 GEN_INT (info->total_size)));
20952 else if (info->push_p
20953 && DEFAULT_ABI != ABI_V4
20954 && !crtl->calls_eh_return)
20956 /* Prevent reordering memory accesses against stack pointer restore. */
20957 if (cfun->calls_alloca
20958 || offset_below_red_zone_p (-info->total_size))
20960 rtx mem = gen_rtx_MEM (BLKmode, sp_reg_rtx);
20961 MEM_NOTRAP_P (mem) = 1;
20962 emit_insn (gen_stack_tie (mem));
20964 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
20965 GEN_INT (info->total_size)));
20968 if (insn && frame_reg_rtx == sp_reg_rtx)
20972 REG_NOTES (insn) = cfa_restores;
20973 cfa_restores = NULL_RTX;
20975 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
20976 RTX_FRAME_RELATED_P (insn) = 1;
20979 /* Restore AltiVec registers if we have not done so already. */
20980 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20981 && TARGET_ALTIVEC_ABI
20982 && info->altivec_size != 0
20983 && (DEFAULT_ABI == ABI_V4
20984 || !offset_below_red_zone_p (info->altivec_save_offset)))
20988 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20989 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20991 rtx addr, areg, mem, reg;
20993 areg = gen_rtx_REG (Pmode, 0);
20995 (areg, GEN_INT (info->altivec_save_offset
20997 + 16 * (i - info->first_altivec_reg_save)));
20999 /* AltiVec addressing mode is [reg+reg]. */
21000 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
21001 mem = gen_frame_mem (V4SImode, addr);
21003 reg = gen_rtx_REG (V4SImode, i);
21004 emit_move_insn (reg, mem);
21005 if (DEFAULT_ABI == ABI_V4)
21006 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21011 /* Restore VRSAVE if we have not done so already. */
21012 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21014 && TARGET_ALTIVEC_VRSAVE
21015 && info->vrsave_mask != 0
21016 && (DEFAULT_ABI == ABI_V4
21017 || !offset_below_red_zone_p (info->vrsave_save_offset)))
21019 rtx addr, mem, reg;
21021 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21022 GEN_INT (info->vrsave_save_offset + sp_offset));
21023 mem = gen_frame_mem (SImode, addr);
21024 reg = gen_rtx_REG (SImode, 12);
21025 emit_move_insn (reg, mem);
21027 emit_insn (generate_set_vrsave (reg, info, 1));
21030 /* Get the old lr if we saved it. If we are restoring registers
21031 out-of-line, then the out-of-line routines can do this for us. */
21032 if (restore_lr && restoring_GPRs_inline)
21034 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21035 info->lr_save_offset + sp_offset);
21037 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21040 /* Get the old cr if we saved it. */
21041 if (info->cr_save_p)
21043 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21044 GEN_INT (info->cr_save_offset + sp_offset));
21045 rtx mem = gen_frame_mem (SImode, addr);
21047 cr_save_reg = gen_rtx_REG (SImode,
21048 DEFAULT_ABI == ABI_AIX
21049 && !restoring_GPRs_inline
21050 && info->first_fp_reg_save < 64
21052 emit_move_insn (cr_save_reg, mem);
21055 /* Set LR here to try to overlap restores below. LR is always saved
21056 above incoming stack, so it never needs REG_CFA_RESTORE. */
21057 if (restore_lr && restoring_GPRs_inline)
21058 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21059 gen_rtx_REG (Pmode, 0));
21061 /* Load exception handler data registers, if needed. */
21062 if (crtl->calls_eh_return)
21064 unsigned int i, regno;
21068 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21069 GEN_INT (sp_offset + 5 * reg_size));
21070 rtx mem = gen_frame_mem (reg_mode, addr);
21072 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
21079 regno = EH_RETURN_DATA_REGNO (i);
21080 if (regno == INVALID_REGNUM)
21083 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
21084 info->ehrd_offset + sp_offset
21085 + reg_size * (int) i);
21087 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
21091 /* Restore GPRs. This is done as a PARALLEL if we are using
21092 the load-multiple instructions. */
21094 && info->spe_64bit_regs_used != 0
21095 && info->first_gp_reg_save != 32)
21097 /* Determine whether we can address all of the registers that need
21098 to be saved with an offset from the stack pointer that fits in
21099 the small const field for SPE memory instructions. */
21100 int spe_regs_addressable_via_sp
21101 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
21102 + (32 - info->first_gp_reg_save - 1) * reg_size)
21103 && restoring_GPRs_inline);
21106 if (spe_regs_addressable_via_sp)
21107 spe_offset = info->spe_gp_save_offset + sp_offset;
21110 rtx old_frame_reg_rtx = frame_reg_rtx;
21111 /* Make r11 point to the start of the SPE save area. We worried about
21112 not clobbering it when we were saving registers in the prologue.
21113 There's no need to worry here because the static chain is passed
21114 anew to every function. */
21115 int ool_adjust = (restoring_GPRs_inline
21117 : (info->first_gp_reg_save
21118 - (FIRST_SAVRES_REGISTER+1))*8);
21120 if (frame_reg_rtx == sp_reg_rtx)
21121 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21122 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
21123 GEN_INT (info->spe_gp_save_offset
21126 /* Keep the invariant that frame_reg_rtx + sp_offset points
21127 at the top of the stack frame. */
21128 sp_offset = -info->spe_gp_save_offset;
21133 if (restoring_GPRs_inline)
21135 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21136 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21138 rtx offset, addr, mem, reg;
21140 /* We're doing all this to ensure that the immediate offset
21141 fits into the immediate field of 'evldd'. */
21142 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
21144 offset = GEN_INT (spe_offset + reg_size * i);
21145 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
21146 mem = gen_rtx_MEM (V2SImode, addr);
21147 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21149 insn = emit_move_insn (reg, mem);
21150 if (DEFAULT_ABI == ABI_V4)
21152 if (frame_pointer_needed
21153 && info->first_gp_reg_save + i
21154 == HARD_FRAME_POINTER_REGNUM)
21156 add_reg_note (insn, REG_CFA_DEF_CFA,
21157 plus_constant (frame_reg_rtx,
21159 RTX_FRAME_RELATED_P (insn) = 1;
21162 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21171 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
21173 /*savep=*/false, /*gpr=*/true,
21175 emit_jump_insn (par);
21176 /* We don't want anybody else emitting things after we jumped
21181 else if (!restoring_GPRs_inline)
21183 /* We are jumping to an out-of-line function. */
21184 bool can_use_exit = info->first_fp_reg_save == 64;
21187 /* Emit stack reset code if we need it. */
21189 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21190 sp_offset, can_use_exit);
21193 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
21196 GEN_INT (sp_offset - info->fp_size)));
21197 if (REGNO (frame_reg_rtx) == 11)
21198 sp_offset += info->fp_size;
21201 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
21202 info->gp_save_offset, reg_mode,
21203 /*savep=*/false, /*gpr=*/true,
21204 /*lr=*/can_use_exit);
21208 if (info->cr_save_p)
21210 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21211 if (DEFAULT_ABI == ABI_V4)
21213 = alloc_reg_note (REG_CFA_RESTORE,
21214 gen_rtx_REG (SImode, CR2_REGNO),
21218 emit_jump_insn (par);
21220 /* We don't want anybody else emitting things after we jumped
21225 insn = emit_insn (par);
21226 if (DEFAULT_ABI == ABI_V4)
21228 if (frame_pointer_needed)
21230 add_reg_note (insn, REG_CFA_DEF_CFA,
21231 plus_constant (frame_reg_rtx, sp_offset));
21232 RTX_FRAME_RELATED_P (insn) = 1;
21235 for (i = info->first_gp_reg_save; i < 32; i++)
21237 = alloc_reg_note (REG_CFA_RESTORE,
21238 gen_rtx_REG (reg_mode, i), cfa_restores);
21241 else if (using_load_multiple)
21244 p = rtvec_alloc (32 - info->first_gp_reg_save);
21245 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21247 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21248 GEN_INT (info->gp_save_offset
21251 rtx mem = gen_frame_mem (reg_mode, addr);
21252 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21254 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
21255 if (DEFAULT_ABI == ABI_V4)
21256 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21259 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
21260 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
21262 add_reg_note (insn, REG_CFA_DEF_CFA,
21263 plus_constant (frame_reg_rtx, sp_offset));
21264 RTX_FRAME_RELATED_P (insn) = 1;
21269 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21270 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21272 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21273 GEN_INT (info->gp_save_offset
21276 rtx mem = gen_frame_mem (reg_mode, addr);
21277 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21279 insn = emit_move_insn (reg, mem);
21280 if (DEFAULT_ABI == ABI_V4)
21282 if (frame_pointer_needed
21283 && info->first_gp_reg_save + i
21284 == HARD_FRAME_POINTER_REGNUM)
21286 add_reg_note (insn, REG_CFA_DEF_CFA,
21287 plus_constant (frame_reg_rtx, sp_offset));
21288 RTX_FRAME_RELATED_P (insn) = 1;
21291 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21297 if (restore_lr && !restoring_GPRs_inline)
21299 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21300 info->lr_save_offset + sp_offset);
21302 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21303 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21304 gen_rtx_REG (Pmode, 0));
21307 /* Restore fpr's if we need to do it without calling a function. */
21308 if (restoring_FPRs_inline)
21309 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21310 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
21311 && ! call_used_regs[info->first_fp_reg_save+i]))
21313 rtx addr, mem, reg;
21314 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21315 GEN_INT (info->fp_save_offset
21318 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21319 ? DFmode : SFmode), addr);
21320 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21321 ? DFmode : SFmode),
21322 info->first_fp_reg_save + i);
21324 emit_move_insn (reg, mem);
21325 if (DEFAULT_ABI == ABI_V4)
21326 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21330 /* If we saved cr, restore it here. Just those that were used. */
21331 if (info->cr_save_p)
21333 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21334 if (DEFAULT_ABI == ABI_V4)
21336 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
21340 /* If this is V.4, unwind the stack pointer after all of the loads
21342 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21343 sp_offset, !restoring_FPRs_inline);
21348 REG_NOTES (insn) = cfa_restores;
21349 cfa_restores = NULL_RTX;
21351 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
21352 RTX_FRAME_RELATED_P (insn) = 1;
21355 if (crtl->calls_eh_return)
21357 rtx sa = EH_RETURN_STACKADJ_RTX;
21358 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
21364 bool lr = (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
21365 if (! restoring_FPRs_inline)
21366 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
21368 p = rtvec_alloc (2);
21370 RTVEC_ELT (p, 0) = ret_rtx;
21371 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
21372 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
21373 : gen_rtx_CLOBBER (VOIDmode,
21374 gen_rtx_REG (Pmode, 65)));
21376 /* If we have to restore more than two FP registers, branch to the
21377 restore function. It will return to our caller. */
21378 if (! restoring_FPRs_inline)
21383 sym = rs6000_savres_routine_sym (info,
21387 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
21388 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
21389 gen_rtx_REG (Pmode,
21390 DEFAULT_ABI == ABI_AIX
21392 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21395 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
21396 GEN_INT (info->fp_save_offset + 8*i));
21397 mem = gen_frame_mem (DFmode, addr);
21399 RTVEC_ELT (p, i+4) =
21400 gen_rtx_SET (VOIDmode,
21401 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
21406 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
21410 /* Write function epilogue. */
21413 rs6000_output_function_epilogue (FILE *file,
21414 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
21417 macho_branch_islands ();
21418 /* Mach-O doesn't support labels at the end of objects, so if
21419 it looks like we might want one, insert a NOP. */
21421 rtx insn = get_last_insn ();
21424 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
21425 insn = PREV_INSN (insn);
21429 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
21430 fputs ("\tnop\n", file);
21434 /* Output a traceback table here. See /usr/include/sys/debug.h for info
21437 We don't output a traceback table if -finhibit-size-directive was
21438 used. The documentation for -finhibit-size-directive reads
21439 ``don't output a @code{.size} assembler directive, or anything
21440 else that would cause trouble if the function is split in the
21441 middle, and the two halves are placed at locations far apart in
21442 memory.'' The traceback table has this property, since it
21443 includes the offset from the start of the function to the
21444 traceback table itself.
21446 System V.4 Powerpc's (and the embedded ABI derived from it) use a
21447 different traceback table. */
21448 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
21449 && rs6000_traceback != traceback_none && !cfun->is_thunk)
21451 const char *fname = NULL;
21452 const char *language_string = lang_hooks.name;
21453 int fixed_parms = 0, float_parms = 0, parm_info = 0;
21455 int optional_tbtab;
21456 rs6000_stack_t *info = rs6000_stack_info ();
21458 if (rs6000_traceback == traceback_full)
21459 optional_tbtab = 1;
21460 else if (rs6000_traceback == traceback_part)
21461 optional_tbtab = 0;
21463 optional_tbtab = !optimize_size && !TARGET_ELF;
21465 if (optional_tbtab)
21467 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
21468 while (*fname == '.') /* V.4 encodes . in the name */
21471 /* Need label immediately before tbtab, so we can compute
21472 its offset from the function start. */
21473 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
21474 ASM_OUTPUT_LABEL (file, fname);
21477 /* The .tbtab pseudo-op can only be used for the first eight
21478 expressions, since it can't handle the possibly variable
21479 length fields that follow. However, if you omit the optional
21480 fields, the assembler outputs zeros for all optional fields
21481 anyways, giving each variable length field is minimum length
21482 (as defined in sys/debug.h). Thus we can not use the .tbtab
21483 pseudo-op at all. */
21485 /* An all-zero word flags the start of the tbtab, for debuggers
21486 that have to find it by searching forward from the entry
21487 point or from the current pc. */
21488 fputs ("\t.long 0\n", file);
21490 /* Tbtab format type. Use format type 0. */
21491 fputs ("\t.byte 0,", file);
21493 /* Language type. Unfortunately, there does not seem to be any
21494 official way to discover the language being compiled, so we
21495 use language_string.
21496 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
21497 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
21498 a number, so for now use 9. LTO and Go aren't assigned numbers
21499 either, so for now use 0. */
21500 if (! strcmp (language_string, "GNU C")
21501 || ! strcmp (language_string, "GNU GIMPLE")
21502 || ! strcmp (language_string, "GNU Go"))
21504 else if (! strcmp (language_string, "GNU F77")
21505 || ! strcmp (language_string, "GNU Fortran"))
21507 else if (! strcmp (language_string, "GNU Pascal"))
21509 else if (! strcmp (language_string, "GNU Ada"))
21511 else if (! strcmp (language_string, "GNU C++")
21512 || ! strcmp (language_string, "GNU Objective-C++"))
21514 else if (! strcmp (language_string, "GNU Java"))
21516 else if (! strcmp (language_string, "GNU Objective-C"))
21519 gcc_unreachable ();
21520 fprintf (file, "%d,", i);
21522 /* 8 single bit fields: global linkage (not set for C extern linkage,
21523 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
21524 from start of procedure stored in tbtab, internal function, function
21525 has controlled storage, function has no toc, function uses fp,
21526 function logs/aborts fp operations. */
21527 /* Assume that fp operations are used if any fp reg must be saved. */
21528 fprintf (file, "%d,",
21529 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
21531 /* 6 bitfields: function is interrupt handler, name present in
21532 proc table, function calls alloca, on condition directives
21533 (controls stack walks, 3 bits), saves condition reg, saves
21535 /* The `function calls alloca' bit seems to be set whenever reg 31 is
21536 set up as a frame pointer, even when there is no alloca call. */
21537 fprintf (file, "%d,",
21538 ((optional_tbtab << 6)
21539 | ((optional_tbtab & frame_pointer_needed) << 5)
21540 | (info->cr_save_p << 1)
21541 | (info->lr_save_p)));
21543 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
21545 fprintf (file, "%d,",
21546 (info->push_p << 7) | (64 - info->first_fp_reg_save));
21548 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
21549 fprintf (file, "%d,", (32 - first_reg_to_save ()));
21551 if (optional_tbtab)
21553 /* Compute the parameter info from the function decl argument
21556 int next_parm_info_bit = 31;
21558 for (decl = DECL_ARGUMENTS (current_function_decl);
21559 decl; decl = DECL_CHAIN (decl))
21561 rtx parameter = DECL_INCOMING_RTL (decl);
21562 enum machine_mode mode = GET_MODE (parameter);
21564 if (GET_CODE (parameter) == REG)
21566 if (SCALAR_FLOAT_MODE_P (mode))
21587 gcc_unreachable ();
21590 /* If only one bit will fit, don't or in this entry. */
21591 if (next_parm_info_bit > 0)
21592 parm_info |= (bits << (next_parm_info_bit - 1));
21593 next_parm_info_bit -= 2;
21597 fixed_parms += ((GET_MODE_SIZE (mode)
21598 + (UNITS_PER_WORD - 1))
21600 next_parm_info_bit -= 1;
21606 /* Number of fixed point parameters. */
21607 /* This is actually the number of words of fixed point parameters; thus
21608 an 8 byte struct counts as 2; and thus the maximum value is 8. */
21609 fprintf (file, "%d,", fixed_parms);
21611 /* 2 bitfields: number of floating point parameters (7 bits), parameters
21613 /* This is actually the number of fp registers that hold parameters;
21614 and thus the maximum value is 13. */
21615 /* Set parameters on stack bit if parameters are not in their original
21616 registers, regardless of whether they are on the stack? Xlc
21617 seems to set the bit when not optimizing. */
21618 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
21620 if (! optional_tbtab)
21623 /* Optional fields follow. Some are variable length. */
21625 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
21626 11 double float. */
21627 /* There is an entry for each parameter in a register, in the order that
21628 they occur in the parameter list. Any intervening arguments on the
21629 stack are ignored. If the list overflows a long (max possible length
21630 34 bits) then completely leave off all elements that don't fit. */
21631 /* Only emit this long if there was at least one parameter. */
21632 if (fixed_parms || float_parms)
21633 fprintf (file, "\t.long %d\n", parm_info);
21635 /* Offset from start of code to tb table. */
21636 fputs ("\t.long ", file);
21637 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
21638 RS6000_OUTPUT_BASENAME (file, fname);
21640 rs6000_output_function_entry (file, fname);
21643 /* Interrupt handler mask. */
21644 /* Omit this long, since we never set the interrupt handler bit
21647 /* Number of CTL (controlled storage) anchors. */
21648 /* Omit this long, since the has_ctl bit is never set above. */
21650 /* Displacement into stack of each CTL anchor. */
21651 /* Omit this list of longs, because there are no CTL anchors. */
21653 /* Length of function name. */
21656 fprintf (file, "\t.short %d\n", (int) strlen (fname));
21658 /* Function name. */
21659 assemble_string (fname, strlen (fname));
21661 /* Register for alloca automatic storage; this is always reg 31.
21662 Only emit this if the alloca bit was set above. */
21663 if (frame_pointer_needed)
21664 fputs ("\t.byte 31\n", file);
21666 fputs ("\t.align 2\n", file);
21670 /* A C compound statement that outputs the assembler code for a thunk
21671 function, used to implement C++ virtual function calls with
21672 multiple inheritance. The thunk acts as a wrapper around a virtual
21673 function, adjusting the implicit object parameter before handing
21674 control off to the real function.
21676 First, emit code to add the integer DELTA to the location that
21677 contains the incoming first argument. Assume that this argument
21678 contains a pointer, and is the one used to pass the `this' pointer
21679 in C++. This is the incoming argument *before* the function
21680 prologue, e.g. `%o0' on a sparc. The addition must preserve the
21681 values of all other incoming arguments.
21683 After the addition, emit code to jump to FUNCTION, which is a
21684 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
21685 not touch the return address. Hence returning from FUNCTION will
21686 return to whoever called the current `thunk'.
21688 The effect must be as if FUNCTION had been called directly with the
21689 adjusted first argument. This macro is responsible for emitting
21690 all of the code for a thunk function; output_function_prologue()
21691 and output_function_epilogue() are not invoked.
21693 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
21694 been extracted from it.) It might possibly be useful on some
21695 targets, but probably not.
21697 If you do not define this macro, the target-independent code in the
21698 C++ frontend will generate a less efficient heavyweight thunk that
21699 calls FUNCTION instead of jumping to it. The generic approach does
21700 not support varargs. */
21703 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
21704 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
21707 rtx this_rtx, insn, funexp;
21709 reload_completed = 1;
21710 epilogue_completed = 1;
21712 /* Mark the end of the (empty) prologue. */
21713 emit_note (NOTE_INSN_PROLOGUE_END);
21715 /* Find the "this" pointer. If the function returns a structure,
21716 the structure return pointer is in r3. */
21717 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
21718 this_rtx = gen_rtx_REG (Pmode, 4);
21720 this_rtx = gen_rtx_REG (Pmode, 3);
21722 /* Apply the constant offset, if required. */
21724 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
21726 /* Apply the offset from the vtable, if required. */
21729 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
21730 rtx tmp = gen_rtx_REG (Pmode, 12);
21732 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
21733 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
21735 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
21736 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
21740 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
21742 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
21744 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
21747 /* Generate a tail call to the target function. */
21748 if (!TREE_USED (function))
21750 assemble_external (function);
21751 TREE_USED (function) = 1;
21753 funexp = XEXP (DECL_RTL (function), 0);
21754 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
21757 if (MACHOPIC_INDIRECT)
21758 funexp = machopic_indirect_call_target (funexp);
21761 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
21762 generate sibcall RTL explicitly. */
21763 insn = emit_call_insn (
21764 gen_rtx_PARALLEL (VOIDmode,
21766 gen_rtx_CALL (VOIDmode,
21767 funexp, const0_rtx),
21768 gen_rtx_USE (VOIDmode, const0_rtx),
21769 gen_rtx_USE (VOIDmode,
21770 gen_rtx_REG (SImode,
21773 SIBLING_CALL_P (insn) = 1;
21776 /* Run just enough of rest_of_compilation to get the insns emitted.
21777 There's not really enough bulk here to make other passes such as
21778 instruction scheduling worth while. Note that use_thunk calls
21779 assemble_start_function and assemble_end_function. */
21780 insn = get_insns ();
21781 insn_locators_alloc ();
21782 shorten_branches (insn);
21783 final_start_function (insn, file, 1);
21784 final (insn, file, 1);
21785 final_end_function ();
21787 reload_completed = 0;
21788 epilogue_completed = 0;
21791 /* A quick summary of the various types of 'constant-pool tables'
21794 Target Flags Name One table per
21795 AIX (none) AIX TOC object file
21796 AIX -mfull-toc AIX TOC object file
21797 AIX -mminimal-toc AIX minimal TOC translation unit
21798 SVR4/EABI (none) SVR4 SDATA object file
21799 SVR4/EABI -fpic SVR4 pic object file
21800 SVR4/EABI -fPIC SVR4 PIC translation unit
21801 SVR4/EABI -mrelocatable EABI TOC function
21802 SVR4/EABI -maix AIX TOC object file
21803 SVR4/EABI -maix -mminimal-toc
21804 AIX minimal TOC translation unit
21806 Name Reg. Set by entries contains:
21807 made by addrs? fp? sum?
21809 AIX TOC 2 crt0 as Y option option
21810 AIX minimal TOC 30 prolog gcc Y Y option
21811 SVR4 SDATA 13 crt0 gcc N Y N
21812 SVR4 pic 30 prolog ld Y not yet N
21813 SVR4 PIC 30 prolog gcc Y option option
21814 EABI TOC 30 prolog gcc Y option option
21818 /* Hash functions for the hash table. */
21821 rs6000_hash_constant (rtx k)
21823 enum rtx_code code = GET_CODE (k);
21824 enum machine_mode mode = GET_MODE (k);
21825 unsigned result = (code << 3) ^ mode;
21826 const char *format;
21829 format = GET_RTX_FORMAT (code);
21830 flen = strlen (format);
21836 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
21839 if (mode != VOIDmode)
21840 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
21852 for (; fidx < flen; fidx++)
21853 switch (format[fidx])
21858 const char *str = XSTR (k, fidx);
21859 len = strlen (str);
21860 result = result * 613 + len;
21861 for (i = 0; i < len; i++)
21862 result = result * 613 + (unsigned) str[i];
21867 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
21871 result = result * 613 + (unsigned) XINT (k, fidx);
21874 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
21875 result = result * 613 + (unsigned) XWINT (k, fidx);
21879 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
21880 result = result * 613 + (unsigned) (XWINT (k, fidx)
21887 gcc_unreachable ();
21894 toc_hash_function (const void *hash_entry)
21896 const struct toc_hash_struct *thc =
21897 (const struct toc_hash_struct *) hash_entry;
21898 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
21901 /* Compare H1 and H2 for equivalence. */
21904 toc_hash_eq (const void *h1, const void *h2)
21906 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
21907 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
21909 if (((const struct toc_hash_struct *) h1)->key_mode
21910 != ((const struct toc_hash_struct *) h2)->key_mode)
21913 return rtx_equal_p (r1, r2);
21916 /* These are the names given by the C++ front-end to vtables, and
21917 vtable-like objects. Ideally, this logic should not be here;
21918 instead, there should be some programmatic way of inquiring as
21919 to whether or not an object is a vtable. */
21921 #define VTABLE_NAME_P(NAME) \
21922 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
21923 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
21924 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
21925 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
21926 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
21928 #ifdef NO_DOLLAR_IN_LABEL
21929 /* Return a GGC-allocated character string translating dollar signs in
21930 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
21933 rs6000_xcoff_strip_dollar (const char *name)
21939 q = (const char *) strchr (name, '$');
21941 if (q == 0 || q == name)
21944 len = strlen (name);
21945 strip = XALLOCAVEC (char, len + 1);
21946 strcpy (strip, name);
21947 p = strip + (q - name);
21951 p = strchr (p + 1, '$');
21954 return ggc_alloc_string (strip, len);
21959 rs6000_output_symbol_ref (FILE *file, rtx x)
21961 /* Currently C++ toc references to vtables can be emitted before it
21962 is decided whether the vtable is public or private. If this is
21963 the case, then the linker will eventually complain that there is
21964 a reference to an unknown section. Thus, for vtables only,
21965 we emit the TOC reference to reference the symbol and not the
21967 const char *name = XSTR (x, 0);
21969 if (VTABLE_NAME_P (name))
21971 RS6000_OUTPUT_BASENAME (file, name);
21974 assemble_name (file, name);
21977 /* Output a TOC entry. We derive the entry name from what is being
21981 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
21984 const char *name = buf;
21986 HOST_WIDE_INT offset = 0;
21988 gcc_assert (!TARGET_NO_TOC);
21990 /* When the linker won't eliminate them, don't output duplicate
21991 TOC entries (this happens on AIX if there is any kind of TOC,
21992 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
21994 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
21996 struct toc_hash_struct *h;
21999 /* Create toc_hash_table. This can't be done at TARGET_OPTION_OVERRIDE
22000 time because GGC is not initialized at that point. */
22001 if (toc_hash_table == NULL)
22002 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
22003 toc_hash_eq, NULL);
22005 h = ggc_alloc_toc_hash_struct ();
22007 h->key_mode = mode;
22008 h->labelno = labelno;
22010 found = htab_find_slot (toc_hash_table, h, INSERT);
22011 if (*found == NULL)
22013 else /* This is indeed a duplicate.
22014 Set this label equal to that label. */
22016 fputs ("\t.set ", file);
22017 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22018 fprintf (file, "%d,", labelno);
22019 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22020 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
22026 /* If we're going to put a double constant in the TOC, make sure it's
22027 aligned properly when strict alignment is on. */
22028 if (GET_CODE (x) == CONST_DOUBLE
22029 && STRICT_ALIGNMENT
22030 && GET_MODE_BITSIZE (mode) >= 64
22031 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
22032 ASM_OUTPUT_ALIGN (file, 3);
22035 (*targetm.asm_out.internal_label) (file, "LC", labelno);
22037 /* Handle FP constants specially. Note that if we have a minimal
22038 TOC, things we put here aren't actually in the TOC, so we can allow
22040 if (GET_CODE (x) == CONST_DOUBLE &&
22041 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
22043 REAL_VALUE_TYPE rv;
22046 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22047 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22048 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
22050 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
22054 if (TARGET_MINIMAL_TOC)
22055 fputs (DOUBLE_INT_ASM_OP, file);
22057 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22058 k[0] & 0xffffffff, k[1] & 0xffffffff,
22059 k[2] & 0xffffffff, k[3] & 0xffffffff);
22060 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
22061 k[0] & 0xffffffff, k[1] & 0xffffffff,
22062 k[2] & 0xffffffff, k[3] & 0xffffffff);
22067 if (TARGET_MINIMAL_TOC)
22068 fputs ("\t.long ", file);
22070 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22071 k[0] & 0xffffffff, k[1] & 0xffffffff,
22072 k[2] & 0xffffffff, k[3] & 0xffffffff);
22073 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
22074 k[0] & 0xffffffff, k[1] & 0xffffffff,
22075 k[2] & 0xffffffff, k[3] & 0xffffffff);
22079 else if (GET_CODE (x) == CONST_DOUBLE &&
22080 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
22082 REAL_VALUE_TYPE rv;
22085 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22087 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22088 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
22090 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
22094 if (TARGET_MINIMAL_TOC)
22095 fputs (DOUBLE_INT_ASM_OP, file);
22097 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22098 k[0] & 0xffffffff, k[1] & 0xffffffff);
22099 fprintf (file, "0x%lx%08lx\n",
22100 k[0] & 0xffffffff, k[1] & 0xffffffff);
22105 if (TARGET_MINIMAL_TOC)
22106 fputs ("\t.long ", file);
22108 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22109 k[0] & 0xffffffff, k[1] & 0xffffffff);
22110 fprintf (file, "0x%lx,0x%lx\n",
22111 k[0] & 0xffffffff, k[1] & 0xffffffff);
22115 else if (GET_CODE (x) == CONST_DOUBLE &&
22116 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
22118 REAL_VALUE_TYPE rv;
22121 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22122 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22123 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
22125 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
22129 if (TARGET_MINIMAL_TOC)
22130 fputs (DOUBLE_INT_ASM_OP, file);
22132 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22133 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
22138 if (TARGET_MINIMAL_TOC)
22139 fputs ("\t.long ", file);
22141 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22142 fprintf (file, "0x%lx\n", l & 0xffffffff);
22146 else if (GET_MODE (x) == VOIDmode
22147 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
22149 unsigned HOST_WIDE_INT low;
22150 HOST_WIDE_INT high;
22152 if (GET_CODE (x) == CONST_DOUBLE)
22154 low = CONST_DOUBLE_LOW (x);
22155 high = CONST_DOUBLE_HIGH (x);
22158 #if HOST_BITS_PER_WIDE_INT == 32
22161 high = (low & 0x80000000) ? ~0 : 0;
22165 low = INTVAL (x) & 0xffffffff;
22166 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
22170 /* TOC entries are always Pmode-sized, but since this
22171 is a bigendian machine then if we're putting smaller
22172 integer constants in the TOC we have to pad them.
22173 (This is still a win over putting the constants in
22174 a separate constant pool, because then we'd have
22175 to have both a TOC entry _and_ the actual constant.)
22177 For a 32-bit target, CONST_INT values are loaded and shifted
22178 entirely within `low' and can be stored in one TOC entry. */
22180 /* It would be easy to make this work, but it doesn't now. */
22181 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
22183 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
22185 #if HOST_BITS_PER_WIDE_INT == 32
22186 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
22187 POINTER_SIZE, &low, &high, 0);
22190 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
22191 high = (HOST_WIDE_INT) low >> 32;
22198 if (TARGET_MINIMAL_TOC)
22199 fputs (DOUBLE_INT_ASM_OP, file);
22201 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22202 (long) high & 0xffffffff, (long) low & 0xffffffff);
22203 fprintf (file, "0x%lx%08lx\n",
22204 (long) high & 0xffffffff, (long) low & 0xffffffff);
22209 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
22211 if (TARGET_MINIMAL_TOC)
22212 fputs ("\t.long ", file);
22214 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22215 (long) high & 0xffffffff, (long) low & 0xffffffff);
22216 fprintf (file, "0x%lx,0x%lx\n",
22217 (long) high & 0xffffffff, (long) low & 0xffffffff);
22221 if (TARGET_MINIMAL_TOC)
22222 fputs ("\t.long ", file);
22224 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
22225 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
22231 if (GET_CODE (x) == CONST)
22233 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
22234 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
22236 base = XEXP (XEXP (x, 0), 0);
22237 offset = INTVAL (XEXP (XEXP (x, 0), 1));
22240 switch (GET_CODE (base))
22243 name = XSTR (base, 0);
22247 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
22248 CODE_LABEL_NUMBER (XEXP (base, 0)));
22252 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
22256 gcc_unreachable ();
22259 if (TARGET_MINIMAL_TOC)
22260 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
22263 fputs ("\t.tc ", file);
22264 RS6000_OUTPUT_BASENAME (file, name);
22267 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
22269 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
22271 fputs ("[TC],", file);
22274 /* Currently C++ toc references to vtables can be emitted before it
22275 is decided whether the vtable is public or private. If this is
22276 the case, then the linker will eventually complain that there is
22277 a TOC reference to an unknown section. Thus, for vtables only,
22278 we emit the TOC reference to reference the symbol and not the
22280 if (VTABLE_NAME_P (name))
22282 RS6000_OUTPUT_BASENAME (file, name);
22284 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
22285 else if (offset > 0)
22286 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
22289 output_addr_const (file, x);
22293 /* Output an assembler pseudo-op to write an ASCII string of N characters
22294 starting at P to FILE.
22296 On the RS/6000, we have to do this using the .byte operation and
22297 write out special characters outside the quoted string.
22298 Also, the assembler is broken; very long strings are truncated,
22299 so we must artificially break them up early. */
22302 output_ascii (FILE *file, const char *p, int n)
22305 int i, count_string;
22306 const char *for_string = "\t.byte \"";
22307 const char *for_decimal = "\t.byte ";
22308 const char *to_close = NULL;
22311 for (i = 0; i < n; i++)
22314 if (c >= ' ' && c < 0177)
22317 fputs (for_string, file);
22320 /* Write two quotes to get one. */
22328 for_decimal = "\"\n\t.byte ";
22332 if (count_string >= 512)
22334 fputs (to_close, file);
22336 for_string = "\t.byte \"";
22337 for_decimal = "\t.byte ";
22345 fputs (for_decimal, file);
22346 fprintf (file, "%d", c);
22348 for_string = "\n\t.byte \"";
22349 for_decimal = ", ";
22355 /* Now close the string if we have written one. Then end the line. */
22357 fputs (to_close, file);
22360 /* Generate a unique section name for FILENAME for a section type
22361 represented by SECTION_DESC. Output goes into BUF.
22363 SECTION_DESC can be any string, as long as it is different for each
22364 possible section type.
22366 We name the section in the same manner as xlc. The name begins with an
22367 underscore followed by the filename (after stripping any leading directory
22368 names) with the last period replaced by the string SECTION_DESC. If
22369 FILENAME does not contain a period, SECTION_DESC is appended to the end of
22373 rs6000_gen_section_name (char **buf, const char *filename,
22374 const char *section_desc)
22376 const char *q, *after_last_slash, *last_period = 0;
22380 after_last_slash = filename;
22381 for (q = filename; *q; q++)
22384 after_last_slash = q + 1;
22385 else if (*q == '.')
22389 len = strlen (after_last_slash) + strlen (section_desc) + 2;
22390 *buf = (char *) xmalloc (len);
22395 for (q = after_last_slash; *q; q++)
22397 if (q == last_period)
22399 strcpy (p, section_desc);
22400 p += strlen (section_desc);
22404 else if (ISALNUM (*q))
22408 if (last_period == 0)
22409 strcpy (p, section_desc);
22414 /* Emit profile function. */
22417 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
22419 /* Non-standard profiling for kernels, which just saves LR then calls
22420 _mcount without worrying about arg saves. The idea is to change
22421 the function prologue as little as possible as it isn't easy to
22422 account for arg save/restore code added just for _mcount. */
22423 if (TARGET_PROFILE_KERNEL)
22426 if (DEFAULT_ABI == ABI_AIX)
22428 #ifndef NO_PROFILE_COUNTERS
22429 # define NO_PROFILE_COUNTERS 0
22431 if (NO_PROFILE_COUNTERS)
22432 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22433 LCT_NORMAL, VOIDmode, 0);
22437 const char *label_name;
22440 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
22441 label_name = ggc_strdup ((*targetm.strip_name_encoding) (buf));
22442 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
22444 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22445 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
22448 else if (DEFAULT_ABI == ABI_DARWIN)
22450 const char *mcount_name = RS6000_MCOUNT;
22451 int caller_addr_regno = LR_REGNO;
22453 /* Be conservative and always set this, at least for now. */
22454 crtl->uses_pic_offset_table = 1;
22457 /* For PIC code, set up a stub and collect the caller's address
22458 from r0, which is where the prologue puts it. */
22459 if (MACHOPIC_INDIRECT
22460 && crtl->uses_pic_offset_table)
22461 caller_addr_regno = 0;
22463 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
22464 LCT_NORMAL, VOIDmode, 1,
22465 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
22469 /* Write function profiler code. */
22472 output_function_profiler (FILE *file, int labelno)
22476 switch (DEFAULT_ABI)
22479 gcc_unreachable ();
22484 warning (0, "no profiling of 64-bit code for this ABI");
22487 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
22488 fprintf (file, "\tmflr %s\n", reg_names[0]);
22489 if (NO_PROFILE_COUNTERS)
22491 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22492 reg_names[0], reg_names[1]);
22494 else if (TARGET_SECURE_PLT && flag_pic)
22496 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
22497 reg_names[0], reg_names[1]);
22498 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
22499 asm_fprintf (file, "\t{cau|addis} %s,%s,",
22500 reg_names[12], reg_names[12]);
22501 assemble_name (file, buf);
22502 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
22503 assemble_name (file, buf);
22504 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
22506 else if (flag_pic == 1)
22508 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
22509 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22510 reg_names[0], reg_names[1]);
22511 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
22512 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
22513 assemble_name (file, buf);
22514 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
22516 else if (flag_pic > 1)
22518 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22519 reg_names[0], reg_names[1]);
22520 /* Now, we need to get the address of the label. */
22521 fputs ("\tbcl 20,31,1f\n\t.long ", file);
22522 assemble_name (file, buf);
22523 fputs ("-.\n1:", file);
22524 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
22525 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
22526 reg_names[0], reg_names[11]);
22527 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
22528 reg_names[0], reg_names[0], reg_names[11]);
22532 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
22533 assemble_name (file, buf);
22534 fputs ("@ha\n", file);
22535 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22536 reg_names[0], reg_names[1]);
22537 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
22538 assemble_name (file, buf);
22539 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
22542 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
22543 fprintf (file, "\tbl %s%s\n",
22544 RS6000_MCOUNT, flag_pic ? "@plt" : "");
22549 if (!TARGET_PROFILE_KERNEL)
22551 /* Don't do anything, done in output_profile_hook (). */
22555 gcc_assert (!TARGET_32BIT);
22557 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
22558 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
22560 if (cfun->static_chain_decl != NULL)
22562 asm_fprintf (file, "\tstd %s,24(%s)\n",
22563 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
22564 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
22565 asm_fprintf (file, "\tld %s,24(%s)\n",
22566 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
22569 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
22577 /* The following variable value is the last issued insn. */
22579 static rtx last_scheduled_insn;
22581 /* The following variable helps to balance issuing of load and
22582 store instructions */
22584 static int load_store_pendulum;
22586 /* Power4 load update and store update instructions are cracked into a
22587 load or store and an integer insn which are executed in the same cycle.
22588 Branches have their own dispatch slot which does not count against the
22589 GCC issue rate, but it changes the program flow so there are no other
22590 instructions to issue in this cycle. */
22593 rs6000_variable_issue_1 (rtx insn, int more)
22595 last_scheduled_insn = insn;
22596 if (GET_CODE (PATTERN (insn)) == USE
22597 || GET_CODE (PATTERN (insn)) == CLOBBER)
22599 cached_can_issue_more = more;
22600 return cached_can_issue_more;
22603 if (insn_terminates_group_p (insn, current_group))
22605 cached_can_issue_more = 0;
22606 return cached_can_issue_more;
22609 /* If no reservation, but reach here */
22610 if (recog_memoized (insn) < 0)
22613 if (rs6000_sched_groups)
22615 if (is_microcoded_insn (insn))
22616 cached_can_issue_more = 0;
22617 else if (is_cracked_insn (insn))
22618 cached_can_issue_more = more > 2 ? more - 2 : 0;
22620 cached_can_issue_more = more - 1;
22622 return cached_can_issue_more;
22625 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
22628 cached_can_issue_more = more - 1;
22629 return cached_can_issue_more;
22633 rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more)
22635 int r = rs6000_variable_issue_1 (insn, more);
22637 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r);
22641 /* Adjust the cost of a scheduling dependency. Return the new cost of
22642 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
22645 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
22647 enum attr_type attr_type;
22649 if (! recog_memoized (insn))
22652 switch (REG_NOTE_KIND (link))
22656 /* Data dependency; DEP_INSN writes a register that INSN reads
22657 some cycles later. */
22659 /* Separate a load from a narrower, dependent store. */
22660 if (rs6000_sched_groups
22661 && GET_CODE (PATTERN (insn)) == SET
22662 && GET_CODE (PATTERN (dep_insn)) == SET
22663 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
22664 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
22665 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
22666 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
22669 attr_type = get_attr_type (insn);
22674 /* Tell the first scheduling pass about the latency between
22675 a mtctr and bctr (and mtlr and br/blr). The first
22676 scheduling pass will not know about this latency since
22677 the mtctr instruction, which has the latency associated
22678 to it, will be generated by reload. */
22679 return TARGET_POWER ? 5 : 4;
22681 /* Leave some extra cycles between a compare and its
22682 dependent branch, to inhibit expensive mispredicts. */
22683 if ((rs6000_cpu_attr == CPU_PPC603
22684 || rs6000_cpu_attr == CPU_PPC604
22685 || rs6000_cpu_attr == CPU_PPC604E
22686 || rs6000_cpu_attr == CPU_PPC620
22687 || rs6000_cpu_attr == CPU_PPC630
22688 || rs6000_cpu_attr == CPU_PPC750
22689 || rs6000_cpu_attr == CPU_PPC7400
22690 || rs6000_cpu_attr == CPU_PPC7450
22691 || rs6000_cpu_attr == CPU_POWER4
22692 || rs6000_cpu_attr == CPU_POWER5
22693 || rs6000_cpu_attr == CPU_POWER7
22694 || rs6000_cpu_attr == CPU_CELL)
22695 && recog_memoized (dep_insn)
22696 && (INSN_CODE (dep_insn) >= 0))
22698 switch (get_attr_type (dep_insn))
22702 case TYPE_DELAYED_COMPARE:
22703 case TYPE_IMUL_COMPARE:
22704 case TYPE_LMUL_COMPARE:
22705 case TYPE_FPCOMPARE:
22706 case TYPE_CR_LOGICAL:
22707 case TYPE_DELAYED_CR:
22716 case TYPE_STORE_UX:
22718 case TYPE_FPSTORE_U:
22719 case TYPE_FPSTORE_UX:
22720 if ((rs6000_cpu == PROCESSOR_POWER6)
22721 && recog_memoized (dep_insn)
22722 && (INSN_CODE (dep_insn) >= 0))
22725 if (GET_CODE (PATTERN (insn)) != SET)
22726 /* If this happens, we have to extend this to schedule
22727 optimally. Return default for now. */
22730 /* Adjust the cost for the case where the value written
22731 by a fixed point operation is used as the address
22732 gen value on a store. */
22733 switch (get_attr_type (dep_insn))
22740 if (! store_data_bypass_p (dep_insn, insn))
22744 case TYPE_LOAD_EXT:
22745 case TYPE_LOAD_EXT_U:
22746 case TYPE_LOAD_EXT_UX:
22747 case TYPE_VAR_SHIFT_ROTATE:
22748 case TYPE_VAR_DELAYED_COMPARE:
22750 if (! store_data_bypass_p (dep_insn, insn))
22756 case TYPE_FAST_COMPARE:
22759 case TYPE_INSERT_WORD:
22760 case TYPE_INSERT_DWORD:
22761 case TYPE_FPLOAD_U:
22762 case TYPE_FPLOAD_UX:
22764 case TYPE_STORE_UX:
22765 case TYPE_FPSTORE_U:
22766 case TYPE_FPSTORE_UX:
22768 if (! store_data_bypass_p (dep_insn, insn))
22776 case TYPE_IMUL_COMPARE:
22777 case TYPE_LMUL_COMPARE:
22779 if (! store_data_bypass_p (dep_insn, insn))
22785 if (! store_data_bypass_p (dep_insn, insn))
22791 if (! store_data_bypass_p (dep_insn, insn))
22804 case TYPE_LOAD_EXT:
22805 case TYPE_LOAD_EXT_U:
22806 case TYPE_LOAD_EXT_UX:
22807 if ((rs6000_cpu == PROCESSOR_POWER6)
22808 && recog_memoized (dep_insn)
22809 && (INSN_CODE (dep_insn) >= 0))
22812 /* Adjust the cost for the case where the value written
22813 by a fixed point instruction is used within the address
22814 gen portion of a subsequent load(u)(x) */
22815 switch (get_attr_type (dep_insn))
22822 if (set_to_load_agen (dep_insn, insn))
22826 case TYPE_LOAD_EXT:
22827 case TYPE_LOAD_EXT_U:
22828 case TYPE_LOAD_EXT_UX:
22829 case TYPE_VAR_SHIFT_ROTATE:
22830 case TYPE_VAR_DELAYED_COMPARE:
22832 if (set_to_load_agen (dep_insn, insn))
22838 case TYPE_FAST_COMPARE:
22841 case TYPE_INSERT_WORD:
22842 case TYPE_INSERT_DWORD:
22843 case TYPE_FPLOAD_U:
22844 case TYPE_FPLOAD_UX:
22846 case TYPE_STORE_UX:
22847 case TYPE_FPSTORE_U:
22848 case TYPE_FPSTORE_UX:
22850 if (set_to_load_agen (dep_insn, insn))
22858 case TYPE_IMUL_COMPARE:
22859 case TYPE_LMUL_COMPARE:
22861 if (set_to_load_agen (dep_insn, insn))
22867 if (set_to_load_agen (dep_insn, insn))
22873 if (set_to_load_agen (dep_insn, insn))
22884 if ((rs6000_cpu == PROCESSOR_POWER6)
22885 && recog_memoized (dep_insn)
22886 && (INSN_CODE (dep_insn) >= 0)
22887 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
22894 /* Fall out to return default cost. */
22898 case REG_DEP_OUTPUT:
22899 /* Output dependency; DEP_INSN writes a register that INSN writes some
22901 if ((rs6000_cpu == PROCESSOR_POWER6)
22902 && recog_memoized (dep_insn)
22903 && (INSN_CODE (dep_insn) >= 0))
22905 attr_type = get_attr_type (insn);
22910 if (get_attr_type (dep_insn) == TYPE_FP)
22914 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
22922 /* Anti dependency; DEP_INSN reads a register that INSN writes some
22927 gcc_unreachable ();
22933 /* Debug version of rs6000_adjust_cost. */
22936 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
22938 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
22944 switch (REG_NOTE_KIND (link))
22946 default: dep = "unknown depencency"; break;
22947 case REG_DEP_TRUE: dep = "data dependency"; break;
22948 case REG_DEP_OUTPUT: dep = "output dependency"; break;
22949 case REG_DEP_ANTI: dep = "anti depencency"; break;
22953 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
22954 "%s, insn:\n", ret, cost, dep);
22962 /* The function returns a true if INSN is microcoded.
22963 Return false otherwise. */
22966 is_microcoded_insn (rtx insn)
22968 if (!insn || !NONDEBUG_INSN_P (insn)
22969 || GET_CODE (PATTERN (insn)) == USE
22970 || GET_CODE (PATTERN (insn)) == CLOBBER)
22973 if (rs6000_cpu_attr == CPU_CELL)
22974 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
22976 if (rs6000_sched_groups)
22978 enum attr_type type = get_attr_type (insn);
22979 if (type == TYPE_LOAD_EXT_U
22980 || type == TYPE_LOAD_EXT_UX
22981 || type == TYPE_LOAD_UX
22982 || type == TYPE_STORE_UX
22983 || type == TYPE_MFCR)
22990 /* The function returns true if INSN is cracked into 2 instructions
22991 by the processor (and therefore occupies 2 issue slots). */
22994 is_cracked_insn (rtx insn)
22996 if (!insn || !NONDEBUG_INSN_P (insn)
22997 || GET_CODE (PATTERN (insn)) == USE
22998 || GET_CODE (PATTERN (insn)) == CLOBBER)
23001 if (rs6000_sched_groups)
23003 enum attr_type type = get_attr_type (insn);
23004 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
23005 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
23006 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
23007 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
23008 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
23009 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
23010 || type == TYPE_IDIV || type == TYPE_LDIV
23011 || type == TYPE_INSERT_WORD)
23018 /* The function returns true if INSN can be issued only from
23019 the branch slot. */
23022 is_branch_slot_insn (rtx insn)
23024 if (!insn || !NONDEBUG_INSN_P (insn)
23025 || GET_CODE (PATTERN (insn)) == USE
23026 || GET_CODE (PATTERN (insn)) == CLOBBER)
23029 if (rs6000_sched_groups)
23031 enum attr_type type = get_attr_type (insn);
23032 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
23040 /* The function returns true if out_inst sets a value that is
23041 used in the address generation computation of in_insn */
23043 set_to_load_agen (rtx out_insn, rtx in_insn)
23045 rtx out_set, in_set;
23047 /* For performance reasons, only handle the simple case where
23048 both loads are a single_set. */
23049 out_set = single_set (out_insn);
23052 in_set = single_set (in_insn);
23054 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
23060 /* The function returns true if the target storage location of
23061 out_insn is adjacent to the target storage location of in_insn */
23062 /* Return 1 if memory locations are adjacent. */
23065 adjacent_mem_locations (rtx insn1, rtx insn2)
23068 rtx a = get_store_dest (PATTERN (insn1));
23069 rtx b = get_store_dest (PATTERN (insn2));
23071 if ((GET_CODE (XEXP (a, 0)) == REG
23072 || (GET_CODE (XEXP (a, 0)) == PLUS
23073 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
23074 && (GET_CODE (XEXP (b, 0)) == REG
23075 || (GET_CODE (XEXP (b, 0)) == PLUS
23076 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
23078 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
23081 if (GET_CODE (XEXP (a, 0)) == PLUS)
23083 reg0 = XEXP (XEXP (a, 0), 0);
23084 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
23087 reg0 = XEXP (a, 0);
23089 if (GET_CODE (XEXP (b, 0)) == PLUS)
23091 reg1 = XEXP (XEXP (b, 0), 0);
23092 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
23095 reg1 = XEXP (b, 0);
23097 val_diff = val1 - val0;
23099 return ((REGNO (reg0) == REGNO (reg1))
23100 && ((MEM_SIZE_KNOWN_P (a) && val_diff == MEM_SIZE (a))
23101 || (MEM_SIZE_KNOWN_P (b) && val_diff == -MEM_SIZE (b))));
23107 /* A C statement (sans semicolon) to update the integer scheduling
23108 priority INSN_PRIORITY (INSN). Increase the priority to execute the
23109 INSN earlier, reduce the priority to execute INSN later. Do not
23110 define this macro if you do not need to adjust the scheduling
23111 priorities of insns. */
23114 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
23116 /* On machines (like the 750) which have asymmetric integer units,
23117 where one integer unit can do multiply and divides and the other
23118 can't, reduce the priority of multiply/divide so it is scheduled
23119 before other integer operations. */
23122 if (! INSN_P (insn))
23125 if (GET_CODE (PATTERN (insn)) == USE)
23128 switch (rs6000_cpu_attr) {
23130 switch (get_attr_type (insn))
23137 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
23138 priority, priority);
23139 if (priority >= 0 && priority < 0x01000000)
23146 if (insn_must_be_first_in_group (insn)
23147 && reload_completed
23148 && current_sched_info->sched_max_insns_priority
23149 && rs6000_sched_restricted_insns_priority)
23152 /* Prioritize insns that can be dispatched only in the first
23154 if (rs6000_sched_restricted_insns_priority == 1)
23155 /* Attach highest priority to insn. This means that in
23156 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
23157 precede 'priority' (critical path) considerations. */
23158 return current_sched_info->sched_max_insns_priority;
23159 else if (rs6000_sched_restricted_insns_priority == 2)
23160 /* Increase priority of insn by a minimal amount. This means that in
23161 haifa-sched.c:ready_sort(), only 'priority' (critical path)
23162 considerations precede dispatch-slot restriction considerations. */
23163 return (priority + 1);
23166 if (rs6000_cpu == PROCESSOR_POWER6
23167 && ((load_store_pendulum == -2 && is_load_insn (insn))
23168 || (load_store_pendulum == 2 && is_store_insn (insn))))
23169 /* Attach highest priority to insn if the scheduler has just issued two
23170 stores and this instruction is a load, or two loads and this instruction
23171 is a store. Power6 wants loads and stores scheduled alternately
23173 return current_sched_info->sched_max_insns_priority;
23178 /* Return true if the instruction is nonpipelined on the Cell. */
23180 is_nonpipeline_insn (rtx insn)
23182 enum attr_type type;
23183 if (!insn || !NONDEBUG_INSN_P (insn)
23184 || GET_CODE (PATTERN (insn)) == USE
23185 || GET_CODE (PATTERN (insn)) == CLOBBER)
23188 type = get_attr_type (insn);
23189 if (type == TYPE_IMUL
23190 || type == TYPE_IMUL2
23191 || type == TYPE_IMUL3
23192 || type == TYPE_LMUL
23193 || type == TYPE_IDIV
23194 || type == TYPE_LDIV
23195 || type == TYPE_SDIV
23196 || type == TYPE_DDIV
23197 || type == TYPE_SSQRT
23198 || type == TYPE_DSQRT
23199 || type == TYPE_MFCR
23200 || type == TYPE_MFCRF
23201 || type == TYPE_MFJMPR)
23209 /* Return how many instructions the machine can issue per cycle. */
23212 rs6000_issue_rate (void)
23214 /* Unless scheduling for register pressure, use issue rate of 1 for
23215 first scheduling pass to decrease degradation. */
23216 if (!reload_completed && !flag_sched_pressure)
23219 switch (rs6000_cpu_attr) {
23220 case CPU_RIOS1: /* ? */
23222 case CPU_PPC601: /* ? */
23231 case CPU_PPCE300C2:
23232 case CPU_PPCE300C3:
23233 case CPU_PPCE500MC:
23234 case CPU_PPCE500MC64:
23254 /* Return how many instructions to look ahead for better insn
23258 rs6000_use_sched_lookahead (void)
23260 if (rs6000_cpu_attr == CPU_PPC8540)
23262 if (rs6000_cpu_attr == CPU_CELL)
23263 return (reload_completed ? 8 : 0);
23267 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
23269 rs6000_use_sched_lookahead_guard (rtx insn)
23271 if (rs6000_cpu_attr != CPU_CELL)
23274 if (insn == NULL_RTX || !INSN_P (insn))
23277 if (!reload_completed
23278 || is_nonpipeline_insn (insn)
23279 || is_microcoded_insn (insn))
23285 /* Determine is PAT refers to memory. */
23288 is_mem_ref (rtx pat)
23294 /* stack_tie does not produce any real memory traffic. */
23295 if (GET_CODE (pat) == UNSPEC
23296 && XINT (pat, 1) == UNSPEC_TIE)
23299 if (GET_CODE (pat) == MEM)
23302 /* Recursively process the pattern. */
23303 fmt = GET_RTX_FORMAT (GET_CODE (pat));
23305 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
23308 ret |= is_mem_ref (XEXP (pat, i));
23309 else if (fmt[i] == 'E')
23310 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
23311 ret |= is_mem_ref (XVECEXP (pat, i, j));
23317 /* Determine if PAT is a PATTERN of a load insn. */
23320 is_load_insn1 (rtx pat)
23322 if (!pat || pat == NULL_RTX)
23325 if (GET_CODE (pat) == SET)
23326 return is_mem_ref (SET_SRC (pat));
23328 if (GET_CODE (pat) == PARALLEL)
23332 for (i = 0; i < XVECLEN (pat, 0); i++)
23333 if (is_load_insn1 (XVECEXP (pat, 0, i)))
23340 /* Determine if INSN loads from memory. */
23343 is_load_insn (rtx insn)
23345 if (!insn || !INSN_P (insn))
23348 if (GET_CODE (insn) == CALL_INSN)
23351 return is_load_insn1 (PATTERN (insn));
23354 /* Determine if PAT is a PATTERN of a store insn. */
23357 is_store_insn1 (rtx pat)
23359 if (!pat || pat == NULL_RTX)
23362 if (GET_CODE (pat) == SET)
23363 return is_mem_ref (SET_DEST (pat));
23365 if (GET_CODE (pat) == PARALLEL)
23369 for (i = 0; i < XVECLEN (pat, 0); i++)
23370 if (is_store_insn1 (XVECEXP (pat, 0, i)))
23377 /* Determine if INSN stores to memory. */
23380 is_store_insn (rtx insn)
23382 if (!insn || !INSN_P (insn))
23385 return is_store_insn1 (PATTERN (insn));
23388 /* Return the dest of a store insn. */
23391 get_store_dest (rtx pat)
23393 gcc_assert (is_store_insn1 (pat));
23395 if (GET_CODE (pat) == SET)
23396 return SET_DEST (pat);
23397 else if (GET_CODE (pat) == PARALLEL)
23401 for (i = 0; i < XVECLEN (pat, 0); i++)
23403 rtx inner_pat = XVECEXP (pat, 0, i);
23404 if (GET_CODE (inner_pat) == SET
23405 && is_mem_ref (SET_DEST (inner_pat)))
23409 /* We shouldn't get here, because we should have either a simple
23410 store insn or a store with update which are covered above. */
23414 /* Returns whether the dependence between INSN and NEXT is considered
23415 costly by the given target. */
23418 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
23423 /* If the flag is not enabled - no dependence is considered costly;
23424 allow all dependent insns in the same group.
23425 This is the most aggressive option. */
23426 if (rs6000_sched_costly_dep == no_dep_costly)
23429 /* If the flag is set to 1 - a dependence is always considered costly;
23430 do not allow dependent instructions in the same group.
23431 This is the most conservative option. */
23432 if (rs6000_sched_costly_dep == all_deps_costly)
23435 insn = DEP_PRO (dep);
23436 next = DEP_CON (dep);
23438 if (rs6000_sched_costly_dep == store_to_load_dep_costly
23439 && is_load_insn (next)
23440 && is_store_insn (insn))
23441 /* Prevent load after store in the same group. */
23444 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
23445 && is_load_insn (next)
23446 && is_store_insn (insn)
23447 && DEP_TYPE (dep) == REG_DEP_TRUE)
23448 /* Prevent load after store in the same group if it is a true
23452 /* The flag is set to X; dependences with latency >= X are considered costly,
23453 and will not be scheduled in the same group. */
23454 if (rs6000_sched_costly_dep <= max_dep_latency
23455 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
23461 /* Return the next insn after INSN that is found before TAIL is reached,
23462 skipping any "non-active" insns - insns that will not actually occupy
23463 an issue slot. Return NULL_RTX if such an insn is not found. */
23466 get_next_active_insn (rtx insn, rtx tail)
23468 if (insn == NULL_RTX || insn == tail)
23473 insn = NEXT_INSN (insn);
23474 if (insn == NULL_RTX || insn == tail)
23479 || (NONJUMP_INSN_P (insn)
23480 && GET_CODE (PATTERN (insn)) != USE
23481 && GET_CODE (PATTERN (insn)) != CLOBBER
23482 && INSN_CODE (insn) != CODE_FOR_stack_tie))
23488 /* We are about to begin issuing insns for this clock cycle. */
23491 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
23492 rtx *ready ATTRIBUTE_UNUSED,
23493 int *pn_ready ATTRIBUTE_UNUSED,
23494 int clock_var ATTRIBUTE_UNUSED)
23496 int n_ready = *pn_ready;
23499 fprintf (dump, "// rs6000_sched_reorder :\n");
23501 /* Reorder the ready list, if the second to last ready insn
23502 is a nonepipeline insn. */
23503 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
23505 if (is_nonpipeline_insn (ready[n_ready - 1])
23506 && (recog_memoized (ready[n_ready - 2]) > 0))
23507 /* Simply swap first two insns. */
23509 rtx tmp = ready[n_ready - 1];
23510 ready[n_ready - 1] = ready[n_ready - 2];
23511 ready[n_ready - 2] = tmp;
23515 if (rs6000_cpu == PROCESSOR_POWER6)
23516 load_store_pendulum = 0;
23518 return rs6000_issue_rate ();
23521 /* Like rs6000_sched_reorder, but called after issuing each insn. */
23524 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
23525 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
23528 fprintf (dump, "// rs6000_sched_reorder2 :\n");
23530 /* For Power6, we need to handle some special cases to try and keep the
23531 store queue from overflowing and triggering expensive flushes.
23533 This code monitors how load and store instructions are being issued
23534 and skews the ready list one way or the other to increase the likelihood
23535 that a desired instruction is issued at the proper time.
23537 A couple of things are done. First, we maintain a "load_store_pendulum"
23538 to track the current state of load/store issue.
23540 - If the pendulum is at zero, then no loads or stores have been
23541 issued in the current cycle so we do nothing.
23543 - If the pendulum is 1, then a single load has been issued in this
23544 cycle and we attempt to locate another load in the ready list to
23547 - If the pendulum is -2, then two stores have already been
23548 issued in this cycle, so we increase the priority of the first load
23549 in the ready list to increase it's likelihood of being chosen first
23552 - If the pendulum is -1, then a single store has been issued in this
23553 cycle and we attempt to locate another store in the ready list to
23554 issue with it, preferring a store to an adjacent memory location to
23555 facilitate store pairing in the store queue.
23557 - If the pendulum is 2, then two loads have already been
23558 issued in this cycle, so we increase the priority of the first store
23559 in the ready list to increase it's likelihood of being chosen first
23562 - If the pendulum < -2 or > 2, then do nothing.
23564 Note: This code covers the most common scenarios. There exist non
23565 load/store instructions which make use of the LSU and which
23566 would need to be accounted for to strictly model the behavior
23567 of the machine. Those instructions are currently unaccounted
23568 for to help minimize compile time overhead of this code.
23570 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
23576 if (is_store_insn (last_scheduled_insn))
23577 /* Issuing a store, swing the load_store_pendulum to the left */
23578 load_store_pendulum--;
23579 else if (is_load_insn (last_scheduled_insn))
23580 /* Issuing a load, swing the load_store_pendulum to the right */
23581 load_store_pendulum++;
23583 return cached_can_issue_more;
23585 /* If the pendulum is balanced, or there is only one instruction on
23586 the ready list, then all is well, so return. */
23587 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
23588 return cached_can_issue_more;
23590 if (load_store_pendulum == 1)
23592 /* A load has been issued in this cycle. Scan the ready list
23593 for another load to issue with it */
23598 if (is_load_insn (ready[pos]))
23600 /* Found a load. Move it to the head of the ready list,
23601 and adjust it's priority so that it is more likely to
23604 for (i=pos; i<*pn_ready-1; i++)
23605 ready[i] = ready[i + 1];
23606 ready[*pn_ready-1] = tmp;
23608 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23609 INSN_PRIORITY (tmp)++;
23615 else if (load_store_pendulum == -2)
23617 /* Two stores have been issued in this cycle. Increase the
23618 priority of the first load in the ready list to favor it for
23619 issuing in the next cycle. */
23624 if (is_load_insn (ready[pos])
23626 && INSN_PRIORITY_KNOWN (ready[pos]))
23628 INSN_PRIORITY (ready[pos])++;
23630 /* Adjust the pendulum to account for the fact that a load
23631 was found and increased in priority. This is to prevent
23632 increasing the priority of multiple loads */
23633 load_store_pendulum--;
23640 else if (load_store_pendulum == -1)
23642 /* A store has been issued in this cycle. Scan the ready list for
23643 another store to issue with it, preferring a store to an adjacent
23645 int first_store_pos = -1;
23651 if (is_store_insn (ready[pos]))
23653 /* Maintain the index of the first store found on the
23655 if (first_store_pos == -1)
23656 first_store_pos = pos;
23658 if (is_store_insn (last_scheduled_insn)
23659 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
23661 /* Found an adjacent store. Move it to the head of the
23662 ready list, and adjust it's priority so that it is
23663 more likely to stay there */
23665 for (i=pos; i<*pn_ready-1; i++)
23666 ready[i] = ready[i + 1];
23667 ready[*pn_ready-1] = tmp;
23669 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23670 INSN_PRIORITY (tmp)++;
23672 first_store_pos = -1;
23680 if (first_store_pos >= 0)
23682 /* An adjacent store wasn't found, but a non-adjacent store was,
23683 so move the non-adjacent store to the front of the ready
23684 list, and adjust its priority so that it is more likely to
23686 tmp = ready[first_store_pos];
23687 for (i=first_store_pos; i<*pn_ready-1; i++)
23688 ready[i] = ready[i + 1];
23689 ready[*pn_ready-1] = tmp;
23690 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23691 INSN_PRIORITY (tmp)++;
23694 else if (load_store_pendulum == 2)
23696 /* Two loads have been issued in this cycle. Increase the priority
23697 of the first store in the ready list to favor it for issuing in
23703 if (is_store_insn (ready[pos])
23705 && INSN_PRIORITY_KNOWN (ready[pos]))
23707 INSN_PRIORITY (ready[pos])++;
23709 /* Adjust the pendulum to account for the fact that a store
23710 was found and increased in priority. This is to prevent
23711 increasing the priority of multiple stores */
23712 load_store_pendulum++;
23721 return cached_can_issue_more;
23724 /* Return whether the presence of INSN causes a dispatch group termination
23725 of group WHICH_GROUP.
23727 If WHICH_GROUP == current_group, this function will return true if INSN
23728 causes the termination of the current group (i.e, the dispatch group to
23729 which INSN belongs). This means that INSN will be the last insn in the
23730 group it belongs to.
23732 If WHICH_GROUP == previous_group, this function will return true if INSN
23733 causes the termination of the previous group (i.e, the dispatch group that
23734 precedes the group to which INSN belongs). This means that INSN will be
23735 the first insn in the group it belongs to). */
23738 insn_terminates_group_p (rtx insn, enum group_termination which_group)
23745 first = insn_must_be_first_in_group (insn);
23746 last = insn_must_be_last_in_group (insn);
23751 if (which_group == current_group)
23753 else if (which_group == previous_group)
23761 insn_must_be_first_in_group (rtx insn)
23763 enum attr_type type;
23766 || GET_CODE (insn) == NOTE
23767 || DEBUG_INSN_P (insn)
23768 || GET_CODE (PATTERN (insn)) == USE
23769 || GET_CODE (PATTERN (insn)) == CLOBBER)
23772 switch (rs6000_cpu)
23774 case PROCESSOR_POWER5:
23775 if (is_cracked_insn (insn))
23777 case PROCESSOR_POWER4:
23778 if (is_microcoded_insn (insn))
23781 if (!rs6000_sched_groups)
23784 type = get_attr_type (insn);
23791 case TYPE_DELAYED_CR:
23792 case TYPE_CR_LOGICAL:
23806 case PROCESSOR_POWER6:
23807 type = get_attr_type (insn);
23811 case TYPE_INSERT_DWORD:
23815 case TYPE_VAR_SHIFT_ROTATE:
23822 case TYPE_INSERT_WORD:
23823 case TYPE_DELAYED_COMPARE:
23824 case TYPE_IMUL_COMPARE:
23825 case TYPE_LMUL_COMPARE:
23826 case TYPE_FPCOMPARE:
23837 case TYPE_LOAD_EXT_UX:
23839 case TYPE_STORE_UX:
23840 case TYPE_FPLOAD_U:
23841 case TYPE_FPLOAD_UX:
23842 case TYPE_FPSTORE_U:
23843 case TYPE_FPSTORE_UX:
23849 case PROCESSOR_POWER7:
23850 type = get_attr_type (insn);
23854 case TYPE_CR_LOGICAL:
23861 case TYPE_DELAYED_COMPARE:
23862 case TYPE_VAR_DELAYED_COMPARE:
23868 case TYPE_LOAD_EXT:
23869 case TYPE_LOAD_EXT_U:
23870 case TYPE_LOAD_EXT_UX:
23872 case TYPE_STORE_UX:
23873 case TYPE_FPLOAD_U:
23874 case TYPE_FPLOAD_UX:
23875 case TYPE_FPSTORE_U:
23876 case TYPE_FPSTORE_UX:
23892 insn_must_be_last_in_group (rtx insn)
23894 enum attr_type type;
23897 || GET_CODE (insn) == NOTE
23898 || DEBUG_INSN_P (insn)
23899 || GET_CODE (PATTERN (insn)) == USE
23900 || GET_CODE (PATTERN (insn)) == CLOBBER)
23903 switch (rs6000_cpu) {
23904 case PROCESSOR_POWER4:
23905 case PROCESSOR_POWER5:
23906 if (is_microcoded_insn (insn))
23909 if (is_branch_slot_insn (insn))
23913 case PROCESSOR_POWER6:
23914 type = get_attr_type (insn);
23921 case TYPE_VAR_SHIFT_ROTATE:
23928 case TYPE_DELAYED_COMPARE:
23929 case TYPE_IMUL_COMPARE:
23930 case TYPE_LMUL_COMPARE:
23931 case TYPE_FPCOMPARE:
23945 case PROCESSOR_POWER7:
23946 type = get_attr_type (insn);
23954 case TYPE_LOAD_EXT_U:
23955 case TYPE_LOAD_EXT_UX:
23956 case TYPE_STORE_UX:
23969 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
23970 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
23973 is_costly_group (rtx *group_insns, rtx next_insn)
23976 int issue_rate = rs6000_issue_rate ();
23978 for (i = 0; i < issue_rate; i++)
23980 sd_iterator_def sd_it;
23982 rtx insn = group_insns[i];
23987 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
23989 rtx next = DEP_CON (dep);
23991 if (next == next_insn
23992 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
24000 /* Utility of the function redefine_groups.
24001 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
24002 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
24003 to keep it "far" (in a separate group) from GROUP_INSNS, following
24004 one of the following schemes, depending on the value of the flag
24005 -minsert_sched_nops = X:
24006 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
24007 in order to force NEXT_INSN into a separate group.
24008 (2) X < sched_finish_regroup_exact: insert exactly X nops.
24009 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
24010 insertion (has a group just ended, how many vacant issue slots remain in the
24011 last group, and how many dispatch groups were encountered so far). */
24014 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
24015 rtx next_insn, bool *group_end, int can_issue_more,
24020 int issue_rate = rs6000_issue_rate ();
24021 bool end = *group_end;
24024 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
24025 return can_issue_more;
24027 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
24028 return can_issue_more;
24030 force = is_costly_group (group_insns, next_insn);
24032 return can_issue_more;
24034 if (sched_verbose > 6)
24035 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
24036 *group_count ,can_issue_more);
24038 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
24041 can_issue_more = 0;
24043 /* Since only a branch can be issued in the last issue_slot, it is
24044 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
24045 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
24046 in this case the last nop will start a new group and the branch
24047 will be forced to the new group. */
24048 if (can_issue_more && !is_branch_slot_insn (next_insn))
24051 while (can_issue_more > 0)
24054 emit_insn_before (nop, next_insn);
24062 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
24064 int n_nops = rs6000_sched_insert_nops;
24066 /* Nops can't be issued from the branch slot, so the effective
24067 issue_rate for nops is 'issue_rate - 1'. */
24068 if (can_issue_more == 0)
24069 can_issue_more = issue_rate;
24071 if (can_issue_more == 0)
24073 can_issue_more = issue_rate - 1;
24076 for (i = 0; i < issue_rate; i++)
24078 group_insns[i] = 0;
24085 emit_insn_before (nop, next_insn);
24086 if (can_issue_more == issue_rate - 1) /* new group begins */
24089 if (can_issue_more == 0)
24091 can_issue_more = issue_rate - 1;
24094 for (i = 0; i < issue_rate; i++)
24096 group_insns[i] = 0;
24102 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
24105 /* Is next_insn going to start a new group? */
24108 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24109 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24110 || (can_issue_more < issue_rate &&
24111 insn_terminates_group_p (next_insn, previous_group)));
24112 if (*group_end && end)
24115 if (sched_verbose > 6)
24116 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
24117 *group_count, can_issue_more);
24118 return can_issue_more;
24121 return can_issue_more;
24124 /* This function tries to synch the dispatch groups that the compiler "sees"
24125 with the dispatch groups that the processor dispatcher is expected to
24126 form in practice. It tries to achieve this synchronization by forcing the
24127 estimated processor grouping on the compiler (as opposed to the function
24128 'pad_goups' which tries to force the scheduler's grouping on the processor).
24130 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
24131 examines the (estimated) dispatch groups that will be formed by the processor
24132 dispatcher. It marks these group boundaries to reflect the estimated
24133 processor grouping, overriding the grouping that the scheduler had marked.
24134 Depending on the value of the flag '-minsert-sched-nops' this function can
24135 force certain insns into separate groups or force a certain distance between
24136 them by inserting nops, for example, if there exists a "costly dependence"
24139 The function estimates the group boundaries that the processor will form as
24140 follows: It keeps track of how many vacant issue slots are available after
24141 each insn. A subsequent insn will start a new group if one of the following
24143 - no more vacant issue slots remain in the current dispatch group.
24144 - only the last issue slot, which is the branch slot, is vacant, but the next
24145 insn is not a branch.
24146 - only the last 2 or less issue slots, including the branch slot, are vacant,
24147 which means that a cracked insn (which occupies two issue slots) can't be
24148 issued in this group.
24149 - less than 'issue_rate' slots are vacant, and the next insn always needs to
24150 start a new group. */
24153 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24155 rtx insn, next_insn;
24157 int can_issue_more;
24160 int group_count = 0;
24164 issue_rate = rs6000_issue_rate ();
24165 group_insns = XALLOCAVEC (rtx, issue_rate);
24166 for (i = 0; i < issue_rate; i++)
24168 group_insns[i] = 0;
24170 can_issue_more = issue_rate;
24172 insn = get_next_active_insn (prev_head_insn, tail);
24175 while (insn != NULL_RTX)
24177 slot = (issue_rate - can_issue_more);
24178 group_insns[slot] = insn;
24180 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24181 if (insn_terminates_group_p (insn, current_group))
24182 can_issue_more = 0;
24184 next_insn = get_next_active_insn (insn, tail);
24185 if (next_insn == NULL_RTX)
24186 return group_count + 1;
24188 /* Is next_insn going to start a new group? */
24190 = (can_issue_more == 0
24191 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24192 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24193 || (can_issue_more < issue_rate &&
24194 insn_terminates_group_p (next_insn, previous_group)));
24196 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
24197 next_insn, &group_end, can_issue_more,
24203 can_issue_more = 0;
24204 for (i = 0; i < issue_rate; i++)
24206 group_insns[i] = 0;
24210 if (GET_MODE (next_insn) == TImode && can_issue_more)
24211 PUT_MODE (next_insn, VOIDmode);
24212 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
24213 PUT_MODE (next_insn, TImode);
24216 if (can_issue_more == 0)
24217 can_issue_more = issue_rate;
24220 return group_count;
24223 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
24224 dispatch group boundaries that the scheduler had marked. Pad with nops
24225 any dispatch groups which have vacant issue slots, in order to force the
24226 scheduler's grouping on the processor dispatcher. The function
24227 returns the number of dispatch groups found. */
24230 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24232 rtx insn, next_insn;
24235 int can_issue_more;
24237 int group_count = 0;
24239 /* Initialize issue_rate. */
24240 issue_rate = rs6000_issue_rate ();
24241 can_issue_more = issue_rate;
24243 insn = get_next_active_insn (prev_head_insn, tail);
24244 next_insn = get_next_active_insn (insn, tail);
24246 while (insn != NULL_RTX)
24249 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24251 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
24253 if (next_insn == NULL_RTX)
24258 /* If the scheduler had marked group termination at this location
24259 (between insn and next_insn), and neither insn nor next_insn will
24260 force group termination, pad the group with nops to force group
24263 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
24264 && !insn_terminates_group_p (insn, current_group)
24265 && !insn_terminates_group_p (next_insn, previous_group))
24267 if (!is_branch_slot_insn (next_insn))
24270 while (can_issue_more)
24273 emit_insn_before (nop, next_insn);
24278 can_issue_more = issue_rate;
24283 next_insn = get_next_active_insn (insn, tail);
24286 return group_count;
24289 /* We're beginning a new block. Initialize data structures as necessary. */
24292 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
24293 int sched_verbose ATTRIBUTE_UNUSED,
24294 int max_ready ATTRIBUTE_UNUSED)
24296 last_scheduled_insn = NULL_RTX;
24297 load_store_pendulum = 0;
24300 /* The following function is called at the end of scheduling BB.
24301 After reload, it inserts nops at insn group bundling. */
24304 rs6000_sched_finish (FILE *dump, int sched_verbose)
24309 fprintf (dump, "=== Finishing schedule.\n");
24311 if (reload_completed && rs6000_sched_groups)
24313 /* Do not run sched_finish hook when selective scheduling enabled. */
24314 if (sel_sched_p ())
24317 if (rs6000_sched_insert_nops == sched_finish_none)
24320 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
24321 n_groups = pad_groups (dump, sched_verbose,
24322 current_sched_info->prev_head,
24323 current_sched_info->next_tail);
24325 n_groups = redefine_groups (dump, sched_verbose,
24326 current_sched_info->prev_head,
24327 current_sched_info->next_tail);
24329 if (sched_verbose >= 6)
24331 fprintf (dump, "ngroups = %d\n", n_groups);
24332 print_rtl (dump, current_sched_info->prev_head);
24333 fprintf (dump, "Done finish_sched\n");
24338 struct _rs6000_sched_context
24340 short cached_can_issue_more;
24341 rtx last_scheduled_insn;
24342 int load_store_pendulum;
24345 typedef struct _rs6000_sched_context rs6000_sched_context_def;
24346 typedef rs6000_sched_context_def *rs6000_sched_context_t;
24348 /* Allocate store for new scheduling context. */
24350 rs6000_alloc_sched_context (void)
24352 return xmalloc (sizeof (rs6000_sched_context_def));
24355 /* If CLEAN_P is true then initializes _SC with clean data,
24356 and from the global context otherwise. */
24358 rs6000_init_sched_context (void *_sc, bool clean_p)
24360 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24364 sc->cached_can_issue_more = 0;
24365 sc->last_scheduled_insn = NULL_RTX;
24366 sc->load_store_pendulum = 0;
24370 sc->cached_can_issue_more = cached_can_issue_more;
24371 sc->last_scheduled_insn = last_scheduled_insn;
24372 sc->load_store_pendulum = load_store_pendulum;
24376 /* Sets the global scheduling context to the one pointed to by _SC. */
24378 rs6000_set_sched_context (void *_sc)
24380 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24382 gcc_assert (sc != NULL);
24384 cached_can_issue_more = sc->cached_can_issue_more;
24385 last_scheduled_insn = sc->last_scheduled_insn;
24386 load_store_pendulum = sc->load_store_pendulum;
24391 rs6000_free_sched_context (void *_sc)
24393 gcc_assert (_sc != NULL);
24399 /* Length in units of the trampoline for entering a nested function. */
24402 rs6000_trampoline_size (void)
24406 switch (DEFAULT_ABI)
24409 gcc_unreachable ();
24412 ret = (TARGET_32BIT) ? 12 : 24;
24417 ret = (TARGET_32BIT) ? 40 : 48;
24424 /* Emit RTL insns to initialize the variable parts of a trampoline.
24425 FNADDR is an RTX for the address of the function's pure code.
24426 CXT is an RTX for the static chain value for the function. */
24429 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
24431 int regsize = (TARGET_32BIT) ? 4 : 8;
24432 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
24433 rtx ctx_reg = force_reg (Pmode, cxt);
24434 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
24436 switch (DEFAULT_ABI)
24439 gcc_unreachable ();
24441 /* Under AIX, just build the 3 word function descriptor */
24444 rtx fnmem, fn_reg, toc_reg;
24446 if (!TARGET_POINTERS_TO_NESTED_FUNCTIONS)
24447 error ("-mno-r11 must not be used if you have trampolines");
24449 fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
24450 fn_reg = gen_reg_rtx (Pmode);
24451 toc_reg = gen_reg_rtx (Pmode);
24453 /* Macro to shorten the code expansions below. */
24454 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
24456 m_tramp = replace_equiv_address (m_tramp, addr);
24458 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
24459 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
24460 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
24461 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
24462 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
24468 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
24471 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
24472 LCT_NORMAL, VOIDmode, 4,
24474 GEN_INT (rs6000_trampoline_size ()), SImode,
24482 /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
24483 identifier as an argument, so the front end shouldn't look it up. */
24486 rs6000_attribute_takes_identifier_p (const_tree attr_id)
24488 return is_attribute_p ("altivec", attr_id);
24491 /* Handle the "altivec" attribute. The attribute may have
24492 arguments as follows:
24494 __attribute__((altivec(vector__)))
24495 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
24496 __attribute__((altivec(bool__))) (always followed by 'unsigned')
24498 and may appear more than once (e.g., 'vector bool char') in a
24499 given declaration. */
24502 rs6000_handle_altivec_attribute (tree *node,
24503 tree name ATTRIBUTE_UNUSED,
24505 int flags ATTRIBUTE_UNUSED,
24506 bool *no_add_attrs)
24508 tree type = *node, result = NULL_TREE;
24509 enum machine_mode mode;
24512 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
24513 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
24514 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
24517 while (POINTER_TYPE_P (type)
24518 || TREE_CODE (type) == FUNCTION_TYPE
24519 || TREE_CODE (type) == METHOD_TYPE
24520 || TREE_CODE (type) == ARRAY_TYPE)
24521 type = TREE_TYPE (type);
24523 mode = TYPE_MODE (type);
24525 /* Check for invalid AltiVec type qualifiers. */
24526 if (type == long_double_type_node)
24527 error ("use of %<long double%> in AltiVec types is invalid");
24528 else if (type == boolean_type_node)
24529 error ("use of boolean types in AltiVec types is invalid");
24530 else if (TREE_CODE (type) == COMPLEX_TYPE)
24531 error ("use of %<complex%> in AltiVec types is invalid");
24532 else if (DECIMAL_FLOAT_MODE_P (mode))
24533 error ("use of decimal floating point types in AltiVec types is invalid");
24534 else if (!TARGET_VSX)
24536 if (type == long_unsigned_type_node || type == long_integer_type_node)
24539 error ("use of %<long%> in AltiVec types is invalid for "
24540 "64-bit code without -mvsx");
24541 else if (rs6000_warn_altivec_long)
24542 warning (0, "use of %<long%> in AltiVec types is deprecated; "
24545 else if (type == long_long_unsigned_type_node
24546 || type == long_long_integer_type_node)
24547 error ("use of %<long long%> in AltiVec types is invalid without "
24549 else if (type == double_type_node)
24550 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
24553 switch (altivec_type)
24556 unsigned_p = TYPE_UNSIGNED (type);
24560 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
24563 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
24566 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
24569 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
24571 case SFmode: result = V4SF_type_node; break;
24572 case DFmode: result = V2DF_type_node; break;
24573 /* If the user says 'vector int bool', we may be handed the 'bool'
24574 attribute _before_ the 'vector' attribute, and so select the
24575 proper type in the 'b' case below. */
24576 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
24577 case V2DImode: case V2DFmode:
24585 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
24586 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
24587 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
24588 case QImode: case V16QImode: result = bool_V16QI_type_node;
24595 case V8HImode: result = pixel_V8HI_type_node;
24601 /* Propagate qualifiers attached to the element type
24602 onto the vector type. */
24603 if (result && result != type && TYPE_QUALS (type))
24604 result = build_qualified_type (result, TYPE_QUALS (type));
24606 *no_add_attrs = true; /* No need to hang on to the attribute. */
24609 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
24614 /* AltiVec defines four built-in scalar types that serve as vector
24615 elements; we must teach the compiler how to mangle them. */
24617 static const char *
24618 rs6000_mangle_type (const_tree type)
24620 type = TYPE_MAIN_VARIANT (type);
24622 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
24623 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
24626 if (type == bool_char_type_node) return "U6__boolc";
24627 if (type == bool_short_type_node) return "U6__bools";
24628 if (type == pixel_type_node) return "u7__pixel";
24629 if (type == bool_int_type_node) return "U6__booli";
24630 if (type == bool_long_type_node) return "U6__booll";
24632 /* Mangle IBM extended float long double as `g' (__float128) on
24633 powerpc*-linux where long-double-64 previously was the default. */
24634 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
24636 && TARGET_LONG_DOUBLE_128
24637 && !TARGET_IEEEQUAD)
24640 /* For all other types, use normal C++ mangling. */
24644 /* Handle a "longcall" or "shortcall" attribute; arguments as in
24645 struct attribute_spec.handler. */
24648 rs6000_handle_longcall_attribute (tree *node, tree name,
24649 tree args ATTRIBUTE_UNUSED,
24650 int flags ATTRIBUTE_UNUSED,
24651 bool *no_add_attrs)
24653 if (TREE_CODE (*node) != FUNCTION_TYPE
24654 && TREE_CODE (*node) != FIELD_DECL
24655 && TREE_CODE (*node) != TYPE_DECL)
24657 warning (OPT_Wattributes, "%qE attribute only applies to functions",
24659 *no_add_attrs = true;
24665 /* Set longcall attributes on all functions declared when
24666 rs6000_default_long_calls is true. */
24668 rs6000_set_default_type_attributes (tree type)
24670 if (rs6000_default_long_calls
24671 && (TREE_CODE (type) == FUNCTION_TYPE
24672 || TREE_CODE (type) == METHOD_TYPE))
24673 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
24675 TYPE_ATTRIBUTES (type));
24678 darwin_set_default_type_attributes (type);
24682 /* Return a reference suitable for calling a function with the
24683 longcall attribute. */
24686 rs6000_longcall_ref (rtx call_ref)
24688 const char *call_name;
24691 if (GET_CODE (call_ref) != SYMBOL_REF)
24694 /* System V adds '.' to the internal name, so skip them. */
24695 call_name = XSTR (call_ref, 0);
24696 if (*call_name == '.')
24698 while (*call_name == '.')
24701 node = get_identifier (call_name);
24702 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
24705 return force_reg (Pmode, call_ref);
24708 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
24709 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
24712 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
24713 struct attribute_spec.handler. */
24715 rs6000_handle_struct_attribute (tree *node, tree name,
24716 tree args ATTRIBUTE_UNUSED,
24717 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
24720 if (DECL_P (*node))
24722 if (TREE_CODE (*node) == TYPE_DECL)
24723 type = &TREE_TYPE (*node);
24728 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
24729 || TREE_CODE (*type) == UNION_TYPE)))
24731 warning (OPT_Wattributes, "%qE attribute ignored", name);
24732 *no_add_attrs = true;
24735 else if ((is_attribute_p ("ms_struct", name)
24736 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
24737 || ((is_attribute_p ("gcc_struct", name)
24738 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
24740 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
24742 *no_add_attrs = true;
24749 rs6000_ms_bitfield_layout_p (const_tree record_type)
24751 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
24752 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
24753 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
24756 #ifdef USING_ELFOS_H
24758 /* A get_unnamed_section callback, used for switching to toc_section. */
24761 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
24763 if (DEFAULT_ABI == ABI_AIX
24764 && TARGET_MINIMAL_TOC
24765 && !TARGET_RELOCATABLE)
24767 if (!toc_initialized)
24769 toc_initialized = 1;
24770 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
24771 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
24772 fprintf (asm_out_file, "\t.tc ");
24773 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
24774 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24775 fprintf (asm_out_file, "\n");
24777 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24778 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24779 fprintf (asm_out_file, " = .+32768\n");
24782 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24784 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
24785 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
24788 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24789 if (!toc_initialized)
24791 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24792 fprintf (asm_out_file, " = .+32768\n");
24793 toc_initialized = 1;
24798 /* Implement TARGET_ASM_INIT_SECTIONS. */
24801 rs6000_elf_asm_init_sections (void)
24804 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
24807 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
24808 SDATA2_SECTION_ASM_OP);
24811 /* Implement TARGET_SELECT_RTX_SECTION. */
24814 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
24815 unsigned HOST_WIDE_INT align)
24817 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
24818 return toc_section;
24820 return default_elf_select_rtx_section (mode, x, align);
24823 /* For a SYMBOL_REF, set generic flags and then perform some
24824 target-specific processing.
24826 When the AIX ABI is requested on a non-AIX system, replace the
24827 function name with the real name (with a leading .) rather than the
24828 function descriptor name. This saves a lot of overriding code to
24829 read the prefixes. */
24832 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
24834 default_encode_section_info (decl, rtl, first);
24837 && TREE_CODE (decl) == FUNCTION_DECL
24839 && DEFAULT_ABI == ABI_AIX)
24841 rtx sym_ref = XEXP (rtl, 0);
24842 size_t len = strlen (XSTR (sym_ref, 0));
24843 char *str = XALLOCAVEC (char, len + 2);
24845 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
24846 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
24851 compare_section_name (const char *section, const char *templ)
24855 len = strlen (templ);
24856 return (strncmp (section, templ, len) == 0
24857 && (section[len] == 0 || section[len] == '.'));
24861 rs6000_elf_in_small_data_p (const_tree decl)
24863 if (rs6000_sdata == SDATA_NONE)
24866 /* We want to merge strings, so we never consider them small data. */
24867 if (TREE_CODE (decl) == STRING_CST)
24870 /* Functions are never in the small data area. */
24871 if (TREE_CODE (decl) == FUNCTION_DECL)
24874 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
24876 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
24877 if (compare_section_name (section, ".sdata")
24878 || compare_section_name (section, ".sdata2")
24879 || compare_section_name (section, ".gnu.linkonce.s")
24880 || compare_section_name (section, ".sbss")
24881 || compare_section_name (section, ".sbss2")
24882 || compare_section_name (section, ".gnu.linkonce.sb")
24883 || strcmp (section, ".PPC.EMB.sdata0") == 0
24884 || strcmp (section, ".PPC.EMB.sbss0") == 0)
24889 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
24892 && size <= g_switch_value
24893 /* If it's not public, and we're not going to reference it there,
24894 there's no need to put it in the small data section. */
24895 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
24902 #endif /* USING_ELFOS_H */
24904 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
24907 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
24909 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
24912 /* Return a REG that occurs in ADDR with coefficient 1.
24913 ADDR can be effectively incremented by incrementing REG.
24915 r0 is special and we must not select it as an address
24916 register by this routine since our caller will try to
24917 increment the returned register via an "la" instruction. */
24920 find_addr_reg (rtx addr)
24922 while (GET_CODE (addr) == PLUS)
24924 if (GET_CODE (XEXP (addr, 0)) == REG
24925 && REGNO (XEXP (addr, 0)) != 0)
24926 addr = XEXP (addr, 0);
24927 else if (GET_CODE (XEXP (addr, 1)) == REG
24928 && REGNO (XEXP (addr, 1)) != 0)
24929 addr = XEXP (addr, 1);
24930 else if (CONSTANT_P (XEXP (addr, 0)))
24931 addr = XEXP (addr, 1);
24932 else if (CONSTANT_P (XEXP (addr, 1)))
24933 addr = XEXP (addr, 0);
24935 gcc_unreachable ();
24937 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
24942 rs6000_fatal_bad_address (rtx op)
24944 fatal_insn ("bad address", op);
24949 typedef struct branch_island_d {
24950 tree function_name;
24955 DEF_VEC_O(branch_island);
24956 DEF_VEC_ALLOC_O(branch_island,gc);
24958 static VEC(branch_island,gc) *branch_islands;
24960 /* Remember to generate a branch island for far calls to the given
24964 add_compiler_branch_island (tree label_name, tree function_name,
24967 branch_island *bi = VEC_safe_push (branch_island, gc, branch_islands, NULL);
24969 bi->function_name = function_name;
24970 bi->label_name = label_name;
24971 bi->line_number = line_number;
24974 /* Generate far-jump branch islands for everything recorded in
24975 branch_islands. Invoked immediately after the last instruction of
24976 the epilogue has been emitted; the branch islands must be appended
24977 to, and contiguous with, the function body. Mach-O stubs are
24978 generated in machopic_output_stub(). */
24981 macho_branch_islands (void)
24985 while (!VEC_empty (branch_island, branch_islands))
24987 branch_island *bi = VEC_last (branch_island, branch_islands);
24988 const char *label = IDENTIFIER_POINTER (bi->label_name);
24989 const char *name = IDENTIFIER_POINTER (bi->function_name);
24990 char name_buf[512];
24991 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
24992 if (name[0] == '*' || name[0] == '&')
24993 strcpy (name_buf, name+1);
24997 strcpy (name_buf+1, name);
24999 strcpy (tmp_buf, "\n");
25000 strcat (tmp_buf, label);
25001 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25002 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25003 dbxout_stabd (N_SLINE, bi->line_number);
25004 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25007 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
25008 strcat (tmp_buf, label);
25009 strcat (tmp_buf, "_pic\n");
25010 strcat (tmp_buf, label);
25011 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
25013 strcat (tmp_buf, "\taddis r11,r11,ha16(");
25014 strcat (tmp_buf, name_buf);
25015 strcat (tmp_buf, " - ");
25016 strcat (tmp_buf, label);
25017 strcat (tmp_buf, "_pic)\n");
25019 strcat (tmp_buf, "\tmtlr r0\n");
25021 strcat (tmp_buf, "\taddi r12,r11,lo16(");
25022 strcat (tmp_buf, name_buf);
25023 strcat (tmp_buf, " - ");
25024 strcat (tmp_buf, label);
25025 strcat (tmp_buf, "_pic)\n");
25027 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
25031 strcat (tmp_buf, ":\nlis r12,hi16(");
25032 strcat (tmp_buf, name_buf);
25033 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
25034 strcat (tmp_buf, name_buf);
25035 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
25037 output_asm_insn (tmp_buf, 0);
25038 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25039 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25040 dbxout_stabd (N_SLINE, bi->line_number);
25041 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25042 VEC_pop (branch_island, branch_islands);
25046 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
25047 already there or not. */
25050 no_previous_def (tree function_name)
25055 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25056 if (function_name == bi->function_name)
25061 /* GET_PREV_LABEL gets the label name from the previous definition of
25065 get_prev_label (tree function_name)
25070 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25071 if (function_name == bi->function_name)
25072 return bi->label_name;
25076 /* INSN is either a function call or a millicode call. It may have an
25077 unconditional jump in its delay slot.
25079 CALL_DEST is the routine we are calling. */
25082 output_call (rtx insn, rtx *operands, int dest_operand_number,
25083 int cookie_operand_number)
25085 static char buf[256];
25086 if (darwin_emit_branch_islands
25087 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
25088 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
25091 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
25093 if (no_previous_def (funname))
25095 rtx label_rtx = gen_label_rtx ();
25096 char *label_buf, temp_buf[256];
25097 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
25098 CODE_LABEL_NUMBER (label_rtx));
25099 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
25100 labelname = get_identifier (label_buf);
25101 add_compiler_branch_island (labelname, funname, insn_line (insn));
25104 labelname = get_prev_label (funname);
25106 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
25107 instruction will reach 'foo', otherwise link as 'bl L42'".
25108 "L42" should be a 'branch island', that will do a far jump to
25109 'foo'. Branch islands are generated in
25110 macho_branch_islands(). */
25111 sprintf (buf, "jbsr %%z%d,%.246s",
25112 dest_operand_number, IDENTIFIER_POINTER (labelname));
25115 sprintf (buf, "bl %%z%d", dest_operand_number);
25119 /* Generate PIC and indirect symbol stubs. */
25122 machopic_output_stub (FILE *file, const char *symb, const char *stub)
25124 unsigned int length;
25125 char *symbol_name, *lazy_ptr_name;
25126 char *local_label_0;
25127 static int label = 0;
25129 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
25130 symb = (*targetm.strip_name_encoding) (symb);
25133 length = strlen (symb);
25134 symbol_name = XALLOCAVEC (char, length + 32);
25135 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
25137 lazy_ptr_name = XALLOCAVEC (char, length + 32);
25138 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
25141 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
25143 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
25147 fprintf (file, "\t.align 5\n");
25149 fprintf (file, "%s:\n", stub);
25150 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25153 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
25154 sprintf (local_label_0, "\"L%011d$spb\"", label);
25156 fprintf (file, "\tmflr r0\n");
25157 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
25158 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
25159 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
25160 lazy_ptr_name, local_label_0);
25161 fprintf (file, "\tmtlr r0\n");
25162 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
25163 (TARGET_64BIT ? "ldu" : "lwzu"),
25164 lazy_ptr_name, local_label_0);
25165 fprintf (file, "\tmtctr r12\n");
25166 fprintf (file, "\tbctr\n");
25170 fprintf (file, "\t.align 4\n");
25172 fprintf (file, "%s:\n", stub);
25173 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25175 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
25176 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
25177 (TARGET_64BIT ? "ldu" : "lwzu"),
25179 fprintf (file, "\tmtctr r12\n");
25180 fprintf (file, "\tbctr\n");
25183 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
25184 fprintf (file, "%s:\n", lazy_ptr_name);
25185 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25186 fprintf (file, "%sdyld_stub_binding_helper\n",
25187 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
25190 /* Legitimize PIC addresses. If the address is already
25191 position-independent, we return ORIG. Newly generated
25192 position-independent addresses go into a reg. This is REG if non
25193 zero, otherwise we allocate register(s) as necessary. */
25195 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
25198 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
25203 if (reg == NULL && ! reload_in_progress && ! reload_completed)
25204 reg = gen_reg_rtx (Pmode);
25206 if (GET_CODE (orig) == CONST)
25210 if (GET_CODE (XEXP (orig, 0)) == PLUS
25211 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
25214 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
25216 /* Use a different reg for the intermediate value, as
25217 it will be marked UNCHANGING. */
25218 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
25219 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
25222 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
25225 if (GET_CODE (offset) == CONST_INT)
25227 if (SMALL_INT (offset))
25228 return plus_constant (base, INTVAL (offset));
25229 else if (! reload_in_progress && ! reload_completed)
25230 offset = force_reg (Pmode, offset);
25233 rtx mem = force_const_mem (Pmode, orig);
25234 return machopic_legitimize_pic_address (mem, Pmode, reg);
25237 return gen_rtx_PLUS (Pmode, base, offset);
25240 /* Fall back on generic machopic code. */
25241 return machopic_legitimize_pic_address (orig, mode, reg);
25244 /* Output a .machine directive for the Darwin assembler, and call
25245 the generic start_file routine. */
25248 rs6000_darwin_file_start (void)
25250 static const struct
25256 { "ppc64", "ppc64", MASK_64BIT },
25257 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
25258 { "power4", "ppc970", 0 },
25259 { "G5", "ppc970", 0 },
25260 { "7450", "ppc7450", 0 },
25261 { "7400", "ppc7400", MASK_ALTIVEC },
25262 { "G4", "ppc7400", 0 },
25263 { "750", "ppc750", 0 },
25264 { "740", "ppc750", 0 },
25265 { "G3", "ppc750", 0 },
25266 { "604e", "ppc604e", 0 },
25267 { "604", "ppc604", 0 },
25268 { "603e", "ppc603", 0 },
25269 { "603", "ppc603", 0 },
25270 { "601", "ppc601", 0 },
25271 { NULL, "ppc", 0 } };
25272 const char *cpu_id = "";
25275 rs6000_file_start ();
25276 darwin_file_start ();
25278 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
25280 if (rs6000_default_cpu != 0 && rs6000_default_cpu[0] != '\0')
25281 cpu_id = rs6000_default_cpu;
25283 if (global_options_set.x_rs6000_cpu_index)
25284 cpu_id = processor_target_table[rs6000_cpu_index].name;
25286 /* Look through the mapping array. Pick the first name that either
25287 matches the argument, has a bit set in IF_SET that is also set
25288 in the target flags, or has a NULL name. */
25291 while (mapping[i].arg != NULL
25292 && strcmp (mapping[i].arg, cpu_id) != 0
25293 && (mapping[i].if_set & target_flags) == 0)
25296 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
25299 #endif /* TARGET_MACHO */
25303 rs6000_elf_reloc_rw_mask (void)
25307 else if (DEFAULT_ABI == ABI_AIX)
25313 /* Record an element in the table of global constructors. SYMBOL is
25314 a SYMBOL_REF of the function to be called; PRIORITY is a number
25315 between 0 and MAX_INIT_PRIORITY.
25317 This differs from default_named_section_asm_out_constructor in
25318 that we have special handling for -mrelocatable. */
25321 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
25323 const char *section = ".ctors";
25326 if (priority != DEFAULT_INIT_PRIORITY)
25328 sprintf (buf, ".ctors.%.5u",
25329 /* Invert the numbering so the linker puts us in the proper
25330 order; constructors are run from right to left, and the
25331 linker sorts in increasing order. */
25332 MAX_INIT_PRIORITY - priority);
25336 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25337 assemble_align (POINTER_SIZE);
25339 if (TARGET_RELOCATABLE)
25341 fputs ("\t.long (", asm_out_file);
25342 output_addr_const (asm_out_file, symbol);
25343 fputs (")@fixup\n", asm_out_file);
25346 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25350 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
25352 const char *section = ".dtors";
25355 if (priority != DEFAULT_INIT_PRIORITY)
25357 sprintf (buf, ".dtors.%.5u",
25358 /* Invert the numbering so the linker puts us in the proper
25359 order; constructors are run from right to left, and the
25360 linker sorts in increasing order. */
25361 MAX_INIT_PRIORITY - priority);
25365 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25366 assemble_align (POINTER_SIZE);
25368 if (TARGET_RELOCATABLE)
25370 fputs ("\t.long (", asm_out_file);
25371 output_addr_const (asm_out_file, symbol);
25372 fputs (")@fixup\n", asm_out_file);
25375 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25379 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
25383 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
25384 ASM_OUTPUT_LABEL (file, name);
25385 fputs (DOUBLE_INT_ASM_OP, file);
25386 rs6000_output_function_entry (file, name);
25387 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
25390 fputs ("\t.size\t", file);
25391 assemble_name (file, name);
25392 fputs (",24\n\t.type\t.", file);
25393 assemble_name (file, name);
25394 fputs (",@function\n", file);
25395 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
25397 fputs ("\t.globl\t.", file);
25398 assemble_name (file, name);
25403 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25404 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25405 rs6000_output_function_entry (file, name);
25406 fputs (":\n", file);
25410 if (TARGET_RELOCATABLE
25411 && !TARGET_SECURE_PLT
25412 && (get_pool_size () != 0 || crtl->profile)
25417 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
25419 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
25420 fprintf (file, "\t.long ");
25421 assemble_name (file, buf);
25423 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
25424 assemble_name (file, buf);
25428 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25429 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25431 if (DEFAULT_ABI == ABI_AIX)
25433 const char *desc_name, *orig_name;
25435 orig_name = (*targetm.strip_name_encoding) (name);
25436 desc_name = orig_name;
25437 while (*desc_name == '.')
25440 if (TREE_PUBLIC (decl))
25441 fprintf (file, "\t.globl %s\n", desc_name);
25443 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25444 fprintf (file, "%s:\n", desc_name);
25445 fprintf (file, "\t.long %s\n", orig_name);
25446 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
25447 if (DEFAULT_ABI == ABI_AIX)
25448 fputs ("\t.long 0\n", file);
25449 fprintf (file, "\t.previous\n");
25451 ASM_OUTPUT_LABEL (file, name);
25455 rs6000_elf_file_end (void)
25457 #ifdef HAVE_AS_GNU_ATTRIBUTE
25458 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
25460 if (rs6000_passes_float)
25461 fprintf (asm_out_file, "\t.gnu_attribute 4, %d\n",
25462 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
25463 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
25465 if (rs6000_passes_vector)
25466 fprintf (asm_out_file, "\t.gnu_attribute 8, %d\n",
25467 (TARGET_ALTIVEC_ABI ? 2
25468 : TARGET_SPE_ABI ? 3
25470 if (rs6000_returns_struct)
25471 fprintf (asm_out_file, "\t.gnu_attribute 12, %d\n",
25472 aix_struct_return ? 2 : 1);
25475 #ifdef POWERPC_LINUX
25477 file_end_indicate_exec_stack ();
25484 rs6000_xcoff_asm_output_anchor (rtx symbol)
25488 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
25489 SYMBOL_REF_BLOCK_OFFSET (symbol));
25490 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
25494 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
25496 fputs (GLOBAL_ASM_OP, stream);
25497 RS6000_OUTPUT_BASENAME (stream, name);
25498 putc ('\n', stream);
25501 /* A get_unnamed_decl callback, used for read-only sections. PTR
25502 points to the section string variable. */
25505 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
25507 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
25508 *(const char *const *) directive,
25509 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
25512 /* Likewise for read-write sections. */
25515 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
25517 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
25518 *(const char *const *) directive,
25519 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
25522 /* A get_unnamed_section callback, used for switching to toc_section. */
25525 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
25527 if (TARGET_MINIMAL_TOC)
25529 /* toc_section is always selected at least once from
25530 rs6000_xcoff_file_start, so this is guaranteed to
25531 always be defined once and only once in each file. */
25532 if (!toc_initialized)
25534 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
25535 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
25536 toc_initialized = 1;
25538 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
25539 (TARGET_32BIT ? "" : ",3"));
25542 fputs ("\t.toc\n", asm_out_file);
25545 /* Implement TARGET_ASM_INIT_SECTIONS. */
25548 rs6000_xcoff_asm_init_sections (void)
25550 read_only_data_section
25551 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
25552 &xcoff_read_only_section_name);
25554 private_data_section
25555 = get_unnamed_section (SECTION_WRITE,
25556 rs6000_xcoff_output_readwrite_section_asm_op,
25557 &xcoff_private_data_section_name);
25559 read_only_private_data_section
25560 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
25561 &xcoff_private_data_section_name);
25564 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
25566 readonly_data_section = read_only_data_section;
25567 exception_section = data_section;
25571 rs6000_xcoff_reloc_rw_mask (void)
25577 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
25578 tree decl ATTRIBUTE_UNUSED)
25581 static const char * const suffix[3] = { "PR", "RO", "RW" };
25583 if (flags & SECTION_CODE)
25585 else if (flags & SECTION_WRITE)
25590 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
25591 (flags & SECTION_CODE) ? "." : "",
25592 name, suffix[smclass], flags & SECTION_ENTSIZE);
25596 rs6000_xcoff_select_section (tree decl, int reloc,
25597 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
25599 if (decl_readonly_section (decl, reloc))
25601 if (TREE_PUBLIC (decl))
25602 return read_only_data_section;
25604 return read_only_private_data_section;
25608 if (TREE_PUBLIC (decl))
25609 return data_section;
25611 return private_data_section;
25616 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
25620 /* Use select_section for private and uninitialized data. */
25621 if (!TREE_PUBLIC (decl)
25622 || DECL_COMMON (decl)
25623 || DECL_INITIAL (decl) == NULL_TREE
25624 || DECL_INITIAL (decl) == error_mark_node
25625 || (flag_zero_initialized_in_bss
25626 && initializer_zerop (DECL_INITIAL (decl))))
25629 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
25630 name = (*targetm.strip_name_encoding) (name);
25631 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
25634 /* Select section for constant in constant pool.
25636 On RS/6000, all constants are in the private read-only data area.
25637 However, if this is being placed in the TOC it must be output as a
25641 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
25642 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
25644 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
25645 return toc_section;
25647 return read_only_private_data_section;
25650 /* Remove any trailing [DS] or the like from the symbol name. */
25652 static const char *
25653 rs6000_xcoff_strip_name_encoding (const char *name)
25658 len = strlen (name);
25659 if (name[len - 1] == ']')
25660 return ggc_alloc_string (name, len - 4);
25665 /* Section attributes. AIX is always PIC. */
25667 static unsigned int
25668 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
25670 unsigned int align;
25671 unsigned int flags = default_section_type_flags (decl, name, reloc);
25673 /* Align to at least UNIT size. */
25674 if (flags & SECTION_CODE)
25675 align = MIN_UNITS_PER_WORD;
25677 /* Increase alignment of large objects if not already stricter. */
25678 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
25679 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
25680 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
25682 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
25685 /* Output at beginning of assembler file.
25687 Initialize the section names for the RS/6000 at this point.
25689 Specify filename, including full path, to assembler.
25691 We want to go into the TOC section so at least one .toc will be emitted.
25692 Also, in order to output proper .bs/.es pairs, we need at least one static
25693 [RW] section emitted.
25695 Finally, declare mcount when profiling to make the assembler happy. */
25698 rs6000_xcoff_file_start (void)
25700 rs6000_gen_section_name (&xcoff_bss_section_name,
25701 main_input_filename, ".bss_");
25702 rs6000_gen_section_name (&xcoff_private_data_section_name,
25703 main_input_filename, ".rw_");
25704 rs6000_gen_section_name (&xcoff_read_only_section_name,
25705 main_input_filename, ".ro_");
25707 fputs ("\t.file\t", asm_out_file);
25708 output_quoted_string (asm_out_file, main_input_filename);
25709 fputc ('\n', asm_out_file);
25710 if (write_symbols != NO_DEBUG)
25711 switch_to_section (private_data_section);
25712 switch_to_section (text_section);
25714 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
25715 rs6000_file_start ();
25718 /* Output at end of assembler file.
25719 On the RS/6000, referencing data should automatically pull in text. */
25722 rs6000_xcoff_file_end (void)
25724 switch_to_section (text_section);
25725 fputs ("_section_.text:\n", asm_out_file);
25726 switch_to_section (data_section);
25727 fputs (TARGET_32BIT
25728 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
25731 #endif /* TARGET_XCOFF */
25733 /* Compute a (partial) cost for rtx X. Return true if the complete
25734 cost has been computed, and false if subexpressions should be
25735 scanned. In either case, *TOTAL contains the cost result. */
25738 rs6000_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
25739 int *total, bool speed)
25741 enum machine_mode mode = GET_MODE (x);
25745 /* On the RS/6000, if it is valid in the insn, it is free. */
25747 if (((outer_code == SET
25748 || outer_code == PLUS
25749 || outer_code == MINUS)
25750 && (satisfies_constraint_I (x)
25751 || satisfies_constraint_L (x)))
25752 || (outer_code == AND
25753 && (satisfies_constraint_K (x)
25755 ? satisfies_constraint_L (x)
25756 : satisfies_constraint_J (x))
25757 || mask_operand (x, mode)
25759 && mask64_operand (x, DImode))))
25760 || ((outer_code == IOR || outer_code == XOR)
25761 && (satisfies_constraint_K (x)
25763 ? satisfies_constraint_L (x)
25764 : satisfies_constraint_J (x))))
25765 || outer_code == ASHIFT
25766 || outer_code == ASHIFTRT
25767 || outer_code == LSHIFTRT
25768 || outer_code == ROTATE
25769 || outer_code == ROTATERT
25770 || outer_code == ZERO_EXTRACT
25771 || (outer_code == MULT
25772 && satisfies_constraint_I (x))
25773 || ((outer_code == DIV || outer_code == UDIV
25774 || outer_code == MOD || outer_code == UMOD)
25775 && exact_log2 (INTVAL (x)) >= 0)
25776 || (outer_code == COMPARE
25777 && (satisfies_constraint_I (x)
25778 || satisfies_constraint_K (x)))
25779 || ((outer_code == EQ || outer_code == NE)
25780 && (satisfies_constraint_I (x)
25781 || satisfies_constraint_K (x)
25783 ? satisfies_constraint_L (x)
25784 : satisfies_constraint_J (x))))
25785 || (outer_code == GTU
25786 && satisfies_constraint_I (x))
25787 || (outer_code == LTU
25788 && satisfies_constraint_P (x)))
25793 else if ((outer_code == PLUS
25794 && reg_or_add_cint_operand (x, VOIDmode))
25795 || (outer_code == MINUS
25796 && reg_or_sub_cint_operand (x, VOIDmode))
25797 || ((outer_code == SET
25798 || outer_code == IOR
25799 || outer_code == XOR)
25801 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
25803 *total = COSTS_N_INSNS (1);
25809 if (mode == DImode && code == CONST_DOUBLE)
25811 if ((outer_code == IOR || outer_code == XOR)
25812 && CONST_DOUBLE_HIGH (x) == 0
25813 && (CONST_DOUBLE_LOW (x)
25814 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
25819 else if ((outer_code == AND && and64_2_operand (x, DImode))
25820 || ((outer_code == SET
25821 || outer_code == IOR
25822 || outer_code == XOR)
25823 && CONST_DOUBLE_HIGH (x) == 0))
25825 *total = COSTS_N_INSNS (1);
25835 /* When optimizing for size, MEM should be slightly more expensive
25836 than generating address, e.g., (plus (reg) (const)).
25837 L1 cache latency is about two instructions. */
25838 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
25847 if (FLOAT_MODE_P (mode))
25848 *total = rs6000_cost->fp;
25850 *total = COSTS_N_INSNS (1);
25854 if (GET_CODE (XEXP (x, 1)) == CONST_INT
25855 && satisfies_constraint_I (XEXP (x, 1)))
25857 if (INTVAL (XEXP (x, 1)) >= -256
25858 && INTVAL (XEXP (x, 1)) <= 255)
25859 *total = rs6000_cost->mulsi_const9;
25861 *total = rs6000_cost->mulsi_const;
25863 else if (mode == SFmode)
25864 *total = rs6000_cost->fp;
25865 else if (FLOAT_MODE_P (mode))
25866 *total = rs6000_cost->dmul;
25867 else if (mode == DImode)
25868 *total = rs6000_cost->muldi;
25870 *total = rs6000_cost->mulsi;
25874 if (mode == SFmode)
25875 *total = rs6000_cost->fp;
25877 *total = rs6000_cost->dmul;
25882 if (FLOAT_MODE_P (mode))
25884 *total = mode == DFmode ? rs6000_cost->ddiv
25885 : rs6000_cost->sdiv;
25892 if (GET_CODE (XEXP (x, 1)) == CONST_INT
25893 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
25895 if (code == DIV || code == MOD)
25897 *total = COSTS_N_INSNS (2);
25900 *total = COSTS_N_INSNS (1);
25904 if (GET_MODE (XEXP (x, 1)) == DImode)
25905 *total = rs6000_cost->divdi;
25907 *total = rs6000_cost->divsi;
25909 /* Add in shift and subtract for MOD. */
25910 if (code == MOD || code == UMOD)
25911 *total += COSTS_N_INSNS (2);
25916 *total = COSTS_N_INSNS (4);
25920 *total = COSTS_N_INSNS (TARGET_POPCNTD ? 1 : 6);
25924 *total = COSTS_N_INSNS (TARGET_CMPB ? 2 : 6);
25928 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
25940 *total = COSTS_N_INSNS (1);
25948 /* Handle mul_highpart. */
25949 if (outer_code == TRUNCATE
25950 && GET_CODE (XEXP (x, 0)) == MULT)
25952 if (mode == DImode)
25953 *total = rs6000_cost->muldi;
25955 *total = rs6000_cost->mulsi;
25958 else if (outer_code == AND)
25961 *total = COSTS_N_INSNS (1);
25966 if (GET_CODE (XEXP (x, 0)) == MEM)
25969 *total = COSTS_N_INSNS (1);
25975 if (!FLOAT_MODE_P (mode))
25977 *total = COSTS_N_INSNS (1);
25983 case UNSIGNED_FLOAT:
25986 case FLOAT_TRUNCATE:
25987 *total = rs6000_cost->fp;
25991 if (mode == DFmode)
25994 *total = rs6000_cost->fp;
25998 switch (XINT (x, 1))
26001 *total = rs6000_cost->fp;
26013 *total = COSTS_N_INSNS (1);
26016 else if (FLOAT_MODE_P (mode)
26017 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
26019 *total = rs6000_cost->fp;
26027 /* Carry bit requires mode == Pmode.
26028 NEG or PLUS already counted so only add one. */
26030 && (outer_code == NEG || outer_code == PLUS))
26032 *total = COSTS_N_INSNS (1);
26035 if (outer_code == SET)
26037 if (XEXP (x, 1) == const0_rtx)
26039 if (TARGET_ISEL && !TARGET_MFCRF)
26040 *total = COSTS_N_INSNS (8);
26042 *total = COSTS_N_INSNS (2);
26045 else if (mode == Pmode)
26047 *total = COSTS_N_INSNS (3);
26056 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
26058 if (TARGET_ISEL && !TARGET_MFCRF)
26059 *total = COSTS_N_INSNS (8);
26061 *total = COSTS_N_INSNS (2);
26065 if (outer_code == COMPARE)
26079 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
26082 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int opno, int *total,
26085 bool ret = rs6000_rtx_costs (x, code, outer_code, opno, total, speed);
26088 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
26089 "opno = %d, total = %d, speed = %s, x:\n",
26090 ret ? "complete" : "scan inner",
26091 GET_RTX_NAME (code),
26092 GET_RTX_NAME (outer_code),
26095 speed ? "true" : "false");
26102 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
26105 rs6000_debug_address_cost (rtx x, bool speed)
26107 int ret = TARGET_ADDRESS_COST (x, speed);
26109 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
26110 ret, speed ? "true" : "false");
26117 /* A C expression returning the cost of moving data from a register of class
26118 CLASS1 to one of CLASS2. */
26121 rs6000_register_move_cost (enum machine_mode mode,
26122 reg_class_t from, reg_class_t to)
26126 if (TARGET_DEBUG_COST)
26129 /* Moves from/to GENERAL_REGS. */
26130 if (reg_classes_intersect_p (to, GENERAL_REGS)
26131 || reg_classes_intersect_p (from, GENERAL_REGS))
26133 reg_class_t rclass = from;
26135 if (! reg_classes_intersect_p (to, GENERAL_REGS))
26138 if (rclass == FLOAT_REGS || rclass == ALTIVEC_REGS || rclass == VSX_REGS)
26139 ret = (rs6000_memory_move_cost (mode, rclass, false)
26140 + rs6000_memory_move_cost (mode, GENERAL_REGS, false));
26142 /* It's more expensive to move CR_REGS than CR0_REGS because of the
26144 else if (rclass == CR_REGS)
26147 /* For those processors that have slow LR/CTR moves, make them more
26148 expensive than memory in order to bias spills to memory .*/
26149 else if ((rs6000_cpu == PROCESSOR_POWER6
26150 || rs6000_cpu == PROCESSOR_POWER7)
26151 && reg_classes_intersect_p (rclass, LINK_OR_CTR_REGS))
26152 ret = 6 * hard_regno_nregs[0][mode];
26155 /* A move will cost one instruction per GPR moved. */
26156 ret = 2 * hard_regno_nregs[0][mode];
26159 /* If we have VSX, we can easily move between FPR or Altivec registers. */
26160 else if (VECTOR_UNIT_VSX_P (mode)
26161 && reg_classes_intersect_p (to, VSX_REGS)
26162 && reg_classes_intersect_p (from, VSX_REGS))
26163 ret = 2 * hard_regno_nregs[32][mode];
26165 /* Moving between two similar registers is just one instruction. */
26166 else if (reg_classes_intersect_p (to, from))
26167 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
26169 /* Everything else has to go through GENERAL_REGS. */
26171 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
26172 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
26174 if (TARGET_DEBUG_COST)
26176 if (dbg_cost_ctrl == 1)
26178 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
26179 ret, GET_MODE_NAME (mode), reg_class_names[from],
26180 reg_class_names[to]);
26187 /* A C expressions returning the cost of moving data of MODE from a register to
26191 rs6000_memory_move_cost (enum machine_mode mode, reg_class_t rclass,
26192 bool in ATTRIBUTE_UNUSED)
26196 if (TARGET_DEBUG_COST)
26199 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
26200 ret = 4 * hard_regno_nregs[0][mode];
26201 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
26202 ret = 4 * hard_regno_nregs[32][mode];
26203 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
26204 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
26206 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
26208 if (TARGET_DEBUG_COST)
26210 if (dbg_cost_ctrl == 1)
26212 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
26213 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
26220 /* Returns a code for a target-specific builtin that implements
26221 reciprocal of the function, or NULL_TREE if not available. */
26224 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
26225 bool sqrt ATTRIBUTE_UNUSED)
26227 if (optimize_insn_for_size_p ())
26233 case VSX_BUILTIN_XVSQRTDP:
26234 if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode))
26237 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
26239 case VSX_BUILTIN_XVSQRTSP:
26240 if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode))
26243 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V4SF];
26252 case BUILT_IN_SQRT:
26253 if (!RS6000_RECIP_AUTO_RSQRTE_P (DFmode))
26256 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRT];
26258 case BUILT_IN_SQRTF:
26259 if (!RS6000_RECIP_AUTO_RSQRTE_P (SFmode))
26262 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
26269 /* Load up a constant. If the mode is a vector mode, splat the value across
26270 all of the vector elements. */
26273 rs6000_load_constant_and_splat (enum machine_mode mode, REAL_VALUE_TYPE dconst)
26277 if (mode == SFmode || mode == DFmode)
26279 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, mode);
26280 reg = force_reg (mode, d);
26282 else if (mode == V4SFmode)
26284 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, SFmode);
26285 rtvec v = gen_rtvec (4, d, d, d, d);
26286 reg = gen_reg_rtx (mode);
26287 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26289 else if (mode == V2DFmode)
26291 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, DFmode);
26292 rtvec v = gen_rtvec (2, d, d);
26293 reg = gen_reg_rtx (mode);
26294 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26297 gcc_unreachable ();
26302 /* Generate an FMA instruction. */
26305 rs6000_emit_madd (rtx target, rtx m1, rtx m2, rtx a)
26307 enum machine_mode mode = GET_MODE (target);
26310 dst = expand_ternary_op (mode, fma_optab, m1, m2, a, target, 0);
26311 gcc_assert (dst != NULL);
26314 emit_move_insn (target, dst);
26317 /* Generate a FMSUB instruction: dst = fma(m1, m2, -a). */
26320 rs6000_emit_msub (rtx target, rtx m1, rtx m2, rtx a)
26322 enum machine_mode mode = GET_MODE (target);
26325 /* Altivec does not support fms directly;
26326 generate in terms of fma in that case. */
26327 if (optab_handler (fms_optab, mode) != CODE_FOR_nothing)
26328 dst = expand_ternary_op (mode, fms_optab, m1, m2, a, target, 0);
26331 a = expand_unop (mode, neg_optab, a, NULL_RTX, 0);
26332 dst = expand_ternary_op (mode, fma_optab, m1, m2, a, target, 0);
26334 gcc_assert (dst != NULL);
26337 emit_move_insn (target, dst);
26340 /* Generate a FNMSUB instruction: dst = -fma(m1, m2, -a). */
26343 rs6000_emit_nmsub (rtx dst, rtx m1, rtx m2, rtx a)
26345 enum machine_mode mode = GET_MODE (dst);
26348 /* This is a tad more complicated, since the fnma_optab is for
26349 a different expression: fma(-m1, m2, a), which is the same
26350 thing except in the case of signed zeros.
26352 Fortunately we know that if FMA is supported that FNMSUB is
26353 also supported in the ISA. Just expand it directly. */
26355 gcc_assert (optab_handler (fma_optab, mode) != CODE_FOR_nothing);
26357 r = gen_rtx_NEG (mode, a);
26358 r = gen_rtx_FMA (mode, m1, m2, r);
26359 r = gen_rtx_NEG (mode, r);
26360 emit_insn (gen_rtx_SET (VOIDmode, dst, r));
26363 /* Newton-Raphson approximation of floating point divide with just 2 passes
26364 (either single precision floating point, or newer machines with higher
26365 accuracy estimates). Support both scalar and vector divide. Assumes no
26366 trapping math and finite arguments. */
26369 rs6000_emit_swdiv_high_precision (rtx dst, rtx n, rtx d)
26371 enum machine_mode mode = GET_MODE (dst);
26372 rtx x0, e0, e1, y1, u0, v0;
26373 enum insn_code code = optab_handler (smul_optab, mode);
26374 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26375 rtx one = rs6000_load_constant_and_splat (mode, dconst1);
26377 gcc_assert (code != CODE_FOR_nothing);
26379 /* x0 = 1./d estimate */
26380 x0 = gen_reg_rtx (mode);
26381 emit_insn (gen_rtx_SET (VOIDmode, x0,
26382 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26385 e0 = gen_reg_rtx (mode);
26386 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - (d * x0) */
26388 e1 = gen_reg_rtx (mode);
26389 rs6000_emit_madd (e1, e0, e0, e0); /* e1 = (e0 * e0) + e0 */
26391 y1 = gen_reg_rtx (mode);
26392 rs6000_emit_madd (y1, e1, x0, x0); /* y1 = (e1 * x0) + x0 */
26394 u0 = gen_reg_rtx (mode);
26395 emit_insn (gen_mul (u0, n, y1)); /* u0 = n * y1 */
26397 v0 = gen_reg_rtx (mode);
26398 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - (d * u0) */
26400 rs6000_emit_madd (dst, v0, y1, u0); /* dst = (v0 * y1) + u0 */
26403 /* Newton-Raphson approximation of floating point divide that has a low
26404 precision estimate. Assumes no trapping math and finite arguments. */
26407 rs6000_emit_swdiv_low_precision (rtx dst, rtx n, rtx d)
26409 enum machine_mode mode = GET_MODE (dst);
26410 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
26411 enum insn_code code = optab_handler (smul_optab, mode);
26412 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26414 gcc_assert (code != CODE_FOR_nothing);
26416 one = rs6000_load_constant_and_splat (mode, dconst1);
26418 /* x0 = 1./d estimate */
26419 x0 = gen_reg_rtx (mode);
26420 emit_insn (gen_rtx_SET (VOIDmode, x0,
26421 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26424 e0 = gen_reg_rtx (mode);
26425 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - d * x0 */
26427 y1 = gen_reg_rtx (mode);
26428 rs6000_emit_madd (y1, e0, x0, x0); /* y1 = x0 + e0 * x0 */
26430 e1 = gen_reg_rtx (mode);
26431 emit_insn (gen_mul (e1, e0, e0)); /* e1 = e0 * e0 */
26433 y2 = gen_reg_rtx (mode);
26434 rs6000_emit_madd (y2, e1, y1, y1); /* y2 = y1 + e1 * y1 */
26436 e2 = gen_reg_rtx (mode);
26437 emit_insn (gen_mul (e2, e1, e1)); /* e2 = e1 * e1 */
26439 y3 = gen_reg_rtx (mode);
26440 rs6000_emit_madd (y3, e2, y2, y2); /* y3 = y2 + e2 * y2 */
26442 u0 = gen_reg_rtx (mode);
26443 emit_insn (gen_mul (u0, n, y3)); /* u0 = n * y3 */
26445 v0 = gen_reg_rtx (mode);
26446 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - d * u0 */
26448 rs6000_emit_madd (dst, v0, y3, u0); /* dst = u0 + v0 * y3 */
26451 /* Newton-Raphson approximation of floating point divide DST = N/D. If NOTE_P,
26452 add a reg_note saying that this was a division. Support both scalar and
26453 vector divide. Assumes no trapping math and finite arguments. */
26456 rs6000_emit_swdiv (rtx dst, rtx n, rtx d, bool note_p)
26458 enum machine_mode mode = GET_MODE (dst);
26460 if (RS6000_RECIP_HIGH_PRECISION_P (mode))
26461 rs6000_emit_swdiv_high_precision (dst, n, d);
26463 rs6000_emit_swdiv_low_precision (dst, n, d);
26466 add_reg_note (get_last_insn (), REG_EQUAL, gen_rtx_DIV (mode, n, d));
26469 /* Newton-Raphson approximation of single/double-precision floating point
26470 rsqrt. Assumes no trapping math and finite arguments. */
26473 rs6000_emit_swrsqrt (rtx dst, rtx src)
26475 enum machine_mode mode = GET_MODE (src);
26476 rtx x0 = gen_reg_rtx (mode);
26477 rtx y = gen_reg_rtx (mode);
26478 int passes = (TARGET_RECIP_PRECISION) ? 2 : 3;
26479 REAL_VALUE_TYPE dconst3_2;
26482 enum insn_code code = optab_handler (smul_optab, mode);
26483 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26485 gcc_assert (code != CODE_FOR_nothing);
26487 /* Load up the constant 1.5 either as a scalar, or as a vector. */
26488 real_from_integer (&dconst3_2, VOIDmode, 3, 0, 0);
26489 SET_REAL_EXP (&dconst3_2, REAL_EXP (&dconst3_2) - 1);
26491 halfthree = rs6000_load_constant_and_splat (mode, dconst3_2);
26493 /* x0 = rsqrt estimate */
26494 emit_insn (gen_rtx_SET (VOIDmode, x0,
26495 gen_rtx_UNSPEC (mode, gen_rtvec (1, src),
26498 /* y = 0.5 * src = 1.5 * src - src -> fewer constants */
26499 rs6000_emit_msub (y, src, halfthree, src);
26501 for (i = 0; i < passes; i++)
26503 rtx x1 = gen_reg_rtx (mode);
26504 rtx u = gen_reg_rtx (mode);
26505 rtx v = gen_reg_rtx (mode);
26507 /* x1 = x0 * (1.5 - y * (x0 * x0)) */
26508 emit_insn (gen_mul (u, x0, x0));
26509 rs6000_emit_nmsub (v, y, u, halfthree);
26510 emit_insn (gen_mul (x1, x0, v));
26514 emit_move_insn (dst, x0);
26518 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
26519 (Power7) targets. DST is the target, and SRC is the argument operand. */
26522 rs6000_emit_popcount (rtx dst, rtx src)
26524 enum machine_mode mode = GET_MODE (dst);
26527 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
26528 if (TARGET_POPCNTD)
26530 if (mode == SImode)
26531 emit_insn (gen_popcntdsi2 (dst, src));
26533 emit_insn (gen_popcntddi2 (dst, src));
26537 tmp1 = gen_reg_rtx (mode);
26539 if (mode == SImode)
26541 emit_insn (gen_popcntbsi2 (tmp1, src));
26542 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
26544 tmp2 = force_reg (SImode, tmp2);
26545 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
26549 emit_insn (gen_popcntbdi2 (tmp1, src));
26550 tmp2 = expand_mult (DImode, tmp1,
26551 GEN_INT ((HOST_WIDE_INT)
26552 0x01010101 << 32 | 0x01010101),
26554 tmp2 = force_reg (DImode, tmp2);
26555 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
26560 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
26561 target, and SRC is the argument operand. */
26564 rs6000_emit_parity (rtx dst, rtx src)
26566 enum machine_mode mode = GET_MODE (dst);
26569 tmp = gen_reg_rtx (mode);
26571 /* Use the PPC ISA 2.05 prtyw/prtyd instruction if we can. */
26574 if (mode == SImode)
26576 emit_insn (gen_popcntbsi2 (tmp, src));
26577 emit_insn (gen_paritysi2_cmpb (dst, tmp));
26581 emit_insn (gen_popcntbdi2 (tmp, src));
26582 emit_insn (gen_paritydi2_cmpb (dst, tmp));
26587 if (mode == SImode)
26589 /* Is mult+shift >= shift+xor+shift+xor? */
26590 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
26592 rtx tmp1, tmp2, tmp3, tmp4;
26594 tmp1 = gen_reg_rtx (SImode);
26595 emit_insn (gen_popcntbsi2 (tmp1, src));
26597 tmp2 = gen_reg_rtx (SImode);
26598 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
26599 tmp3 = gen_reg_rtx (SImode);
26600 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
26602 tmp4 = gen_reg_rtx (SImode);
26603 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
26604 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
26607 rs6000_emit_popcount (tmp, src);
26608 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
26612 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
26613 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
26615 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
26617 tmp1 = gen_reg_rtx (DImode);
26618 emit_insn (gen_popcntbdi2 (tmp1, src));
26620 tmp2 = gen_reg_rtx (DImode);
26621 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
26622 tmp3 = gen_reg_rtx (DImode);
26623 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
26625 tmp4 = gen_reg_rtx (DImode);
26626 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
26627 tmp5 = gen_reg_rtx (DImode);
26628 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
26630 tmp6 = gen_reg_rtx (DImode);
26631 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
26632 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
26635 rs6000_emit_popcount (tmp, src);
26636 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
26640 /* Return an RTX representing where to find the function value of a
26641 function returning MODE. */
26643 rs6000_complex_function_value (enum machine_mode mode)
26645 unsigned int regno;
26647 enum machine_mode inner = GET_MODE_INNER (mode);
26648 unsigned int inner_bytes = GET_MODE_SIZE (inner);
26650 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26651 regno = FP_ARG_RETURN;
26654 regno = GP_ARG_RETURN;
26656 /* 32-bit is OK since it'll go in r3/r4. */
26657 if (TARGET_32BIT && inner_bytes >= 4)
26658 return gen_rtx_REG (mode, regno);
26661 if (inner_bytes >= 8)
26662 return gen_rtx_REG (mode, regno);
26664 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
26666 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
26667 GEN_INT (inner_bytes));
26668 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
26671 /* Target hook for TARGET_FUNCTION_VALUE.
26673 On the SPE, both FPs and vectors are returned in r3.
26675 On RS/6000 an integer value is in r3 and a floating-point value is in
26676 fp1, unless -msoft-float. */
26679 rs6000_function_value (const_tree valtype,
26680 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
26681 bool outgoing ATTRIBUTE_UNUSED)
26683 enum machine_mode mode;
26684 unsigned int regno;
26686 /* Special handling for structs in darwin64. */
26688 && rs6000_darwin64_struct_check_p (TYPE_MODE (valtype), valtype))
26690 CUMULATIVE_ARGS valcum;
26694 valcum.fregno = FP_ARG_MIN_REG;
26695 valcum.vregno = ALTIVEC_ARG_MIN_REG;
26696 /* Do a trial code generation as if this were going to be passed as
26697 an argument; if any part goes in memory, we return NULL. */
26698 valret = rs6000_darwin64_record_arg (&valcum, valtype, true, /* retval= */ true);
26701 /* Otherwise fall through to standard ABI rules. */
26704 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
26706 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26707 return gen_rtx_PARALLEL (DImode,
26709 gen_rtx_EXPR_LIST (VOIDmode,
26710 gen_rtx_REG (SImode, GP_ARG_RETURN),
26712 gen_rtx_EXPR_LIST (VOIDmode,
26713 gen_rtx_REG (SImode,
26714 GP_ARG_RETURN + 1),
26717 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
26719 return gen_rtx_PARALLEL (DCmode,
26721 gen_rtx_EXPR_LIST (VOIDmode,
26722 gen_rtx_REG (SImode, GP_ARG_RETURN),
26724 gen_rtx_EXPR_LIST (VOIDmode,
26725 gen_rtx_REG (SImode,
26726 GP_ARG_RETURN + 1),
26728 gen_rtx_EXPR_LIST (VOIDmode,
26729 gen_rtx_REG (SImode,
26730 GP_ARG_RETURN + 2),
26732 gen_rtx_EXPR_LIST (VOIDmode,
26733 gen_rtx_REG (SImode,
26734 GP_ARG_RETURN + 3),
26738 mode = TYPE_MODE (valtype);
26739 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
26740 || POINTER_TYPE_P (valtype))
26741 mode = TARGET_32BIT ? SImode : DImode;
26743 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26744 /* _Decimal128 must use an even/odd register pair. */
26745 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26746 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
26747 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
26748 regno = FP_ARG_RETURN;
26749 else if (TREE_CODE (valtype) == COMPLEX_TYPE
26750 && targetm.calls.split_complex_arg)
26751 return rs6000_complex_function_value (mode);
26752 /* VSX is a superset of Altivec and adds V2DImode/V2DFmode. Since the same
26753 return register is used in both cases, and we won't see V2DImode/V2DFmode
26754 for pure altivec, combine the two cases. */
26755 else if (TREE_CODE (valtype) == VECTOR_TYPE
26756 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
26757 && ALTIVEC_OR_VSX_VECTOR_MODE (mode))
26758 regno = ALTIVEC_ARG_RETURN;
26759 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26760 && (mode == DFmode || mode == DCmode
26761 || mode == TFmode || mode == TCmode))
26762 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26764 regno = GP_ARG_RETURN;
26766 return gen_rtx_REG (mode, regno);
26769 /* Define how to find the value returned by a library function
26770 assuming the value has mode MODE. */
26772 rs6000_libcall_value (enum machine_mode mode)
26774 unsigned int regno;
26776 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
26778 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26779 return gen_rtx_PARALLEL (DImode,
26781 gen_rtx_EXPR_LIST (VOIDmode,
26782 gen_rtx_REG (SImode, GP_ARG_RETURN),
26784 gen_rtx_EXPR_LIST (VOIDmode,
26785 gen_rtx_REG (SImode,
26786 GP_ARG_RETURN + 1),
26790 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26791 /* _Decimal128 must use an even/odd register pair. */
26792 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26793 else if (SCALAR_FLOAT_MODE_P (mode)
26794 && TARGET_HARD_FLOAT && TARGET_FPRS
26795 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
26796 regno = FP_ARG_RETURN;
26797 /* VSX is a superset of Altivec and adds V2DImode/V2DFmode. Since the same
26798 return register is used in both cases, and we won't see V2DImode/V2DFmode
26799 for pure altivec, combine the two cases. */
26800 else if (ALTIVEC_OR_VSX_VECTOR_MODE (mode)
26801 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
26802 regno = ALTIVEC_ARG_RETURN;
26803 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
26804 return rs6000_complex_function_value (mode);
26805 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26806 && (mode == DFmode || mode == DCmode
26807 || mode == TFmode || mode == TCmode))
26808 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26810 regno = GP_ARG_RETURN;
26812 return gen_rtx_REG (mode, regno);
26816 /* Given FROM and TO register numbers, say whether this elimination is allowed.
26817 Frame pointer elimination is automatically handled.
26819 For the RS/6000, if frame pointer elimination is being done, we would like
26820 to convert ap into fp, not sp.
26822 We need r30 if -mminimal-toc was specified, and there are constant pool
26826 rs6000_can_eliminate (const int from, const int to)
26828 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
26829 ? ! frame_pointer_needed
26830 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
26831 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
26835 /* Define the offset between two registers, FROM to be eliminated and its
26836 replacement TO, at the start of a routine. */
26838 rs6000_initial_elimination_offset (int from, int to)
26840 rs6000_stack_t *info = rs6000_stack_info ();
26841 HOST_WIDE_INT offset;
26843 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26844 offset = info->push_p ? 0 : -info->total_size;
26845 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26847 offset = info->push_p ? 0 : -info->total_size;
26848 if (FRAME_GROWS_DOWNWARD)
26849 offset += info->fixed_size + info->vars_size + info->parm_size;
26851 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26852 offset = FRAME_GROWS_DOWNWARD
26853 ? info->fixed_size + info->vars_size + info->parm_size
26855 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26856 offset = info->total_size;
26857 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26858 offset = info->push_p ? info->total_size : 0;
26859 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
26862 gcc_unreachable ();
26868 rs6000_dwarf_register_span (rtx reg)
26872 unsigned regno = REGNO (reg);
26873 enum machine_mode mode = GET_MODE (reg);
26877 && (SPE_VECTOR_MODE (GET_MODE (reg))
26878 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
26879 && mode != SFmode && mode != SDmode && mode != SCmode)))
26884 regno = REGNO (reg);
26886 /* The duality of the SPE register size wreaks all kinds of havoc.
26887 This is a way of distinguishing r0 in 32-bits from r0 in
26889 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
26890 gcc_assert (words <= 4);
26891 for (i = 0; i < words; i++, regno++)
26893 if (BYTES_BIG_ENDIAN)
26895 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
26896 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
26900 parts[2 * i] = gen_rtx_REG (SImode, regno);
26901 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
26905 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
26908 /* Fill in sizes for SPE register high parts in table used by unwinder. */
26911 rs6000_init_dwarf_reg_sizes_extra (tree address)
26916 enum machine_mode mode = TYPE_MODE (char_type_node);
26917 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
26918 rtx mem = gen_rtx_MEM (BLKmode, addr);
26919 rtx value = gen_int_mode (4, mode);
26921 for (i = 1201; i < 1232; i++)
26923 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
26924 HOST_WIDE_INT offset
26925 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
26927 emit_move_insn (adjust_address (mem, mode, offset), value);
26932 /* Map internal gcc register numbers to DWARF2 register numbers. */
26935 rs6000_dbx_register_number (unsigned int regno)
26937 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
26939 if (regno == MQ_REGNO)
26941 if (regno == LR_REGNO)
26943 if (regno == CTR_REGNO)
26945 if (CR_REGNO_P (regno))
26946 return regno - CR0_REGNO + 86;
26947 if (regno == CA_REGNO)
26948 return 101; /* XER */
26949 if (ALTIVEC_REGNO_P (regno))
26950 return regno - FIRST_ALTIVEC_REGNO + 1124;
26951 if (regno == VRSAVE_REGNO)
26953 if (regno == VSCR_REGNO)
26955 if (regno == SPE_ACC_REGNO)
26957 if (regno == SPEFSCR_REGNO)
26959 /* SPE high reg number. We get these values of regno from
26960 rs6000_dwarf_register_span. */
26961 gcc_assert (regno >= 1200 && regno < 1232);
26965 /* target hook eh_return_filter_mode */
26966 static enum machine_mode
26967 rs6000_eh_return_filter_mode (void)
26969 return TARGET_32BIT ? SImode : word_mode;
26972 /* Target hook for scalar_mode_supported_p. */
26974 rs6000_scalar_mode_supported_p (enum machine_mode mode)
26976 if (DECIMAL_FLOAT_MODE_P (mode))
26977 return default_decimal_float_supported_p ();
26979 return default_scalar_mode_supported_p (mode);
26982 /* Target hook for vector_mode_supported_p. */
26984 rs6000_vector_mode_supported_p (enum machine_mode mode)
26987 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
26990 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
26993 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
27000 /* Target hook for invalid_arg_for_unprototyped_fn. */
27001 static const char *
27002 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
27004 return (!rs6000_darwin64_abi
27006 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
27007 && (funcdecl == NULL_TREE
27008 || (TREE_CODE (funcdecl) == FUNCTION_DECL
27009 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
27010 ? N_("AltiVec argument passed to unprototyped function")
27014 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
27015 setup by using __stack_chk_fail_local hidden function instead of
27016 calling __stack_chk_fail directly. Otherwise it is better to call
27017 __stack_chk_fail directly. */
27019 static tree ATTRIBUTE_UNUSED
27020 rs6000_stack_protect_fail (void)
27022 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
27023 ? default_hidden_stack_protect_fail ()
27024 : default_external_stack_protect_fail ();
27028 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
27029 int num_operands ATTRIBUTE_UNUSED)
27031 if (rs6000_warn_cell_microcode)
27034 int insn_code_number = recog_memoized (insn);
27035 location_t location = locator_location (INSN_LOCATOR (insn));
27037 /* Punt on insns we cannot recognize. */
27038 if (insn_code_number < 0)
27041 temp = get_insn_template (insn_code_number, insn);
27043 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
27044 warning_at (location, OPT_mwarn_cell_microcode,
27045 "emitting microcode insn %s\t[%s] #%d",
27046 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27047 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
27048 warning_at (location, OPT_mwarn_cell_microcode,
27049 "emitting conditional microcode insn %s\t[%s] #%d",
27050 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27055 /* Mask options that we want to support inside of attribute((target)) and
27056 #pragma GCC target operations. Note, we do not include things like
27057 64/32-bit, endianess, hard/soft floating point, etc. that would have
27058 different calling sequences. */
27060 struct rs6000_opt_mask {
27061 const char *name; /* option name */
27062 int mask; /* mask to set */
27063 bool invert; /* invert sense of mask */
27064 bool valid_target; /* option is a target option */
27067 static struct rs6000_opt_mask const rs6000_opt_masks[] =
27069 { "altivec", MASK_ALTIVEC, false, true },
27070 { "cmpb", MASK_CMPB, false, true },
27071 { "dlmzb", MASK_DLMZB, false, true },
27072 { "fprnd", MASK_FPRND, false, true },
27073 { "hard-dfp", MASK_DFP, false, true },
27074 { "isel", MASK_ISEL, false, true },
27075 { "mfcrf", MASK_MFCRF, false, true },
27076 { "mfpgpr", MASK_MFPGPR, false, true },
27077 { "mulhw", MASK_MULHW, false, true },
27078 { "multiple", MASK_MULTIPLE, false, true },
27079 { "update", MASK_NO_UPDATE, true , true },
27080 { "popcntb", MASK_POPCNTB, false, true },
27081 { "popcntd", MASK_POPCNTD, false, true },
27082 { "powerpc-gfxopt", MASK_PPC_GFXOPT, false, true },
27083 { "powerpc-gpopt", MASK_PPC_GPOPT, false, true },
27084 { "recip-precision", MASK_RECIP_PRECISION, false, true },
27085 { "string", MASK_STRING, false, true },
27086 { "vsx", MASK_VSX, false, true },
27089 { "aix64", MASK_64BIT, false, false },
27090 { "aix32", MASK_64BIT, true, false },
27092 { "64", MASK_64BIT, false, false },
27093 { "32", MASK_64BIT, true, false },
27097 { "eabi", MASK_EABI, false, false },
27099 #ifdef MASK_LITTLE_ENDIAN
27100 { "little", MASK_LITTLE_ENDIAN, false, false },
27101 { "big", MASK_LITTLE_ENDIAN, true, false },
27103 #ifdef MASK_RELOCATABLE
27104 { "relocatable", MASK_RELOCATABLE, false, false },
27106 #ifdef MASK_STRICT_ALIGN
27107 { "strict-align", MASK_STRICT_ALIGN, false, false },
27109 { "power", MASK_POWER, false, false },
27110 { "power2", MASK_POWER2, false, false },
27111 { "powerpc", MASK_POWERPC, false, false },
27112 { "soft-float", MASK_SOFT_FLOAT, false, false },
27113 { "string", MASK_STRING, false, false },
27116 /* Option variables that we want to support inside attribute((target)) and
27117 #pragma GCC target operations. */
27119 struct rs6000_opt_var {
27120 const char *name; /* option name */
27121 size_t global_offset; /* offset of the option in global_options. */
27122 size_t target_offset; /* offset of the option in target optiosn. */
27125 static struct rs6000_opt_var const rs6000_opt_vars[] =
27128 offsetof (struct gcc_options, x_TARGET_FRIZ),
27129 offsetof (struct cl_target_option, x_TARGET_FRIZ), },
27130 { "avoid-indexed-addresses",
27131 offsetof (struct gcc_options, x_TARGET_AVOID_XFORM),
27132 offsetof (struct cl_target_option, x_TARGET_AVOID_XFORM) },
27134 offsetof (struct gcc_options, x_rs6000_paired_float),
27135 offsetof (struct cl_target_option, x_rs6000_paired_float), },
27137 offsetof (struct gcc_options, x_rs6000_default_long_calls),
27138 offsetof (struct cl_target_option, x_rs6000_default_long_calls), },
27141 /* Inner function to handle attribute((target("..."))) and #pragma GCC target
27142 parsing. Return true if there were no errors. */
27145 rs6000_inner_target_options (tree args, bool attr_p)
27149 if (args == NULL_TREE)
27152 else if (TREE_CODE (args) == STRING_CST)
27154 char *p = ASTRDUP (TREE_STRING_POINTER (args));
27157 while ((q = strtok (p, ",")) != NULL)
27159 bool error_p = false;
27160 bool not_valid_p = false;
27161 const char *cpu_opt = NULL;
27164 if (strncmp (q, "cpu=", 4) == 0)
27166 int cpu_index = rs6000_cpu_name_lookup (q+4);
27167 if (cpu_index >= 0)
27168 rs6000_cpu_index = cpu_index;
27175 else if (strncmp (q, "tune=", 5) == 0)
27177 int tune_index = rs6000_cpu_name_lookup (q+5);
27178 if (tune_index >= 0)
27179 rs6000_tune_index = tune_index;
27189 bool invert = false;
27193 if (strncmp (r, "no-", 3) == 0)
27199 for (i = 0; i < ARRAY_SIZE (rs6000_opt_masks); i++)
27200 if (strcmp (r, rs6000_opt_masks[i].name) == 0)
27202 int mask = rs6000_opt_masks[i].mask;
27204 if (!rs6000_opt_masks[i].valid_target)
27205 not_valid_p = true;
27209 target_flags_explicit |= mask;
27211 if (rs6000_opt_masks[i].invert)
27215 target_flags &= ~mask;
27217 target_flags |= mask;
27222 if (error_p && !not_valid_p)
27224 for (i = 0; i < ARRAY_SIZE (rs6000_opt_vars); i++)
27225 if (strcmp (r, rs6000_opt_vars[i].name) == 0)
27227 size_t j = rs6000_opt_vars[i].global_offset;
27228 ((int *) &global_options)[j] = !invert;
27237 const char *eprefix, *esuffix;
27242 eprefix = "__attribute__((__target__(";
27247 eprefix = "#pragma GCC target ";
27252 error ("invalid cpu \"%s\" for %s\"%s\"%s", cpu_opt, eprefix,
27254 else if (not_valid_p)
27255 error ("%s\"%s\"%s is not allowed", eprefix, q, esuffix);
27257 error ("%s\"%s\"%s is invalid", eprefix, q, esuffix);
27262 else if (TREE_CODE (args) == TREE_LIST)
27266 tree value = TREE_VALUE (args);
27269 bool ret2 = rs6000_inner_target_options (value, attr_p);
27273 args = TREE_CHAIN (args);
27275 while (args != NULL_TREE);
27279 gcc_unreachable ();
27284 /* Print out the target options as a list for -mdebug=target. */
27287 rs6000_debug_target_options (tree args, const char *prefix)
27289 if (args == NULL_TREE)
27290 fprintf (stderr, "%s<NULL>", prefix);
27292 else if (TREE_CODE (args) == STRING_CST)
27294 char *p = ASTRDUP (TREE_STRING_POINTER (args));
27297 while ((q = strtok (p, ",")) != NULL)
27300 fprintf (stderr, "%s\"%s\"", prefix, q);
27305 else if (TREE_CODE (args) == TREE_LIST)
27309 tree value = TREE_VALUE (args);
27312 rs6000_debug_target_options (value, prefix);
27315 args = TREE_CHAIN (args);
27317 while (args != NULL_TREE);
27321 gcc_unreachable ();
27327 /* Hook to validate attribute((target("..."))). */
27330 rs6000_valid_attribute_p (tree fndecl,
27331 tree ARG_UNUSED (name),
27335 struct cl_target_option cur_target;
27337 tree old_optimize = build_optimization_node ();
27338 tree new_target, new_optimize;
27339 tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
27341 gcc_assert ((fndecl != NULL_TREE) && (args != NULL_TREE));
27343 if (TARGET_DEBUG_TARGET)
27345 tree tname = DECL_NAME (fndecl);
27346 fprintf (stderr, "\n==================== rs6000_valid_attribute_p:\n");
27348 fprintf (stderr, "function: %.*s\n",
27349 (int) IDENTIFIER_LENGTH (tname),
27350 IDENTIFIER_POINTER (tname));
27352 fprintf (stderr, "function: unknown\n");
27354 fprintf (stderr, "args:");
27355 rs6000_debug_target_options (args, " ");
27356 fprintf (stderr, "\n");
27359 fprintf (stderr, "flags: 0x%x\n", flags);
27361 fprintf (stderr, "--------------------\n");
27364 old_optimize = build_optimization_node ();
27365 func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
27367 /* If the function changed the optimization levels as well as setting target
27368 options, start with the optimizations specified. */
27369 if (func_optimize && func_optimize != old_optimize)
27370 cl_optimization_restore (&global_options,
27371 TREE_OPTIMIZATION (func_optimize));
27373 /* The target attributes may also change some optimization flags, so update
27374 the optimization options if necessary. */
27375 cl_target_option_save (&cur_target, &global_options);
27376 rs6000_cpu_index = rs6000_tune_index = -1;
27377 ret = rs6000_inner_target_options (args, true);
27379 /* Set up any additional state. */
27382 ret = rs6000_option_override_internal (false);
27383 new_target = build_target_option_node ();
27388 new_optimize = build_optimization_node ();
27395 DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target;
27397 if (old_optimize != new_optimize)
27398 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
27401 cl_target_option_restore (&global_options, &cur_target);
27403 if (old_optimize != new_optimize)
27404 cl_optimization_restore (&global_options,
27405 TREE_OPTIMIZATION (old_optimize));
27411 /* Hook to validate the current #pragma GCC target and set the state, and
27412 update the macros based on what was changed. If ARGS is NULL, then
27413 POP_TARGET is used to reset the options. */
27416 rs6000_pragma_target_parse (tree args, tree pop_target)
27421 if (TARGET_DEBUG_TARGET)
27423 fprintf (stderr, "\n==================== rs6000_pragma_target_parse\n");
27424 fprintf (stderr, "args:");
27425 rs6000_debug_target_options (args, " ");
27426 fprintf (stderr, "\n");
27430 fprintf (stderr, "pop_target:\n");
27431 debug_tree (pop_target);
27434 fprintf (stderr, "pop_target: <NULL>\n");
27436 fprintf (stderr, "--------------------\n");
27442 cur_tree = ((pop_target)
27444 : target_option_default_node);
27445 cl_target_option_restore (&global_options,
27446 TREE_TARGET_OPTION (cur_tree));
27450 rs6000_cpu_index = rs6000_tune_index = -1;
27451 ret = rs6000_inner_target_options (args, false);
27452 cur_tree = build_target_option_node ();
27459 target_option_current_node = cur_tree;
27465 /* Remember the last target of rs6000_set_current_function. */
27466 static GTY(()) tree rs6000_previous_fndecl;
27468 /* Establish appropriate back-end context for processing the function
27469 FNDECL. The argument might be NULL to indicate processing at top
27470 level, outside of any function scope. */
27472 rs6000_set_current_function (tree fndecl)
27474 tree old_tree = (rs6000_previous_fndecl
27475 ? DECL_FUNCTION_SPECIFIC_TARGET (rs6000_previous_fndecl)
27478 tree new_tree = (fndecl
27479 ? DECL_FUNCTION_SPECIFIC_TARGET (fndecl)
27482 if (TARGET_DEBUG_TARGET)
27484 bool print_final = false;
27485 fprintf (stderr, "\n==================== rs6000_set_current_function");
27488 fprintf (stderr, ", fndecl %s (%p)",
27489 (DECL_NAME (fndecl)
27490 ? IDENTIFIER_POINTER (DECL_NAME (fndecl))
27491 : "<unknown>"), (void *)fndecl);
27493 if (rs6000_previous_fndecl)
27494 fprintf (stderr, ", prev_fndecl (%p)", (void *)rs6000_previous_fndecl);
27496 fprintf (stderr, "\n");
27499 fprintf (stderr, "\nnew fndecl target specific options:\n");
27500 debug_tree (new_tree);
27501 print_final = true;
27506 fprintf (stderr, "\nold fndecl target specific options:\n");
27507 debug_tree (old_tree);
27508 print_final = true;
27512 fprintf (stderr, "--------------------\n");
27515 /* Only change the context if the function changes. This hook is called
27516 several times in the course of compiling a function, and we don't want to
27517 slow things down too much or call target_reinit when it isn't safe. */
27518 if (fndecl && fndecl != rs6000_previous_fndecl)
27520 rs6000_previous_fndecl = fndecl;
27521 if (old_tree == new_tree)
27526 cl_target_option_restore (&global_options,
27527 TREE_TARGET_OPTION (new_tree));
27533 struct cl_target_option *def
27534 = TREE_TARGET_OPTION (target_option_current_node);
27536 cl_target_option_restore (&global_options, def);
27543 /* Save the current options */
27546 rs6000_function_specific_save (struct cl_target_option *ptr)
27548 ptr->rs6000_target_flags_explicit = target_flags_explicit;
27551 /* Restore the current options */
27554 rs6000_function_specific_restore (struct cl_target_option *ptr)
27556 target_flags_explicit = ptr->rs6000_target_flags_explicit;
27557 (void) rs6000_option_override_internal (false);
27560 /* Print the current options */
27563 rs6000_function_specific_print (FILE *file, int indent,
27564 struct cl_target_option *ptr)
27567 int flags = ptr->x_target_flags;
27569 /* Print the various mask options. */
27570 for (i = 0; i < ARRAY_SIZE (rs6000_opt_masks); i++)
27571 if ((flags & rs6000_opt_masks[i].mask) != 0)
27573 flags &= ~ rs6000_opt_masks[i].mask;
27574 fprintf (file, "%*s-m%s%s\n", indent, "",
27575 rs6000_opt_masks[i].invert ? "no-" : "",
27576 rs6000_opt_masks[i].name);
27579 /* Print the various options that are variables. */
27580 for (i = 0; i < ARRAY_SIZE (rs6000_opt_vars); i++)
27582 size_t j = rs6000_opt_vars[i].target_offset;
27583 if (((signed char *) ptr)[j])
27584 fprintf (file, "%*s-m%s\n", indent, "",
27585 rs6000_opt_vars[i].name);
27590 /* Hook to determine if one function can safely inline another. */
27593 rs6000_can_inline_p (tree caller, tree callee)
27596 tree caller_tree = DECL_FUNCTION_SPECIFIC_TARGET (caller);
27597 tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (callee);
27599 /* If callee has no option attributes, then it is ok to inline. */
27603 /* If caller has no option attributes, but callee does then it is not ok to
27605 else if (!caller_tree)
27610 struct cl_target_option *caller_opts = TREE_TARGET_OPTION (caller_tree);
27611 struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree);
27613 /* Callee's options should a subset of the caller's, i.e. a vsx function
27614 can inline an altivec function but a non-vsx function can't inline a
27616 if ((caller_opts->x_target_flags & callee_opts->x_target_flags)
27617 == callee_opts->x_target_flags)
27621 if (TARGET_DEBUG_TARGET)
27622 fprintf (stderr, "rs6000_can_inline_p:, caller %s, callee %s, %s inline\n",
27623 (DECL_NAME (caller)
27624 ? IDENTIFIER_POINTER (DECL_NAME (caller))
27626 (DECL_NAME (callee)
27627 ? IDENTIFIER_POINTER (DECL_NAME (callee))
27629 (ret ? "can" : "cannot"));
27634 /* Allocate a stack temp and fixup the address so it meets the particular
27635 memory requirements (either offetable or REG+REG addressing). */
27638 rs6000_allocate_stack_temp (enum machine_mode mode,
27639 bool offsettable_p,
27642 rtx stack = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
27643 rtx addr = XEXP (stack, 0);
27644 int strict_p = (reload_in_progress || reload_completed);
27646 if (!legitimate_indirect_address_p (addr, strict_p))
27649 && !rs6000_legitimate_offset_address_p (mode, addr, strict_p))
27650 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
27652 else if (reg_reg_p && !legitimate_indexed_address_p (addr, strict_p))
27653 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
27659 /* Given a memory reference, if it is not a reg or reg+reg addressing, convert
27660 to such a form to deal with memory reference instructions like STFIWX that
27661 only take reg+reg addressing. */
27664 rs6000_address_for_fpconvert (rtx x)
27666 int strict_p = (reload_in_progress || reload_completed);
27669 gcc_assert (MEM_P (x));
27670 addr = XEXP (x, 0);
27671 if (! legitimate_indirect_address_p (addr, strict_p)
27672 && ! legitimate_indexed_address_p (addr, strict_p))
27674 if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)
27676 rtx reg = XEXP (addr, 0);
27677 HOST_WIDE_INT size = GET_MODE_SIZE (GET_MODE (x));
27678 rtx size_rtx = GEN_INT ((GET_CODE (addr) == PRE_DEC) ? -size : size);
27679 gcc_assert (REG_P (reg));
27680 emit_insn (gen_add3_insn (reg, reg, size_rtx));
27683 else if (GET_CODE (addr) == PRE_MODIFY)
27685 rtx reg = XEXP (addr, 0);
27686 rtx expr = XEXP (addr, 1);
27687 gcc_assert (REG_P (reg));
27688 gcc_assert (GET_CODE (expr) == PLUS);
27689 emit_insn (gen_add3_insn (reg, XEXP (expr, 0), XEXP (expr, 1)));
27693 x = replace_equiv_address (x, copy_addr_to_reg (addr));
27699 /* Given a memory reference, if it is not in the form for altivec memory
27700 reference instructions (i.e. reg or reg+reg addressing with AND of -16),
27701 convert to the altivec format. */
27704 rs6000_address_for_altivec (rtx x)
27706 gcc_assert (MEM_P (x));
27707 if (!altivec_indexed_or_indirect_operand (x, GET_MODE (x)))
27709 rtx addr = XEXP (x, 0);
27710 int strict_p = (reload_in_progress || reload_completed);
27712 if (!legitimate_indexed_address_p (addr, strict_p)
27713 && !legitimate_indirect_address_p (addr, strict_p))
27714 addr = copy_to_mode_reg (Pmode, addr);
27716 addr = gen_rtx_AND (Pmode, addr, GEN_INT (-16));
27717 x = change_address (x, GET_MODE (x), addr);
27723 /* Implement TARGET_LEGITIMATE_CONSTANT_P.
27725 On the RS/6000, all integer constants are acceptable, most won't be valid
27726 for particular insns, though. Only easy FP constants are acceptable. */
27729 rs6000_legitimate_constant_p (enum machine_mode mode, rtx x)
27731 if (rs6000_tls_referenced_p (x))
27734 return ((GET_CODE (x) != CONST_DOUBLE && GET_CODE (x) != CONST_VECTOR)
27735 || GET_MODE (x) == VOIDmode
27736 || (TARGET_POWERPC64 && mode == DImode)
27737 || easy_fp_constant (x, mode)
27738 || easy_vector_constant (x, mode));
27742 /* A function pointer under AIX is a pointer to a data area whose first word
27743 contains the actual address of the function, whose second word contains a
27744 pointer to its TOC, and whose third word contains a value to place in the
27745 static chain register (r11). Note that if we load the static chain, our
27746 "trampoline" need not have any executable code. */
27749 rs6000_call_indirect_aix (rtx value, rtx func_desc, rtx flag)
27755 rtx stack_toc_offset;
27757 rtx func_toc_offset;
27759 rtx func_sc_offset;
27762 rtx (*call_func) (rtx, rtx, rtx, rtx);
27763 rtx (*call_value_func) (rtx, rtx, rtx, rtx, rtx);
27765 stack_ptr = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
27766 toc_reg = gen_rtx_REG (Pmode, TOC_REGNUM);
27768 /* Load up address of the actual function. */
27769 func_desc = force_reg (Pmode, func_desc);
27770 func_addr = gen_reg_rtx (Pmode);
27771 emit_move_insn (func_addr, gen_rtx_MEM (Pmode, func_desc));
27776 stack_toc_offset = GEN_INT (TOC_SAVE_OFFSET_32BIT);
27777 func_toc_offset = GEN_INT (AIX_FUNC_DESC_TOC_32BIT);
27778 func_sc_offset = GEN_INT (AIX_FUNC_DESC_SC_32BIT);
27779 if (TARGET_POINTERS_TO_NESTED_FUNCTIONS)
27781 call_func = gen_call_indirect_aix32bit;
27782 call_value_func = gen_call_value_indirect_aix32bit;
27786 call_func = gen_call_indirect_aix32bit_nor11;
27787 call_value_func = gen_call_value_indirect_aix32bit_nor11;
27792 stack_toc_offset = GEN_INT (TOC_SAVE_OFFSET_64BIT);
27793 func_toc_offset = GEN_INT (AIX_FUNC_DESC_TOC_64BIT);
27794 func_sc_offset = GEN_INT (AIX_FUNC_DESC_SC_64BIT);
27795 if (TARGET_POINTERS_TO_NESTED_FUNCTIONS)
27797 call_func = gen_call_indirect_aix64bit;
27798 call_value_func = gen_call_value_indirect_aix64bit;
27802 call_func = gen_call_indirect_aix64bit_nor11;
27803 call_value_func = gen_call_value_indirect_aix64bit_nor11;
27807 /* Reserved spot to store the TOC. */
27808 stack_toc_mem = gen_frame_mem (Pmode,
27809 gen_rtx_PLUS (Pmode,
27811 stack_toc_offset));
27814 gcc_assert (cfun->machine);
27816 /* Can we optimize saving the TOC in the prologue or do we need to do it at
27818 if (TARGET_SAVE_TOC_INDIRECT && !cfun->calls_alloca)
27819 cfun->machine->save_toc_in_prologue = true;
27823 MEM_VOLATILE_P (stack_toc_mem) = 1;
27824 emit_move_insn (stack_toc_mem, toc_reg);
27827 /* Calculate the address to load the TOC of the called function. We don't
27828 actually load this until the split after reload. */
27829 func_toc_mem = gen_rtx_MEM (Pmode,
27830 gen_rtx_PLUS (Pmode,
27834 /* If we have a static chain, load it up. */
27835 if (TARGET_POINTERS_TO_NESTED_FUNCTIONS)
27837 func_sc_mem = gen_rtx_MEM (Pmode,
27838 gen_rtx_PLUS (Pmode,
27842 sc_reg = gen_rtx_REG (Pmode, STATIC_CHAIN_REGNUM);
27843 emit_move_insn (sc_reg, func_sc_mem);
27846 /* Create the call. */
27848 insn = call_value_func (value, func_addr, flag, func_toc_mem,
27851 insn = call_func (func_addr, flag, func_toc_mem, stack_toc_mem);
27853 emit_call_insn (insn);
27856 /* Return whether we need to always update the saved TOC pointer when we update
27857 the stack pointer. */
27860 rs6000_save_toc_in_prologue_p (void)
27862 return (cfun && cfun->machine && cfun->machine->save_toc_in_prologue);
27865 #include "gt-rs6000.h"